1 Operations
Morozovka Admin edited this page 2026-10-21 07:13:11 +03:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Эксплуатация

Управление сервисами

# Портал
systemctl restart morozovka-portal
systemctl status morozovka-portal --no-pager
systemctl is-active morozovka-portal

# Gitea
systemctl restart gitea
systemctl status gitea --no-pager

# Nginx
systemctl reload nginx
nginx -t

# PostgreSQL
systemctl restart postgresql

# Google sync
systemctl list-timers morozovka-sync.timer

Логи

# Портал (gunicorn + access log)
journalctl -u morozovka-portal -f --no-pager
journalctl -u morozovka-portal -n 100

# Gitea
journalctl -u gitea -f --no-pager

# Nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log

# PostgreSQL
journalctl -u postgresql -f --no-pager
tail -f /var/log/postgresql/postgresql-15-main.log

# Google sync
journalctl -u morozovka-sync.timer -n 20
journalctl -u morozovka-sync.service -n 50

Проверка здоровья

# 1. Health портала
curl -sS http://127.0.0.1:8000/healthz
# → {"db":"ok","llm":"disabled","status":"ok"}

# 2. Все публичные роуты
for p in / /schedule /feed /projects /workshops /login; do
  code=$(curl -sS -o /dev/null -w '%{http_code}' "http://127.0.0.1:8000$p")
  printf '%-15s %s\n' "$p" "$code"
done

# 3. Полные смоук-тесты (94 проверки, 3 сек)
bash /opt/morozovka-portal/tests/run_smoke.sh

# 4. Миграции
cd /opt/morozovka-portal
export PATH=./venv/bin:$PATH
alembic current

# 5. Сервисы
systemctl is-active morozovka-portal gitea nginx postgresql

Обновление кода

cd /opt/morozovka-portal

# 1. Бэкап
cp -r app /tmp/app_backup_$(date +%s)
PGPASSWORD='rf-slf-1945' pg_dump -h 127.0.0.1 -U morozovka morozovka_portal > /tmp/db_backup_$(date +%s).sql

# 2. Git pull
git fetch origin
git log HEAD..origin/main --oneline
git pull origin main

# 3. Зависимости (если requirements.txt изменился)
./venv/bin/pip install -r requirements.txt

# 4. Миграции
export PATH=./venv/bin:$PATH
alembic upgrade head

# 5. Синтаксис
python3 -c "import ast,glob; [ast.parse(open(f).read()) for f in glob.glob('app/*.py') + glob.glob('app/modules/*.py')]" && echo "OK"

# 6. Рестарт
systemctl restart morozovka-portal
sleep 3

# 7. Проверка
curl -sS http://127.0.0.1:8000/healthz
bash tests/run_smoke.sh

Если что-то сломалось — откат:

git reset --hard HEAD~1
alembic downgrade -1
systemctl restart morozovka-portal

Troubleshooting

Портал не запускается

systemctl status morozovka-portal --no-pager
journalctl -u morozovka-portal -n 100 --no-pager

Частые причины:

  • .env не читается → проверь EnvironmentFile=-/opt/morozovka-portal/.env в systemd
  • Синтаксическая ошибка в Python → python3 -c "import ast,glob; [ast.parse(open(f).read()) for f in glob.glob('app/*.py')]"
  • Миграции не применены → alembic current и alembic upgrade head
  • Порт 8000 занят → ss -tlnp | grep 8000

/healthz → 503 (db:error)

  • PostgreSQL не запущен → systemctl restart postgresql
  • Неверный DATABASE_URL → проверь .env, app/config.py
  • Пароль изменился → ALTER USER morozovka WITH PASSWORD 'новый'; и .env

Файлы не скачиваются

  • Блоб отсутствует на диске → ls -la /var/lib/gitea/portal-files/ | wc -l
  • current_version_id указывает на несуществующую версию → проверь в psql
  • Права на папку → проверь FileFolderACL

Webhook 401

  • GITEA_WEBHOOK_SECRET не совпадает с настройкой в Gitea → проверь оба

Webhook 200, но нет уведомлений

  • У проекта нет gitea_repo → проверь в /projects/<id>
  • У проекта нет подписчиков → проверь projectsubscription
  • Push в ветку, которая не отслеживается → проверь payload.ref

Gitea sync не работает

  • GOOGLE_CALENDAR_ID неправильный → проверь в .env
  • google_credentials.json отсутствует → положи в /opt/morozovka-portal/
  • Календарь не расшарен на service account → Google Calendar → настройки → доступ
  • Timer не запущен → systemctl status morozovka-sync.timer

Email не приходит

  • SMTP не настроен → письма идут в journalctl
  • Проверка: journalctl -u morozovka-portal | grep "EMAIL ДЛЯ"

LLM не работает

  • LLM_ENABLED=false в .env (по умолчанию)
  • Модель не загружена → ollama list (должна быть qwen2.5:14b)
  • Ollama не запущена → systemctl status ollama
  • Проверка: curl -sS http://localhost:11434/v1/models

Обслуживание

Очистка старых сессий

PGPASSWORD='rf-slf-1945' psql -h 127.0.0.1 -U morozovka -d morozovka_portal -c "
DELETE FROM usersession WHERE created_at < NOW() - INTERVAL '30 days';
"

Очистка старых уведомлений

PGPASSWORD='rf-slf-1945' psql -h 127.0.0.1 -U morozovka -d morozovka_portal -c "
DELETE FROM notification WHERE is_read = true AND created_at < NOW() - INTERVAL '90 days';
"

Проверка размера портала

# БД
PGPASSWORD='rf-slf-1945' psql -h 127.0.0.1 -U morozovka -d morozovka_portal -c "
SELECT pg_size_pretty(pg_database_size('morozovka_portal'));
"

# Файлы
du -sh /var/lib/gitea/portal-files/

# Топ-10 таблиц по размеру
PGPASSWORD='rf-slf-1945' psql -h 127.0.0.1 -U morozovka -d morozovka_portal -c "
SELECT relname, pg_size_pretty(pg_total_relation_size(relid))
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;
"

Cron / systemd timers

Timer Что Когда
morozovka-sync.timer Google Calendar → Event Каждые 15 мин
(TODO) morozovka-backup.timer pg_dump + rsync 3:00

Emergency recovery

Портал полностью лёг

  1. Проверь systemctl status morozovka-portal postgresql nginx
  2. Если БД умерла → systemctl restart postgresql
  3. Если портал падает в цикле → journalctl -u morozovka-portal -n 100
  4. Синтаксис → python3 -c "import ast,glob; [ast.parse(open(f).read()) for f in glob.glob('app/*.py') + glob.glob('app/modules/*.py')]"
  5. Если миграция сломала → alembic downgrade -1
  6. Worst case — восстановление из бэкапа (см. Database)

Вебхук Gitea сломался

curl -X POST http://127.0.0.1:8000/webhooks/gitea \
  -H "X-Gitea-Signature: DEADBEEF" -d '{}'
  • 401 = защита работает, ок
  • 200 = подпись не проверяется → GITEA_WEBHOOK_SECRET пустой
  • 000 = портал не отвечает → см. выше