143 lines
5.6 KiB
Markdown
143 lines
5.6 KiB
Markdown
# CryptoWallet API — Production Deploy Bundle
|
||
|
||
Самодостаточная папка для деплоя на Linux-сервер. Содержит всё нужное для сборки и запуска продакшн-версии API.
|
||
|
||
## Состав
|
||
|
||
```
|
||
deployserver/
|
||
├── Dockerfile # Multi-stage production build
|
||
├── docker-compose.yml # Только API (БД внешняя, из Vault)
|
||
├── .env.example # Шаблон переменных окружения
|
||
├── .dockerignore
|
||
├── start.sh # Автоматический deploy скрипт
|
||
├── db/
|
||
│ └── schema.sql # DDL таблиц (users, wallets, sessions) — идемпотентный
|
||
├── apps/api/ # Исходник API
|
||
│ ├── src/
|
||
│ ├── package.json
|
||
│ ├── tsconfig.json
|
||
│ ├── swagger.json
|
||
│ └── .eslintrc.json
|
||
├── package.json # Монорепо root
|
||
├── pnpm-workspace.yaml
|
||
└── pnpm-lock.yaml
|
||
```
|
||
|
||
## Требования
|
||
|
||
- Ubuntu 20.04+ / Debian 11+ / любой Linux с Docker 24+
|
||
- Docker Compose plugin (`docker compose` команда)
|
||
- Исходящий HTTPS на Vault (`corp.vault.elcsa.ru:443`)
|
||
- Сетевой доступ к PostgreSQL (адрес приходит из Vault)
|
||
|
||
## Быстрый старт
|
||
|
||
```bash
|
||
# 1. Скопировать папку на сервер
|
||
scp -r deployserver user@server:/opt/cryptowallet
|
||
ssh user@server
|
||
cd /opt/cryptowallet
|
||
|
||
# 2. Установить Docker (если нет)
|
||
curl -fsSL https://get.docker.com | sudo sh
|
||
sudo usermod -aG docker $USER
|
||
newgrp docker
|
||
|
||
# 3. Настроить .env
|
||
cp .env.example .env
|
||
nano .env # заполнить VAULT_ROLE_ID, VAULT_SECRET_ID
|
||
|
||
# 4. Применить схему БД (один раз, на пустой БД)
|
||
sudo apt install -y postgresql-client
|
||
PGPASSWORD=<пароль_из_Vault> psql -h <host> -U <user> -d <db> -f db/schema.sql
|
||
|
||
# 5. Запустить
|
||
chmod +x start.sh
|
||
./start.sh
|
||
|
||
# 6. Открыть порт наружу
|
||
sudo ufw allow 22/tcp
|
||
sudo ufw allow 3001/tcp
|
||
sudo ufw enable
|
||
```
|
||
|
||
## Проверка
|
||
|
||
```bash
|
||
curl http://localhost:3001/api/health
|
||
# → {"success":true,"data":{"status":"ok"}}
|
||
|
||
curl http://<server-ip>:3001/api/health # извне
|
||
```
|
||
|
||
Swagger UI: `http://<server-ip>:3001/api/docs`
|
||
|
||
## Порты
|
||
|
||
| Порт | Назначение | Открыть наружу? |
|
||
|------|-----------|-----------------|
|
||
| 3001 | API HTTP | ✅ да (`ufw allow 3001`) |
|
||
| 443 (out) | Vault | исходящий, обычно открыт |
|
||
| 5432 (out) | PostgreSQL | исходящий к внешнему адресу БД |
|
||
|
||
## Управление
|
||
|
||
```bash
|
||
docker compose logs -f api # смотреть логи
|
||
docker compose restart api # рестарт (например после смены .env)
|
||
docker compose down # остановить
|
||
docker compose ps # статус
|
||
docker compose up -d --build # пересобрать и запустить (после обновления кода)
|
||
```
|
||
|
||
## Обновление
|
||
|
||
```bash
|
||
# Скопировать новую версию deployserver/ (или git pull)
|
||
docker compose build --pull api
|
||
docker compose up -d
|
||
```
|
||
|
||
Схема БД не применяется автоматически — если добавились новые таблицы/колонки, выполни `schema.sql` вручную (он идемпотентный, безопасно запускать повторно).
|
||
|
||
## Ротация ключей
|
||
|
||
JWT public keys и CSRF secret читаются из Vault при старте и **каждый час** обновляются автоматически (см. `key-rotation.service.ts`). При ошибках Vault сервис продолжает работать со старыми ключами — в логах будет `ERROR: Failed to refresh ...`.
|
||
|
||
## Безопасность Dockerfile
|
||
|
||
- **Non-root user** (uid 1001) — контейнер не работает от root
|
||
- **tini** как PID 1 — корректная обработка `SIGTERM` / `SIGKILL`
|
||
- **Multi-stage build** — в финальный образ попадают только production deps + компилированный dist
|
||
- **Alpine base** — минимальный образ (~150 MB)
|
||
- **Healthcheck** — Docker рестартит контейнер если API упал
|
||
- **Log rotation** — max 5×20MB логов, не забьёт диск
|
||
|
||
## Troubleshooting
|
||
|
||
**`Vault AppRole login failed`**
|
||
- Проверь VAULT_ROLE_ID / VAULT_SECRET_ID в .env
|
||
- Проверь доступ: `curl -v https://corp.vault.elcsa.ru/v1/sys/health`
|
||
|
||
**`password authentication failed for user "postgres_user"`**
|
||
- Креды в `.env` не совпадают с тем что в Vault (или с реальной БД)
|
||
- Решение: либо подставь пароль из Vault в `.env`, либо оставь пустыми — Vault перекроет при логине
|
||
|
||
**Таблицы не существуют (relation does not exist)**
|
||
- Не применён `db/schema.sql` — см. шаг 4 в Quick Start
|
||
|
||
**Port 3001 занят**
|
||
- `sudo lsof -i :3001`
|
||
- Измени порт: в `docker-compose.yml` `"3002:3001"` и в `ufw allow 3002`
|
||
|
||
**Нет места на диске**
|
||
- `docker system prune -a` — удалит старые образы
|
||
|
||
## Автозапуск при reboot
|
||
|
||
Restart policy `unless-stopped` уже настроен. Убедись что Docker стартует:
|
||
```bash
|
||
sudo systemctl enable docker
|
||
```
|