Ответ
В последнем production-проекте мы использовали CI/CD пайплайн на GitHub Actions с Docker. Целью была полная автоматизация от пуша кода в main до обновления сервиса на сервере.
Основные этапы пайплайна (.github/workflows/deploy.yml):
-
Тестирование и сборка:
jobs: test-and-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - run: npm run lint # ESLint - run: npm test # Jest - run: npm run build # Если есть сборка (TypeScript, etc.) -
Сборка и публикация Docker-образа:
build-and-push: needs: test-and-build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build Docker image run: docker build -t ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }} . - name: Push to Docker Hub run: | echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin docker push ${{ secrets.DOCKER_USERNAME }}/my-app:${{ github.sha }} -
Деплой на продакшен-сервер:
deploy: needs: build-and-push runs-on: ubuntu-latest steps: - name: Deploy via SSH uses: appleboy/ssh-action@v1 with: host: ${{ secrets.SSH_HOST }} username: ${{ secrets.SSH_USER }} key: ${{ secrets.SSH_PRIVATE_KEY }} script: | cd /opt/my-app docker-compose pull docker-compose up -d --remove-orphans docker image prune -f
Инфраструктура на сервере:
- Приложение и зависимости (PostgreSQL, Redis) описаны в
docker-compose.prod.yml. - Nginx как reverse proxy и для раздачи статики.
- PM2 или аналогичный процесс-менеджер не требуется, так как контейнером управляет Docker.
- Для staging-окружения использовался аналогичный пайплайн, но с триггером на пуши в ветку
developи деплоем на отдельный сервер.