- Docker и Docker Compose установлены
- Git (для клонирования репозитория, если нужно)
В docker-compose.yml используется внешняя сеть atom-external-network. Создайте её перед запуском:
docker network create atom-external-networkЕсли сеть уже существует, эта команда выдаст предупреждение, но это нормально.
Создайте файл .env в корне проекта для настройки переменных окружения (или используйте значения по умолчанию):
# База данных
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=atom_dbro
POSTGRES_PORT=5432
# Приложение
PORT=3000
# JWT
JWT_SECRET=your-secret-key-change-in-production
JWT_EXPIRES_IN=24h
# Database URL (автоматически формируется из переменных выше)
DATABASE_URL=postgresql://postgres:postgres@postgres:5432/atom_dbro
# S3 Configuration (ОБЯЗАТЕЛЬНО)
S3_BUCKET_NAME=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key-id
S3_SECRET_ACCESS_KEY=your-secret-access-key
S3_REGION=us-east-1
# S3 Configuration (опционально, для кастомных провайдеров)
# S3_ENDPOINT=https://s3.ru1.storage.beget.cloud
# S3_PUBLIC_URL_TEMPLATE=https://{bucket}.s3.{region}.amazonaws.com/{key}
# S3_FORCE_PATH_STYLE=true- В продакшене обязательно измените
JWT_SECRETиPOSTGRES_PASSWORDна безопасные значения! - S3 переменные обязательны - приложение не запустится без них. Укажите как минимум:
S3_BUCKET_NAMES3_ACCESS_KEY_ID(илиAWS_ACCESS_KEY_ID)S3_SECRET_ACCESS_KEY(илиAWS_SECRET_ACCESS_KEY)
docker compose up -d --builddocker compose up -dЭта команда:
- Соберёт образ приложения из Dockerfile
- Запустит PostgreSQL контейнер
- Запустит приложение в контейнере
- Подождёт, пока PostgreSQL станет здоровым, перед запуском приложения
После первого запуска контейнеров нужно выполнить миграции базы данных:
# Войти в контейнер приложения
docker exec -it atom-dbro-app sh
# Выполнить миграции
npm run db:migrate
# Выйти из контейнера
exitИли одной командой:
docker exec -it atom-dbro-app npm run db:migratedocker compose ps# Все сервисы
docker compose logs -f
# Только приложение
docker compose logs -f app
# Только база данных
docker compose logs -f postgres- Приложение: http://localhost:3000 (или http://<IP_СЕРВЕРА>:3000 для доступа извне)
- Swagger документация: http://localhost:3000/api
✅ Приложение настроено для доступа извне - порт проброшен на все интерфейсы (0.0.0.0), поэтому сервис доступен не только с localhost, но и по IP-адресу сервера из внешней сети.
- Узнайте IP-адрес сервера:
# Linux/Mac
hostname -I
# или
ip addr show
# Windows
ipconfig-
Проверьте доступность извне:
- С другого компьютера в той же сети:
http://<IP_СЕРВЕРА>:3000 - Или используйте curl:
curl http://<IP_СЕРВЕРА>:3000
- С другого компьютера в той же сети:
-
Настройка Firewall (если приложение недоступно):
Linux (ufw):
sudo ufw allow 3000/tcp sudo ufw reload
Linux (firewalld):
sudo firewall-cmd --permanent --add-port=3000/tcp sudo firewall-cmd --reload
Windows Firewall:
- Откройте "Брандмауэр Защитника Windows"
- Создайте правило для входящих подключений на порт 3000
docker compose stopdocker compose downdocker compose down -vdocker compose up -d --build app# Войти в контейнер приложения
docker exec -it atom-dbro-app sh
# Выполнить скрипт импорта городов (если нужно)
docker exec -it atom-dbro-app npm run import:citiesdocker compose logs -f app# Войти в контейнер PostgreSQL
docker exec -it atom-dbro-postgres psql -U postgres -d atom_dbroОшибка: network atom-external-network not found
Решение: Создайте сеть командой:
docker network create atom-external-networkОшибка: port is already allocated
Решение: Измените порт в .env файле или docker-compose.yml:
APP_PORT=3001
POSTGRES_PORT=5433Решение:
- Убедитесь, что PostgreSQL контейнер запущен:
docker compose ps - Проверьте переменную
DATABASE_URLв контейнере:docker exec atom-dbro-app env | grep DATABASE_URL - Проверьте логи:
docker compose logs postgres
Решение:
- В development режиме код монтируется через volumes, но нужно перезапустить контейнер:
docker compose restart app- Для production изменений нужно пересобрать образ:
docker compose up -d --build app- При автоматическом деплое через GitHub Actions образ пересобирается автоматически при каждом push
Для production окружения рекомендуется:
- Использовать .env файл с безопасными паролями и секретами
- Настроить reverse proxy (nginx, traefik) перед приложением
- Настроить SSL/TLS сертификаты
- Использовать managed базу данных вместо контейнера PostgreSQL
- Настроить мониторинг и логирование
- Настроить backup базы данных
- Использовать Docker secrets для чувствительных данных
Проект настроен для автоматического деплоя через GitHub Actions. При каждом push в ветку main происходит автоматическая сборка Docker образа, экспорт в архив, передача на сервер через SSH и деплой.
Перед использованием CI/CD необходимо настроить секреты в GitHub:
- Перейдите в репозиторий на GitHub
- Откройте Settings → Secrets and variables → Actions
- Добавьте следующие секреты:
-
DEPLOY_HOST- IP-адрес или домен сервера деплоя- Пример:
192.168.1.100илиdeploy.example.com
- Пример:
-
DEPLOY_USER- Пользователь для SSH подключения- Пример:
root,deploy,ubuntu
- Пример:
-
DEPLOY_SSH_KEY- Приватный SSH ключ для доступа к серверу- Содержимое файла
~/.ssh/id_rsa(или другого приватного ключа) ⚠️ ВАЖНО: Используйте ключ без пароля или настройте ssh-agent
- Содержимое файла
-
DEPLOY_PROJECT_PATH- Абсолютный путь к директории проекта на сервере- Пример:
/home/user/atom-dbro-backendили/opt/atom-dbro-backend ⚠️ ВАЖНО:- Путь должен существовать на сервере и содержать
docker-compose.yml - Используйте абсолютный путь (не
~/)
- Путь должен существовать на сервере и содержать
- Пример:
-
DOCKER_IMAGE_NAME- Название Docker образа- По умолчанию:
atom-dbro-backend ⚠️ ВАЖНО:- Используйте только строчные буквы, цифры, дефисы, подчеркивания и точки
- Не используйте заглавные буквы или специальные символы
- Правильно:
atom-dbro-backend,my-app,app_v1.0 - Неправильно:
Atom-Dbro-Backend,my app,app@v1
- По умолчанию:
-
DEPLOY_CONTAINER_NAME- Название контейнера приложения- По умолчанию:
atom-dbro-app - Должно соответствовать
container_nameвdocker-compose.yml
- По умолчанию:
-
DEPLOY_SERVICE_NAME- Название сервиса в docker-compose.yml- По умолчанию:
app - Должно соответствовать имени сервиса в
docker-compose.yml
- По умолчанию:
-
DEPLOY_COMPOSE_PROJECT_NAME- Имя проекта (стек) для docker compose- По умолчанию: не установлен (используется имя директории)
- Используйте, если нужно явно указать имя стека
- Пример:
atom-dbro-backend
-
DEPLOY_SSH_PORT- Порт SSH- По умолчанию:
22
- По умолчанию:
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose# Создайте директорию для проекта (выберите подходящий путь)
# Вариант 1: в домашней директории пользователя
mkdir -p ~/atom-dbro-backend
cd ~/atom-dbro-backend
# Вариант 2: в системной директории
sudo mkdir -p /opt/atom-dbro-backend
sudo chown $USER:$USER /opt/atom-dbro-backend
cd /opt/atom-dbro-backend- Запомните выбранный путь - он понадобится для секрета
DEPLOY_PROJECT_PATHв GitHub! - Используйте абсолютный путь (например,
/home/user/atom-dbro-backend, а не~/atom-dbro-backend)
Скопируйте на сервер следующие файлы:
# docker-compose.yml
# .env (с production переменными окружения)Или клонируйте репозиторий (только для чтения):
git clone https://github.com/Web2Bizz/atom-dbro-backend.git ~/atom-dbro-backend
cd ~/atom-dbro-backenddocker-compose.yml находится в корне директории проекта!
docker network create atom-external-network
docker network create atom-internal-networkСоздайте файл .env в директории проекта с production переменными:
# База данных
POSTGRES_USER=postgres
POSTGRES_PASSWORD=your-secure-password
POSTGRES_DB=atom_dbro
POSTGRES_PORT=5432
# Приложение
PORT=3000
# JWT
JWT_SECRET=your-very-secure-secret-key
JWT_EXPIRES_IN=24h
# Database URL
DATABASE_URL=postgresql://postgres:your-secure-password@postgres:5432/atom_dbro
# S3 Configuration
S3_BUCKET_NAME=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key-id
S3_SECRET_ACCESS_KEY=your-secret-access-key
S3_REGION=us-east-1
# Docker Image (для docker-compose.yml)
# Переменная DOCKER_IMAGE будет установлена автоматически при деплое
# Не нужно указывать в .env файлеВажно: SSH ключ должен быть настроен правильно, иначе деплой не будет работать.
На вашем локальном компьютере создайте новую пару SSH ключей:
# Создайте SSH ключ (без пароля для автоматизации)
ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/github_actions_deploy -N ""
# Или используйте RSA (если ed25519 не поддерживается)
ssh-keygen -t rsa -b 4096 -C "github-actions-deploy" -f ~/.ssh/github_actions_deploy -N ""# Вариант 1: Используя ssh-copy-id (рекомендуется)
# Замените USER и HOST на ваши значения
ssh-copy-id -i ~/.ssh/github_actions_deploy.pub USER@HOST
# Вариант 2: Вручную
# Скопируйте содержимое публичного ключа
cat ~/.ssh/github_actions_deploy.pub
# На сервере добавьте ключ в authorized_keys
# Подключитесь к серверу
ssh USER@HOST
# На сервере выполните:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ВАШ_ПУБЛИЧНЫЙ_КЛЮЧ_СЮДА" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
exitПроверьте, что подключение работает:
# Тест подключения с использованием приватного ключа
# Замените USER, HOST и PORT на ваши значения
ssh -i ~/.ssh/github_actions_deploy -p PORT USER@HOST \
"echo 'SSH connection successful' && hostname"Если подключение успешно, переходите к следующему шагу.
# Покажите приватный ключ (скопируйте ВСЁ содержимое, включая заголовки)
cat ~/.ssh/github_actions_deployВажно: Копируйте весь ключ, включая строки:
-----BEGIN OPENSSH PRIVATE KEY-----(или-----BEGIN RSA PRIVATE KEY-----)- Все строки ключа
-----END OPENSSH PRIVATE KEY-----(или-----END RSA PRIVATE KEY-----)
Добавьте скопированное содержимое в GitHub:
- Перейдите в репозиторий → Settings → Secrets and variables → Actions
- Нажмите New repository secret
- Name:
DEPLOY_SSH_KEY - Secret: вставьте весь приватный ключ
- Нажмите Add secret
Убедитесь, что пользователь имеет необходимые права:
# На сервере (замените USER и PROJECT_PATH на ваши значения)
sudo usermod -aG docker USER
# Проверьте права на директорию проекта
ls -la PROJECT_PATH# Убедитесь, что пользователь может выполнять docker команды
sudo usermod -aG docker $USER
# Настройте права на директорию проекта
chmod 755 ~/atom-dbro-backendПосле настройки, при каждом push в ветку main:
- GitHub Actions запускает workflow (
.github/workflows/deploy.yml) - Сборка Docker образа с тегом
latest - Экспорт образа в архив
image.tar.gz - Передача образа на сервер через SSH (SCP)
- Подключение к серверу через SSH и выполнение деплоя:
- Загрузка образа в Docker (
docker load) - Остановка и удаление старого контейнера приложения
- Запуск нового контейнера через
docker compose(только сервис приложения, без зависимостей) - Проверка готовности контейнера
- Health check приложения (проверка доступности API)
- Очистка неиспользуемых Docker ресурсов
- Загрузка образа в Docker (
- Уведомление о результате в GitHub Actions
- Миграции базы данных не выполняются автоматически - их нужно запускать вручную при необходимости
- Перезапускается только контейнер приложения, база данных не затрагивается
- Используется
docker compose(неdocker-compose)
Для ручного деплоя выполните следующие шаги:
- Соберите Docker образ (локально или на сервере):
docker build -t atom-dbro-backend:latest .- На сервере перезапустите контейнер:
cd /path/to/project
export DOCKER_IMAGE="atom-dbro-backend:latest"
docker compose up -d --force-recreate --no-deps appИли используйте скрипт scripts/deploy.sh (если он существует и настроен).
Ошибка: Permission denied (publickey)
Решение:
-
Проверьте, что SSH ключ добавлен в GitHub Secrets:
- Убедитесь, что секрет
DEPLOY_SSH_KEYсуществует - Проверьте, что ключ скопирован полностью (включая заголовки
-----BEGINи-----END) - Убедитесь, что нет лишних пробелов или переносов строк
- Убедитесь, что секрет
-
Проверьте публичный ключ на сервере:
# На сервере cat ~/.ssh/authorized_keys # Должен быть ваш публичный ключ (начинается с ssh-ed25519 или ssh-rsa)
-
Проверьте права доступа на сервере:
# На сервере chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys ls -la ~/.ssh
-
Проверьте SSH доступ вручную:
# На локальном компьютере ssh -i ~/.ssh/github_actions_deploy -p PORT USER@HOST
-
Проверьте firewall на сервере:
# На сервере sudo ufw status # Если SSH порт закрыт: sudo ufw allow PORT/tcp
-
Проверьте SSH сервис:
# На сервере sudo systemctl status ssh # Или для некоторых систем: sudo systemctl status sshd
-
Проверьте логи SSH на сервере:
# На сервере sudo tail -f /var/log/auth.log # Или для некоторых систем: sudo tail -f /var/log/secure
-
Убедитесь, что ключ без пароля:
- Если ключ защищен паролем, GitHub Actions не сможет его использовать
- Создайте новый ключ без пароля:
ssh-keygen -t ed25519 -N ""
Ошибка: ❌ ERROR: PROJECT_DIR is not set
Решение:
- Убедитесь, что секрет
DEPLOY_PROJECT_PATHустановлен в GitHub Secrets - Используйте абсолютный путь (например,
/home/user/atom-dbro-backend, а не~/atom-dbro-backend) - Проверьте, что путь существует на сервере
Ошибка: ❌ ERROR: Service 'app' not found in docker-compose.yml
Решение:
- Убедитесь, что файл
docker-compose.ymlсуществует в директории проекта - Проверьте, что сервис с нужным именем существует в
docker-compose.yml - Если сервис называется по-другому, установите секрет
DEPLOY_SERVICE_NAMEс правильным именем
Ошибка: no such service: app
Решение:
- Проверьте, что в
docker-compose.ymlесть сервис с именем, указанным вDEPLOY_SERVICE_NAME(по умолчаниюapp) - Убедитесь, что вы находитесь в правильной директории проекта
- Проверьте синтаксис
docker-compose.yml
Решение:
- Проверьте логи:
docker logs <CONTAINER_NAME>(замените на имя вашего контейнера) - Убедитесь, что
.envфайл настроен правильно - Проверьте, что Docker сети созданы:
docker network ls - Проверьте доступность образа:
docker images | grep <IMAGE_NAME> - Проверьте, что переменная
DOCKER_IMAGEустановлена в окружении перед запускомdocker compose
Ошибка: ❌ Health check failed after 30 attempts
Решение:
- Проверьте логи контейнера:
docker logs <CONTAINER_NAME> --tail 100 - Убедитесь, что приложение запустилось и слушает на порту 3000
- Проверьте, что порт 3000 проброшен в
docker-compose.yml - Проверьте доступность приложения вручную:
curl http://localhost:3000/api - Убедитесь, что приложение полностью инициализировалось (может потребоваться больше времени)
Ошибка: Запускается стек с неправильным именем (например, atom-dbro-gateway вместо нужного)
Решение:
- Установите секрет
DEPLOY_COMPOSE_PROJECT_NAMEс правильным именем стека - Или убедитесь, что вы находитесь в правильной директории проекта
- Проверьте, какой project name использует docker compose:
docker compose ps
Все деплои можно отслеживать в GitHub:
- Перейдите в репозиторий → Actions
- Выберите нужный workflow run
- Просмотрите логи каждого шага
┌─────────────────────────────────────┐
│ atom-external-network │
│ (внешняя сеть) │
│ │
│ ┌─────────────────────────────┐ │
│ │ atom-dbro-app │ │
│ │ (порт 3000) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
│
│
┌─────────────────────────────────────┐
│ atom-internal-network │
│ (внутренняя сеть) │
│ │
│ ┌─────────────────────────────┐ │
│ │ atom-dbro-app │ │
│ └─────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────┐ │
│ │ atom-dbro-postgres │ │
│ │ (порт 5432) │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘