Автоматический деплой

Зачем нужно

Автоматический деплой (auto-deploy) — это развёртывание приложения на сервере без ручных действий. Push в main = приложение обновлено. Это устраняет человеческий фактор, ускоряет доставку и делает процесс повторяемым.

Где используется

  • Фронтенд-проекты — деплой на Vercel/Netlify/Pages при push
  • Бэкенд — обновление сервера после мержа в main
  • Staging — автоматическое обновление тестового окружения
  • Preview — временный деплой для каждого PR

Deploy on Push

Базовая схема

Developer → Push to main → CI checks pass → Auto deploy

GitHub Actions + GitHub Pages

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - name: Deploy to Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

GitHub Actions + VPS (SSH деплой)

name: Deploy to VPS

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --production
            npm run build
            pm2 restart app

Environment Variables

Управление переменными окружения

.env.development    ← локальная разработка
.env.staging        ← staging-сервер
.env.production     ← production-сервер
# .env.production (НИКОГДА не коммитить!)
DATABASE_URL=postgres://user:pass@db:5432/prod
API_KEY=sk-prod-xxxxx
JWT_SECRET=super-secret-prod-key
NODE_ENV=production

Секреты в GitHub Actions

# Секреты задаются в Settings → Secrets → Actions
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production    # привязка к environment
    steps:
      - name: Build with env vars
        env:
          VITE_API_URL: ${{ secrets.API_URL }}
          VITE_GA_ID: ${{ secrets.GA_TRACKING_ID }}
        run: npm run build

GitHub Environments

Repository Settings → Environments
├── staging
│   ├── Secrets: API_URL, DB_URL
│   └── Protection: none
├── production
│   ├── Secrets: API_URL, DB_URL
│   └── Protection: required reviewers
jobs:
  deploy-staging:
    environment: staging
    # ...

  deploy-production:
    environment: production
    needs: deploy-staging
    # ...

Staging vs Production

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│ Development │    │   Staging   │    │ Production  │
│  (local)    │───▶│  (preview)  │───▶│   (live)    │
│             │    │             │    │             │
│ localhost   │    │ staging.app │    │  app.com    │
│ .env.dev    │    │ .env.stag   │    │ .env.prod   │
│ mock data   │    │ test data   │    │ real data   │
└─────────────┘    └─────────────┘    └─────────────┘
Staging Production
Данные Тестовые Реальные пользователи
Доступ Команда Публичный
Обновление На каждый push в develop На push в main
Ошибки Допустимы Критичны
Тестирование QA, E2E тесты Мониторинг

Rollback-стратегии

1. Git revert

# Откатить последний коммит
git revert HEAD
git push origin main
# CI/CD автоматически задеплоит откат

2. Повторный деплой предыдущей версии

# В GitHub Actions — ручной запуск с указанием коммита
on:
  workflow_dispatch:
    inputs:
      commit_sha:
        description: 'Commit SHA to deploy'
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.commit_sha }}
      - run: npm ci && npm run build
      # ... deploy steps

3. Blue-Green Deployment

                    ┌──────────┐
        ┌──────────▶│  Blue    │ (текущая версия)
        │           │  v1.0    │
Users ──┤           └──────────┘
        │           ┌──────────┐
        └──────────▶│  Green   │ (новая версия)
                    │  v1.1    │
                    └──────────┘

Переключение: меняем маршрут с Blue на Green
Откат: переключаем обратно на Blue

4. Canary Deployment

Users (100%)
├── 90% → Version 1.0 (stable)
└── 10% → Version 1.1 (canary)

Если canary стабилен:
Users (100%) → Version 1.1

Preview Deployments

Временный деплой для каждого PR — позволяет ревьюеру увидеть изменения.

# Vercel/Netlify делают это автоматически
# Для GitHub Pages — ручной вариант:
name: Preview Deploy

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

      - name: Deploy Preview
        uses: rossjrw/pr-preview-action@v1
        with:
          source-dir: ./dist/

Пример: полный pipeline

name: Full Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  # 1. Проверка кода
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: 'npm' }
      - run: npm ci
      - run: npm run lint
      - run: npm run build
      - run: npm test
      - uses: actions/upload-artifact@v4
        with: { name: dist, path: dist/ }

  # 2. Деплой на staging (develop)
  deploy-staging:
    needs: ci
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/download-artifact@v4
        with: { name: dist, path: dist/ }
      - name: Deploy to Staging
        run: echo "Deploy to staging..."

  # 3. Деплой на production (main)
  deploy-production:
    needs: ci
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with: { name: dist, path: dist/ }
      - name: Deploy to Production
        run: echo "Deploy to production..."

Частые ошибки

Ошибка Проблема Решение
Секреты в коде Утечка через Git .env в .gitignore, secrets в CI
Нет rollback плана Невозможно откатить Заранее протестируй git revert
Staging отличается от prod Баги только на prod Одинаковая конфигурация, Docker
Нет preview deploys Ревьюер не видит изменения Vercel/Netlify авто-preview
Деплой без тестов Баги на проде CI обязателен перед deploy

Практика

  1. Настрой auto-deploy на GitHub Pages через Actions
  2. Создай staging и production environments в GitHub
  3. Добавь секреты окружения для API ключей
  4. Попробуй rollback через git revert
  5. Настрой Vercel для preview deployments на PR

Связанные темы

  • GitHub Actions — CI/CD платформа
  • Vercel — деплой фронтенда
  • Netlify — деплой статических сайтов
  • GitHub Pages — бесплатный хостинг
  • Docker Compose — контейнеризация для деплоя

Ресурсы