Содержание

Что нужно для старта

  • VPS с Ubuntu 22.04 (от любого провайдера: Hetzner, DigitalOcean, Timeweb)
  • Домен или просто IP-адрес
  • Локально: SSH-клиент и репозиторий с Dockerfile + docker-compose.yml

Подключаемся к серверу

ssh root@YOUR_SERVER_IP

Первым делом — обновляем систему и создаём пользователя вместо root:

apt update && apt upgrade -y

# Создаём пользователя
adduser deploy
usermod -aG sudo deploy

# Копируем SSH-ключ для нового пользователя
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

Устанавливаем Docker

# Официальный скрипт установки
curl -fsSL https://get.docker.com | sh

# Добавляем пользователя в группу docker (не нужен sudo)
usermod -aG docker deploy

# Проверяем
docker --version
docker compose version

💡 После usermod нужно перелогиниться: exit и снова ssh deploy@IP.

Клонируем проект на сервер

# На сервере
cd /home/deploy
git clone https://github.com/your-user/your-repo.git app
cd app

Если репозиторий приватный — добавь SSH-ключ сервера в GitHub:

# Генерируем ключ на сервере
ssh-keygen -t ed25519 -C "deploy@server"

# Копируем публичный ключ
cat ~/.ssh/id_ed25519.pub
# Добавляем в GitHub → Settings → Deploy keys

Настраиваем переменные окружения

# На сервере создаём .env (не коммитим его в git!)
cp .env.example .env
nano .env
# .env на сервере
POSTGRES_USER=myuser
POSTGRES_PASSWORD=strong_password_here
POSTGRES_DB=myapp
APP_PORT=3000
NODE_ENV=production

Запускаем приложение

# Собрать образы и запустить в фоне
docker compose up -d --build

# Проверить статус
docker compose ps

# Посмотреть логи
docker compose logs -f app

Если всё запустилось — приложение доступно на http://IP:3000.

Nginx как reverse proxy

Nginx принимает запросы на 80/443 и проксирует их в контейнер. Без него не будет HTTPS и красивого домена.

Добавляем Nginx в docker-compose.yml:

services:
  app:
    build: .
    expose:
      - "3000"       # Порт открыт только внутри сети Docker
    networks:
      - web

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      - ./nginx/certs:/etc/nginx/certs:ro
    depends_on:
      - app
    networks:
      - web

networks:
  web:
    driver: bridge

Конфиг nginx/default.conf:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass         http://app:3000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection 'upgrade';
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

💡 Для HTTPS — используй Certbot или замени Nginx на Caddy: он сам получает SSL-сертификат без настройки.

Автодеплой через GitHub Actions

Каждый пуш в main — автоматический деплой на сервер (основы Actions — в отдельной статье).

Создай .github/workflows/deploy.yml:

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host:     ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key:      ${{ secrets.SERVER_SSH_KEY }}
          script: |
            cd /home/deploy/app
            git pull origin main
            docker compose up -d --build
            docker image prune -f

Добавь секреты в GitHub → Settings → Secrets and variables → Actions:

  • SERVER_HOST — IP сервера
  • SERVER_USERdeploy
  • SERVER_SSH_KEY — приватный ключ (cat ~/.ssh/id_ed25519)

Полезные команды на сервере

# Смотрим что занимает место
docker system df

# Удаляем неиспользуемые образы и слои
docker system prune -f

# Перезапустить один сервис без даунтайма
docker compose up -d --no-deps --build app

# Зайти в контейнер
docker compose exec app sh

# Бэкап базы данных
docker compose exec db pg_dump -U myuser myapp > backup_$(date +%Y%m%d).sql

⚠️ Всегда проверяй docker compose logs после деплоя — контейнер может стартовать, но падать внутри.

Поделиться: