← JavaScript/CI/CD: деплой и автоматизация#365 из 383← ПредыдущийСледующий →+20 XP
Полезно по теме:Гайд: как учить JavaScriptПрактика: JS базаПрактика: async и сетьТермин: Closure

CI/CD: деплой и автоматизация

Стратегии деплоя

Ручной деплой

Самый простой, но рискованный способ:

# «Классический» деплой по SSH
ssh user@server
cd /var/www/my-app
git pull origin main
npm install
npm run build
pm2 restart all

Проблемы: человеческий фактор, забыл шаг, разные версии на серверах, нет отката.

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

Код попадает в production автоматически после прохождения CI:

Push → CI (тесты, линт, сборка) → ✅ → Auto Deploy
                                   ❌ → Остановка, уведомление

Blue-Green Deployment

Две идентичные среды: Blue (текущая) и Green (новая версия).

Трафик → [Blue v1.0] ← текущая production
         [Green v1.1] ← новая версия, тестируется

# После проверки — переключаем трафик:
Трафик → [Green v1.1] ← теперь production
         [Blue v1.0] ← можно откатиться мгновенно

Canary Deployment

Новая версия раскатывается постепенно — сначала на 5% пользователей, потом 25%, потом 100%.

95% трафика → [v1.0]
 5% трафика → [v1.1] ← наблюдаем за метриками

# Если всё хорошо:
 0% трафика → [v1.0]
100% трафика → [v1.1]

Окружения (Environments)

Типичная цепочка окружений

Development → Staging → Production
  (dev)       (stage)    (prod)

| Окружение | Назначение | Данные |

|-----------|------------|--------|

| Development | Локальная разработка | Моковые данные |

| Staging | Предпродакшн тестирование | Копия production данных |

| Production | Реальные пользователи | Реальные данные |

GitHub Environments

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - name: Deploy to staging
        run: ./deploy.sh staging
        env:
          API_URL: ${{ vars.API_URL }}
          API_KEY: ${{ secrets.API_KEY }}

  deploy-production:
    runs-on: ubuntu-latest
    environment: production
    needs: deploy-staging
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - name: Deploy to production
        run: ./deploy.sh production
        env:
          API_URL: ${{ vars.API_URL }}
          API_KEY: ${{ secrets.API_KEY }}

GitHub Environments позволяют настроить ручное подтверждение деплоя. Для production можно потребовать approval от тимлида.

Vercel — автодеплой фронтенда

Vercel — платформа для деплоя фронтенд-приложений (Next.js, React, Vue).

Как это работает

1. Подключить GitHub репозиторий к Vercel

2. Каждый push в main → автоматический деплой в production

3. Каждый PR → preview deployment с уникальным URL

Push в main     → https://my-app.vercel.app (production)
Push в feature  → https://my-app-abc123.vercel.app (preview)

Настройка через GitHub Actions

name: Deploy to Vercel

on:
  push:
    branches: [main]

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

      - name: Install Vercel CLI
        run: npm install -g vercel

      - name: Pull Vercel config
        run: vercel pull --yes --token ${{ secrets.VERCEL_TOKEN }}

      - name: Build
        run: vercel build --prod --token ${{ secrets.VERCEL_TOKEN }}

      - name: Deploy
        run: vercel deploy --prebuilt --prod --token ${{ secrets.VERCEL_TOKEN }}

Netlify — альтернатива Vercel

Netlify — ещё одна популярная платформа для фронтенда.

name: Deploy to Netlify

on:
  push:
    branches: [main]

jobs:
  deploy:
    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 build

      - name: Deploy to Netlify
        uses: nwtgck/actions-netlify@v3
        with:
          publish-dir: './dist'
          production-branch: main
          deploy-message: 'Deploy from GitHub Actions'
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

Docker для фронтенда

Docker — инструмент контейнеризации. Упаковывает приложение вместе со всеми зависимостями в контейнер, который одинаково работает везде.

Dockerfile для React

# Этап 1: сборка
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Этап 2: production-сервер
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Сборка и запуск

# Собрать образ
docker build -t my-app .

# Запустить контейнер
docker run -p 3000:80 my-app

# Открыть http://localhost:3000

CI с Docker

name: Docker Build & Push

on:
  push:
    branches: [main]

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

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: myuser/my-app:latest

Переменные окружения в CI

Secrets в GitHub

Секреты хранятся в Settings → Secrets and variables → Actions.

steps:
  - name: Deploy
    run: ./deploy.sh
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}

Правила безопасности:

  • Никогда не хардкодить секреты в коде
  • Никогда не коммитить .env файлы
  • Использовать разные секреты для staging и production
  • Ротировать ключи регулярно
  • Variables (несекретные)

    steps:
      - name: Build
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ vars.API_URL }}
          NODE_ENV: production

    Variables видны в логах, Secrets — замаскированы (***).

    Кэширование зависимостей

    CI каждый раз стартует с чистого окружения. Без кэша npm install загружает все пакеты заново — это медленно.

    Кэширование npm

    steps:
      - uses: actions/checkout@v4
    
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'  # автоматическое кэширование!
    
      - run: npm ci

    Ручное кэширование

    steps:
      - uses: actions/checkout@v4
    
      - name: Cache node_modules
        uses: actions/cache@v4
        with:
          path: node_modules
          key: node-modules-${{ hashFiles('package-lock.json') }}
          restore-keys: |
            node-modules-
    
      - run: npm ci

    Ключ кэша основан на хэше package-lock.json. Если зависимости не менялись — используется кэш. Это ускоряет CI в 2–3 раза.

    Preview Deployments

    Preview deployment — временный деплой для каждого Pull Request. Позволяет тестировать изменения до мержа.

    name: Preview Deploy
    
    on:
      pull_request:
        branches: [main]
    
    jobs:
      preview:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run build
    
          - name: Deploy Preview
            id: deploy
            run: |
              url=$(vercel deploy --token ${{ secrets.VERCEL_TOKEN }})
              echo "url=$url" >> "$GITHUB_OUTPUT"
    
          - name: Comment PR
            uses: actions/github-script@v7
            with:
              script: |
                github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: context.issue.number,
                  body: '🚀 Preview: ${{ steps.deploy.outputs.url }}'
                })

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

    Мониторинг после деплоя

    Деплой — это не финальный шаг. После выкатки нужно следить за приложением.

    Что мониторить

  • Ошибки — Sentry, LogRocket (JavaScript ошибки в реальном времени)
  • Производительность — Core Web Vitals (LCP, FID, CLS)
  • Доступность — Uptime monitoring (UptimeRobot, Pingdom)
  • Аналитика — пользователи действительно используют новую фичу?
  • Health Check в CI

    - name: Health check
      run: |
        sleep 30
        response=$(curl -s -o /dev/null -w "%{http_code}" https://my-app.com/api/health)
        if [ "$response" != "200" ]; then
          echo "Health check failed with status $response"
          exit 1
        fi
        echo "Health check passed"

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

    - name: Smoke test
      id: smoke
      continue-on-error: true
      run: |
        curl -f https://my-app.com || exit 1
    
    - name: Rollback on failure
      if: steps.smoke.outcome == 'failure'
      run: |
        echo "Smoke test failed, rolling back..."
        vercel rollback --token ${{ secrets.VERCEL_TOKEN }}

    Чеклист CI/CD для проекта

    1. ✅ Линтинг (ESLint, Prettier) на каждый PR

    2. ✅ TypeScript проверка (tsc --noEmit) на каждый PR

    3. ✅ Тесты на каждый PR и push в main

    4. ✅ Сборка проекта (npm run build)

    5. ✅ Preview deploy для PR

    6. ✅ Автодеплой в staging при мерже в develop

    7. ✅ Автодеплой в production при мерже в main

    8. ✅ Health check после деплоя

    9. ✅ Мониторинг ошибок (Sentry)

    10. ✅ Branch protection rules — CI обязателен для мержа

    Примеры

    Деплой в production только после успешного CI

    name: Deploy
    
    on:
      push:
        branches: [main]
    
    jobs:
      verify:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run lint
          - run: npm test
          - run: npm run build
    
      deploy:
        runs-on: ubuntu-latest
        needs: verify
        environment: production
        steps:
          - uses: actions/checkout@v4
          - name: Deploy script
            run: ./deploy.sh production

    Двухэтапный Dockerfile для frontend-приложения

    FROM node:20-alpine AS build
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    
    FROM nginx:alpine
    COPY --from=build /app/dist /usr/share/nginx/html
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]

    CI/CD: деплой и автоматизация

    Стратегии деплоя

    Ручной деплой

    Самый простой, но рискованный способ:

    # «Классический» деплой по SSH
    ssh user@server
    cd /var/www/my-app
    git pull origin main
    npm install
    npm run build
    pm2 restart all

    Проблемы: человеческий фактор, забыл шаг, разные версии на серверах, нет отката.

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

    Код попадает в production автоматически после прохождения CI:

    Push → CI (тесты, линт, сборка) → ✅ → Auto Deploy
                                       ❌ → Остановка, уведомление

    Blue-Green Deployment

    Две идентичные среды: Blue (текущая) и Green (новая версия).

    Трафик → [Blue v1.0] ← текущая production
             [Green v1.1] ← новая версия, тестируется
    
    # После проверки — переключаем трафик:
    Трафик → [Green v1.1] ← теперь production
             [Blue v1.0] ← можно откатиться мгновенно

    Canary Deployment

    Новая версия раскатывается постепенно — сначала на 5% пользователей, потом 25%, потом 100%.

    95% трафика → [v1.0]
     5% трафика → [v1.1] ← наблюдаем за метриками
    
    # Если всё хорошо:
     0% трафика → [v1.0]
    100% трафика → [v1.1]

    Окружения (Environments)

    Типичная цепочка окружений

    Development → Staging → Production
      (dev)       (stage)    (prod)

    | Окружение | Назначение | Данные |

    |-----------|------------|--------|

    | Development | Локальная разработка | Моковые данные |

    | Staging | Предпродакшн тестирование | Копия production данных |

    | Production | Реальные пользователи | Реальные данные |

    GitHub Environments

    jobs:
      deploy-staging:
        runs-on: ubuntu-latest
        environment: staging
        steps:
          - uses: actions/checkout@v4
          - run: npm ci && npm run build
          - name: Deploy to staging
            run: ./deploy.sh staging
            env:
              API_URL: ${{ vars.API_URL }}
              API_KEY: ${{ secrets.API_KEY }}
    
      deploy-production:
        runs-on: ubuntu-latest
        environment: production
        needs: deploy-staging
        steps:
          - uses: actions/checkout@v4
          - run: npm ci && npm run build
          - name: Deploy to production
            run: ./deploy.sh production
            env:
              API_URL: ${{ vars.API_URL }}
              API_KEY: ${{ secrets.API_KEY }}

    GitHub Environments позволяют настроить ручное подтверждение деплоя. Для production можно потребовать approval от тимлида.

    Vercel — автодеплой фронтенда

    Vercel — платформа для деплоя фронтенд-приложений (Next.js, React, Vue).

    Как это работает

    1. Подключить GitHub репозиторий к Vercel

    2. Каждый push в main → автоматический деплой в production

    3. Каждый PR → preview deployment с уникальным URL

    Push в main     → https://my-app.vercel.app (production)
    Push в feature  → https://my-app-abc123.vercel.app (preview)

    Настройка через GitHub Actions

    name: Deploy to Vercel
    
    on:
      push:
        branches: [main]
    
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - name: Install Vercel CLI
            run: npm install -g vercel
    
          - name: Pull Vercel config
            run: vercel pull --yes --token ${{ secrets.VERCEL_TOKEN }}
    
          - name: Build
            run: vercel build --prod --token ${{ secrets.VERCEL_TOKEN }}
    
          - name: Deploy
            run: vercel deploy --prebuilt --prod --token ${{ secrets.VERCEL_TOKEN }}

    Netlify — альтернатива Vercel

    Netlify — ещё одна популярная платформа для фронтенда.

    name: Deploy to Netlify
    
    on:
      push:
        branches: [main]
    
    jobs:
      deploy:
        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 build
    
          - name: Deploy to Netlify
            uses: nwtgck/actions-netlify@v3
            with:
              publish-dir: './dist'
              production-branch: main
              deploy-message: 'Deploy from GitHub Actions'
            env:
              NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
              NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

    Docker для фронтенда

    Docker — инструмент контейнеризации. Упаковывает приложение вместе со всеми зависимостями в контейнер, который одинаково работает везде.

    Dockerfile для React

    # Этап 1: сборка
    FROM node:20-alpine AS build
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    
    # Этап 2: production-сервер
    FROM nginx:alpine
    COPY --from=build /app/dist /usr/share/nginx/html
    COPY nginx.conf /etc/nginx/conf.d/default.conf
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]

    Сборка и запуск

    # Собрать образ
    docker build -t my-app .
    
    # Запустить контейнер
    docker run -p 3000:80 my-app
    
    # Открыть http://localhost:3000

    CI с Docker

    name: Docker Build & Push
    
    on:
      push:
        branches: [main]
    
    jobs:
      docker:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - name: Login to Docker Hub
            uses: docker/login-action@v3
            with:
              username: ${{ secrets.DOCKER_USERNAME }}
              password: ${{ secrets.DOCKER_TOKEN }}
    
          - name: Build and push
            uses: docker/build-push-action@v5
            with:
              push: true
              tags: myuser/my-app:latest

    Переменные окружения в CI

    Secrets в GitHub

    Секреты хранятся в Settings → Secrets and variables → Actions.

    steps:
      - name: Deploy
        run: ./deploy.sh
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

    Правила безопасности:

  • Никогда не хардкодить секреты в коде
  • Никогда не коммитить .env файлы
  • Использовать разные секреты для staging и production
  • Ротировать ключи регулярно
  • Variables (несекретные)

    steps:
      - name: Build
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ vars.API_URL }}
          NODE_ENV: production

    Variables видны в логах, Secrets — замаскированы (***).

    Кэширование зависимостей

    CI каждый раз стартует с чистого окружения. Без кэша npm install загружает все пакеты заново — это медленно.

    Кэширование npm

    steps:
      - uses: actions/checkout@v4
    
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'  # автоматическое кэширование!
    
      - run: npm ci

    Ручное кэширование

    steps:
      - uses: actions/checkout@v4
    
      - name: Cache node_modules
        uses: actions/cache@v4
        with:
          path: node_modules
          key: node-modules-${{ hashFiles('package-lock.json') }}
          restore-keys: |
            node-modules-
    
      - run: npm ci

    Ключ кэша основан на хэше package-lock.json. Если зависимости не менялись — используется кэш. Это ускоряет CI в 2–3 раза.

    Preview Deployments

    Preview deployment — временный деплой для каждого Pull Request. Позволяет тестировать изменения до мержа.

    name: Preview Deploy
    
    on:
      pull_request:
        branches: [main]
    
    jobs:
      preview:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run build
    
          - name: Deploy Preview
            id: deploy
            run: |
              url=$(vercel deploy --token ${{ secrets.VERCEL_TOKEN }})
              echo "url=$url" >> "$GITHUB_OUTPUT"
    
          - name: Comment PR
            uses: actions/github-script@v7
            with:
              script: |
                github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: context.issue.number,
                  body: '🚀 Preview: ${{ steps.deploy.outputs.url }}'
                })

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

    Мониторинг после деплоя

    Деплой — это не финальный шаг. После выкатки нужно следить за приложением.

    Что мониторить

  • Ошибки — Sentry, LogRocket (JavaScript ошибки в реальном времени)
  • Производительность — Core Web Vitals (LCP, FID, CLS)
  • Доступность — Uptime monitoring (UptimeRobot, Pingdom)
  • Аналитика — пользователи действительно используют новую фичу?
  • Health Check в CI

    - name: Health check
      run: |
        sleep 30
        response=$(curl -s -o /dev/null -w "%{http_code}" https://my-app.com/api/health)
        if [ "$response" != "200" ]; then
          echo "Health check failed with status $response"
          exit 1
        fi
        echo "Health check passed"

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

    - name: Smoke test
      id: smoke
      continue-on-error: true
      run: |
        curl -f https://my-app.com || exit 1
    
    - name: Rollback on failure
      if: steps.smoke.outcome == 'failure'
      run: |
        echo "Smoke test failed, rolling back..."
        vercel rollback --token ${{ secrets.VERCEL_TOKEN }}

    Чеклист CI/CD для проекта

    1. ✅ Линтинг (ESLint, Prettier) на каждый PR

    2. ✅ TypeScript проверка (tsc --noEmit) на каждый PR

    3. ✅ Тесты на каждый PR и push в main

    4. ✅ Сборка проекта (npm run build)

    5. ✅ Preview deploy для PR

    6. ✅ Автодеплой в staging при мерже в develop

    7. ✅ Автодеплой в production при мерже в main

    8. ✅ Health check после деплоя

    9. ✅ Мониторинг ошибок (Sentry)

    10. ✅ Branch protection rules — CI обязателен для мержа

    Примеры

    Деплой в production только после успешного CI

    name: Deploy
    
    on:
      push:
        branches: [main]
    
    jobs:
      verify:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - run: npm ci
          - run: npm run lint
          - run: npm test
          - run: npm run build
    
      deploy:
        runs-on: ubuntu-latest
        needs: verify
        environment: production
        steps:
          - uses: actions/checkout@v4
          - name: Deploy script
            run: ./deploy.sh production

    Двухэтапный Dockerfile для frontend-приложения

    FROM node:20-alpine AS build
    WORKDIR /app
    COPY package*.json ./
    RUN npm ci
    COPY . .
    RUN npm run build
    
    FROM nginx:alpine
    COPY --from=build /app/dist /usr/share/nginx/html
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    📖

    Теоретический урок

    Изучи материал выше и задай вопросы AI если что-то непонятно

    Этот урок содержит теоретическую информацию. Изучи материал, затем отметь урок как пройденный.

    Загружаем AI-помощника...