Тема
API Deploy
Швидкий деплой
bash
./deploy.shСкрипт виконує:
git push pisduk main— пуш коду на сервер- SSH до Hetzner →
git pull→docker compose build --no-cache→docker compose up -d
WARNING
Пушимо в pisduk, а не в origin. Це різні GitHub-репозиторії.
Ручний деплой
bash
# Push до деплой-ремоуту
git push pisduk main
# SSH rebuild
ssh -i ~/.ssh/hetzner root@37.27.202.249 \
"cd /opt/pisd/pisduk && git pull --ff-only && docker compose build --no-cache && docker compose up -d"Docker Compose
На сервері в /opt/pisd/pisduk/:
yaml
services:
api:
build: .
ports:
- "3000:3000"
env_file: .env
depends_on:
- postgres
- redis
postgres:
image: postgis/postgis:16-3.4
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redisdata:/dataЗмінні середовища (.env)
| Змінна | Опис | Значення prod |
|---|---|---|
NODE_ENV | Середовище | production |
DATABASE_URL | PostgreSQL URL | postgresql://pisd:***@postgres:5432/pisd |
REDIS_URL | Redis URL | redis://redis:6379 |
JWT_SECRET | JWT підпис | Сильний випадковий рядок |
JWT_REFRESH_SECRET | Refresh JWT підпис | Окремий сильний рядок |
TURBO_SMS_KEY | TurboSMS API ключ | Від провайдера |
TURBO_SMS_SENDER | Відправник SMS | PEACED |
CORS_ORIGINS | Дозволені origin | https://m.pisd.uk,https://admin.pisd.uk,https://partner.peaced.uk |
OTP_ALLOW_DEV_CODE | Dev-escape OTP | false (ніколи в prod) |
R2_ACCOUNT_ID | Cloudflare R2 | Від Cloudflare |
R2_ACCESS_KEY_ID | R2 ключ | Від Cloudflare |
R2_SECRET_ACCESS_KEY | R2 секрет | Від Cloudflare |
R2_BUCKET | R2 bucket | pisd-media |
R2_PUBLIC_URL | Публічний CDN | https://cdn.pisd.uk |
DANGER
OTP_ALLOW_DEV_CODE=true — тільки для локальної розробки. На prod ніколи.
Міграції бази даних
synchronize: false у production. Всі зміни схеми — через onModuleInit у відповідному сервісі.
Патерн міграції
typescript
async onModuleInit() {
await this.dataSource.query(`
ALTER TABLE events
ADD COLUMN IF NOT EXISTS template_id uuid REFERENCES event_templates(id),
ADD COLUMN IF NOT EXISTS enabled_modules text[] DEFAULT '{}';
`);
}Правило
Завжди використовуй ADD COLUMN IF NOT EXISTS і CREATE TABLE IF NOT EXISTS — безпечно для повторних деплоїв.
Типові помилки
| Помилка | Причина | Рішення |
|---|---|---|
column already exists | Відсутній IF NOT EXISTS | Додай перевірку |
relation does not exist | Таблиця ще не створена | Перевір порядок onModuleInit |
duplicate key | Seed виконався двічі | Додай ON CONFLICT DO NOTHING |
Логи
bash
# Real-time логи API
ssh -i ~/.ssh/hetzner root@37.27.202.249 \
"cd /opt/pisd/pisduk && docker compose logs -f api"
# Останні 100 рядків
ssh -i ~/.ssh/hetzner root@37.27.202.249 \
"cd /opt/pisd/pisduk && docker compose logs --tail=100 api"