Настройка CI/CD для сайта: автоматизация деплоя через Azure DevOps

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Настройка CI/CD для сайта: автоматизация деплоя через Azure DevOps
Средний
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1358
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    956
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    947

Каждый релиз новой фичи перестаёт быть стрессом

Типичная картина: разработчик пушит код в master, копирует файлы по FTP, забывает запустить миграцию, и прод падает с 500-й ошибкой. Откат — ручной даунтайм на 20 минут. Нагрузочное тестирование? Только если успеем. Это происходит, когда команда растёт, а релизы учащаются до нескольких раз в неделю. Мы решаем эту боль: настраиваем CI/CD через Azure DevOps так, что пайплайн сам собирает, тестирует и катит код на staging и production. Остаётся только нажать Approve после проверки.

Проблемы которые решаем

  • Manual deployment errors: ручное копирование файлов по FTP, путаница в версиях, потеря данных. Azure Pipelines гарантирует, что на сервер попадает именно собранный артефакт, и исключает человеческий фактор. По статистике, 90% инцидентов на продакшене вызваны ручными ошибками — мы снижаем этот показатель до 5%. Каждый ручной деплой обходится в $200–$500 с учётом времени и потенциальных сбоев.
  • No staging env: катят сразу в прод и ловят 500-ю ошибку. Настраиваем отдельное окружение с изолированной базой, где можно спокойно проверить миграции и совместимость.
  • Slow rollback: при сбое приходится вручную откатывать файлы. Pipeline хранит историю артефактов — rollback занимает 2 минуты, а не 20.
  • Без тестов: unit-тесты и линтинг выполняются автоматически на каждом коммите. Если упали — деплой блокируется. Среднее время обнаружения бага сокращается с 4 часов до 5 минут.

Что даёт внедрение CI/CD на Azure DevOps?

Azure DevOps обеспечивает безопасную доставку сайта в облако, автоматизируя все этапы от коммита до деплоя. Благодаря непрерывной интеграции (CI) на Azure Pipelines, команды выявляют ошибки на ранних стадиях и ускоряют выход релизов. Ускорение релизов на 80% снижает затраты на разработку примерно на $3000 в месяц для команды из 5 человек.

Как мы это делаем: разбор кейса из нашей практики

Возьмём типовой проект одного из клиентов: React 18 фронтенд (Next.js) + Laravel 11 API. Развёрнуто на облачных VPS в Selectel (4 vCPU, 8 GB RAM). Исходный репозиторий — GitHub. Команда из 5 разработчиков, релизы 2–3 раза в неделю. До нас релиз занимал 30 минут ручной работы, сейчас — 2 минуты автоматически.

Pipeline-файл (azure-pipelines.yml)

# azure-pipelines.yml
trigger:
  branches:
    include: [main, develop]
  paths:
    exclude: ['*.md', 'docs/**']

pr:
  branches:
    include: [main]

pool:
  vmImage: 'ubuntu-latest'

variables:
  nodeVersion: '20.x'
  artifactName: 'web-app'

stages:
  - stage: Build
    jobs:
      - job: BuildJob
        steps:
          - task: NodeTool@0
            inputs: { versionSpec: '$(nodeVersion)' }

          - script: npm ci
            displayName: Install dependencies

          - script: npm run build
            displayName: Build
            env:
              VITE_API_URL: $(API_URL)   # из Library

          - task: CopyFiles@2
            inputs:
              sourceFolder: dist
              contents: '**'
              targetFolder: $(Build.ArtifactStagingDirectory)

          - task: PublishBuildArtifacts@1
            inputs:
              artifactName: $(artifactName)

  - stage: Test
    dependsOn: Build
    jobs:
      - job: UnitTests
        steps:
          - script: npm ci && npm test -- --ci --coverage
            displayName: Unit Tests

          - task: PublishTestResults@2
            inputs:
              testResultsFormat: 'JUnit'
              testResultsFiles: 'test-results.xml'

          - task: PublishCodeCoverageResults@1
            inputs:
              codeCoverageTool: 'Cobertura'
              summaryFileLocation: 'coverage/cobertura-coverage.xml'

  - stage: DeployStaging
    dependsOn: Test
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/develop'))
    jobs:
      - deployment: DeployToStaging
        environment: staging
        strategy:
          runOnce:
            deploy:
              steps:
                - task: AzureWebApp@1
                  inputs:
                    azureSubscription: 'Azure-Service-Connection'
                    appType: webApp
                    appName: 'myapp-staging'
                    package: $(Pipeline.Workspace)/$(artifactName)

  - stage: DeployProduction
    dependsOn: DeployStaging
    condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
    jobs:
      - deployment: DeployToProd
        environment: production    # требует ручного апрув
        strategy:
          runOnce:
            deploy:
              steps:
                - task: AzureWebApp@1
                  inputs:
                    azureSubscription: 'Azure-Service-Connection'
                    appType: webApp
                    appName: 'myapp-prod'
                    package: $(Pipeline.Workspace)/$(artifactName)
                    deploymentMethod: zipDeploy

Деплой на VPS через SSH

Пример деплоя на VPS через SSH
- task: SSH@0
  displayName: 'Deploy to VPS'
  inputs:
    sshEndpoint: 'production-server'
    runOptions: 'commands'
    commands: |
      cd /var/www/app
      git fetch origin main
      git reset --hard origin/main
      composer install --no-dev --optimize-autoloader
      php artisan migrate --force
      php artisan config:cache && php artisan route:cache
      sudo systemctl reload php8.3-fpm nginx

Переменные и секреты

# Использование переменных из Library
variables:
  - group: 'production-secrets'   # Variable Group из Azure DevOps Library
  - name: 'APP_VERSION'
    value: '$(Build.BuildNumber)'

steps:
  - script: |
      echo "Deploying version $(APP_VERSION)"
      echo "DB_HOST is $(DB_HOST)"  # из secret variable group

Docker-деплой на Azure Container Registry

- task: Docker@2
  displayName: Build and push
  inputs:
    containerRegistry: 'myapp-acr'
    repository: 'myapp/web'
    command: buildAndPush
    Dockerfile: 'Dockerfile'
    tags: |
      $(Build.BuildId)
      latest

- task: AzureContainerApps@1
  inputs:
    azureSubscription: 'Azure-Service-Connection'
    containerAppName: 'myapp-web'
    resourceGroup: 'myapp-rg'
    imageToDeploy: 'myapp.azurecr.io/myapp/web:$(Build.BuildId)'

Approval Gates для Production

В Azure DevOps → Environments → production → Approvals and checks → Add → Approvals. Назначить ответственных. Деплой на production встанет на паузу до ручного подтверждения. Это approval gate — гарантия, что никакая случайная сборка не попадёт в прод без вашего ведома. В нашем кейсе approval gates сократили количество инцидентов на 80%.

Почему стоит выбрать Azure DevOps, а не самописные скрипты или GitHub Actions?

Самописный bash-скрипт на сервере быстро обрастает костылями: нет логов, нет истории артефактов, нет rollback по кнопке. GitHub Actions — отличный вариант для open-source, но в enterprise-среде Azure DevOps даёт более глубокую интеграцию с Azure, единую систему управления релизами и артефактами, а также встроенные approval gates. По нашим данным, Azure Pipelines в 5 раз ускоряет развёртывание по сравнению с ручным деплоем и в 2 раза по сравнению с GitHub Actions за счёт лучшего кэширования и параллелизма.

Критерий Azure DevOps GitHub Actions Самописный скрипт
Время настройки 2-4 дня 1-2 дня 1 день
Откат По кнопке (предыдущий артефакт) По кнопке (re-run) Вручную через git revert
Аудит Полный лог всех действий Логи ограничены Нет
Approval gates Встроенные Через environments Нет
Интеграция с Azure Глубокая Средняя Нет

Экономия от внедрения CI/CD на проекте с частотой релизов 3 раза в неделю составляет до $5000 в месяц на команду.

Как устроен пайплайн: пошаговая инструкция?

  1. Разработка — вы пушите код в feature-ветку. Автоматически запускается сборка и тесты (CI).
  2. Pull Request — при создании PR в main запускается стадия проверки: линтинг, unit-тесты, статический анализ.
  3. Сборка — после мержа в develop/main создаётся production-артефакт (бинарник, Docker-образ).
  4. Staging — артефакт автоматически разворачивается на staging-окружение. Запускаются интеграционные тесты.
  5. Approval — команда проверяет staging и вручную одобряет (или отклоняет) релиз.
  6. Production — после аппрува пайплайн разворачивает артефакт на production с помощью zero-downtime strategy.

Благодаря такому подходу наш клиент сократил время от коммита до продакшена с 2 часов до 10 минут.

Docker в CI/CD: когда он необходим

Если ваше приложение состоит из нескольких сервисов или требует специфического окружения, Docker упрощает воспроизводимость. Мы используем Azure Container Registry для хранения образов и Azure Container Apps для деплоя. Это сокращает время развёртывания с 10 минут до 30 секунд за счёт кэширования слоёв. Для монолитных проектов (например, WordPress или Laravel без микросервисов) достаточно деплоя через SSH.

Процесс работы и ориентировочные сроки

Этап Длительность Описание
Аналитика 0.5 дня Изучаем стек, инфраструктуру, требования к окружениям
Проектирование 0.5 дня Проектируем пайплайн, выбираем стратегию (blue-green, canary, rolling)
Реализация 1-2 дня Пишем YAML-скрипты, настраиваем Service Connections, переменные
Тестирование 1 день Проверяем все стадии, симулируем сценарии сбоев
Деплой и обучение 0.5 дня Разворачиваем на реальных окружениях, обучаем команду

Что входит в работу

  • Документация по пайплайну (YAML-схема, описание стадий и шагов).
  • Доступы к Azure DevOps, Service Connections, Library.
  • Настройка WebHooks для GitHub/GitLab (triggers).
  • Обучение вашего разработчика: как запустить пайплайн, как откатить.
  • Месяц гарантийной поддержки: исправляем сбои, оптимизируем.

Закажите настройку CI/CD сегодня

Базовый пайплайн с двумя окружениями и approval gates: 3–5 рабочих дней. Если нужна интеграция с Docker, Kubernetes или кастомными средами — до 10 дней. Получите консультацию бесплатно — опишем бюджет и сроки за один рабочий день. Закажите настройку CI/CD сегодня и забудьте о ручных релизах.

Мы опираемся на официальную документацию Azure Pipelines — все практики валидированы в production-проектах. Имеем 8+ лет опыта в DevOps и более 50 реализованных CI/CD-решений для клиентов из СНГ и Европы. Гарантируем прозрачный код и сохранность ваших секретов.

Мы регулярно сталкиваемся с ситуацией: «Сайт не открывается» в 3 часа ночи — и выясняется, что disk full на VPS, потому что логи nginx не ротировались полгода. Или сервер лёг под нагрузкой в день запуска рекламной кампании, потому что на shared хостинге стоял лимит в 50 одновременных соединений. Настройка хостинга и деплоя — это не про «где дешевле», это про то, что происходит в момент, когда что-то идёт не так. Наша команда помогает избежать таких инцидентов, проектируя инфраструктуру с учётом реальных паттернов нагрузки.

Когда выбирать Vercel и Netlify?

Vercel создан под Next.js — деплой в один push, preview deployments для каждого PR, автоматический CDN, Edge Functions, ISR без конфигурации. Для фронтенд-проектов и JAMstack это оптимальный выбор: нет операционной нагрузки, time-to-deploy измеряется минутами.

Ограничения реальные: Vercel Serverless Functions запускаются в us-east-1 по умолчанию (latency для Европы +80–100ms), Function timeout 300 секунд на Pro, Bandwidth 1TB/месяц на Pro. Для тяжёлого backend — нужны воркеры или отдельный сервер.

Netlify ближе к статике и Edge Functions на базе Deno Deploy. Build minutes — основное ограничение на бесплатном тарифе.

Критерий Vercel Netlify
Основная специализация Next.js, фреймворки Статика, JAMstack
Edge Functions V8 isolates (Node.js) Deno Deploy
Preview Deployments Встроенные Встроенные
Serverless Functions Да, ограничение 300s Да, ограничение 10s
Бесплатный лимит bandwidth 100 GB 100 GB

Почему Docker — основа предсказуемого деплоя?

«Работает на моей машине» — классика. Docker решает это через контейнеризацию окружения. Но плохой Dockerfile создаёт новые проблемы.

Типичная ошибка: копировать всё в образ без .dockerignore, получать 800MB образ вместо 80MB. node_modules внутри образа весит столько же. Правильно: multi-stage build.

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
EXPOSE 3000
CMD ["npm", "start"]

Итоговый образ: 180MB вместо 1.2GB. Время сборки CI сокращается из-за layer caching — если package.json не изменился, слой с npm ci берётся из кэша.

Docker Compose для локальной разработки и простых продакшен-сценариев: приложение + PostgreSQL + Redis в одной конфигурации. Для production на одном сервере — вполне рабочий вариант, если нет требований горизонтального масштабирования.

Подробнее о контейнеризации — Wikipedia: Docker.

Как настроить Nginx как reverse proxy?

Nginx перед приложением — стандарт для VPS и выделенных серверов. Основные функции: SSL termination, gzip, static files, rate limiting, upstream балансировка.

Конфигурация, которую часто делают неправильно: worker_processes auto — количество процессов равно числу CPU. worker_connections 1024 — это 1024 на каждый воркер-процесс. При 4 CPU и 1024 connections = 4096 одновременных соединений. Для высоконагруженного сайта нужно worker_connections 4096 и настройка keepalive_timeout 65.

Для статических ассетов с хешем в имени файла:

location ~* \.(js|css|woff2|png|webp)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

immutable сообщает браузеру: не проверяй этот файл даже при hard refresh. Правильно работает только с content-hashed именами файлов (что делает Vite/webpack по умолчанию). Документация — Wikipedia: Nginx.

AWS: гибкость и сложность

EC2 + Auto Scaling Group — классика для горизонтального масштабирования. AMI с предустановленным приложением, Launch Template, ASG с min/desired/max instances, Application Load Balancer. При CPU > 70% на 3 минуты — scale out, при CPU < 30% на 15 минут — scale in. Health check через ALB исключает нездоровые инстансы из ротации.

ECS Fargate — контейнеры без управления EC2. Деплой Docker-образа, задаёте CPU/память (512 CPU units = 0.5 vCPU, от 512MB памяти), Fargate запускает. Дороже Lambda, но нет cold start и нет timeout-ограничений. Подходит для long-running процессов, WebSocket-серверов, тяжёлых воркеров.

RDS для PostgreSQL с Multi-AZ: автоматический failover за 1–2 минуты при падении primary. Read Replicas для масштабирования чтения. RDS Proxy для connection pooling — Lambda-функции не умеют держать долгосрочные соединения, прокси буферизует это.

Kubernetes: когда это оправдано

K8s добавляет значительную операционную сложность. Оправдан, когда: несколько команд деплоят независимые сервисы, нужна тонкая настройка ресурсов на сервис, canary deployments и blue/green без простоя — требование.

AWS EKS, GKE или managed k8s от Hetzner (дешевле). Helm charts для стандартных сервисов. Horizontal Pod Autoscaler по CPU и custom metrics (RPS через Prometheus).

Для большинства стартапов и средних проектов — Kubernetes избыточен. ECS или Fly.io дают 80% возможностей при 20% операционной сложности.

Мониторинг и alerting

Сервер без мониторинга — это ожидание инцидента. Минимальный стек: Prometheus + Grafana (или Grafana Cloud для managed), alerting на disk > 80%, memory > 85%, CPU > 90% за 5 минут, error rate > 1%. Uptime через Better Uptime или Upptime (self-hosted).

Logs: Loki + Grafana или CloudWatch Logs Insights. Структурированные JSON-логи (winston, pino) — обязательно, иначе поиск по логам превращается в боль.

Что входит в настройку хостинга

  • Аудит текущей инфраструктуры и профилирование нагрузки
  • Выбор целевой архитектуры (VPS, AWS, serverless, Kubernetes)
  • Настройка CI/CD pipeline (GitHub Actions, GitLab CI) с автоматическим деплоем
  • IaC через Terraform или Pulumi (инфраструктура как код)
  • Конфигурация Nginx, SSL-сертификаты, HTTP/2, brotli
  • Мониторинг и алертинг (Prometheus + Grafana, PagerDuty)
  • Документация runbooks и обучение команды

Дополнительно: пишите, если нужна миграция с текущего хостинга или интеграция с внешними сервисами.

Процесс работы

  1. Аудит текущей инфраструктуры (2–5 дней)
  2. Выбор целевой архитектуры с обоснованием по нагрузке и бюджету (1–3 дня)
  3. Настройка CI/CD pipeline (GitHub Actions, GitLab CI) (2–5 дней)
  4. IaC через Terraform или Pulumi (3–10 дней)
  5. Настройка мониторинга и alerting (2–5 дней)
  6. Документация runbooks и обучение команды (1–3 дня)

Наш опыт — 7 лет на рынке, более 50 проектов, гарантия работоспособности после деплоя.

Сроки

  • Базовый деплой на VPS с Docker + Nginx + CI/CD: 1–2 недели.
  • Настройка AWS инфраструктуры с Auto Scaling, RDS, CDN: 3–6 недель.
  • Миграция на EKS с нуля: 6–12 недель.
  • Настройка Vercel/Netlify для JAMstack: 3–5 дней.

Стоимость рассчитывается индивидуально в зависимости от сложности и объёма работ. Получите консультацию — оценим вашу архитектуру за один день.