Archive of

CI/CD Pipeline: anime-backlog-web

Written by skeirss

CI/CD Pipeline: anime-backlog-web

About the Project

anime-backlog-web is a custom-built application for tracking anime, consisting of separate Docker containers:

  • Backend — Python
  • Frontend — Node.js / Next.js
  • Database — PostgreSQL

1. Infrastructure Preparation

Terraform

Terraform is used to provision a virtual machine in Yandex Cloud. The main configuration file requests the following resources:

  • 1 boot disk
  • 1 virtual network
  • 1 subnet
  • 1 virtual machine with minimal specifications
  • attachment of the disk and network to the VM

cloud-terraform/main.tf

Cloud-init

Initial VM configuration (bootstrap), executed once on first boot:

  • user creation
  • SSH key addition

cloud-terraform/cloud-init.yml

Ansible

More detailed configuration of the cloud VM instance:

  • installation and configuration of Docker
  • firewall setup
  • installation of fail2ban
  • hardening of sshd security

After the Terraform → Cloud-init → Ansible sequence, the virtual machine is fully prepared for application deployment.

ansible/harden.yml


2. Pipeline Trigger

A git push to the remote repository on GitHub causes GitHub to send a webhook to: https://jenkins.bernd32.xyz/github-webhook/

Access security:

Resource Access
https://jenkins.bernd32.xyz (Jenkins itself) restricted to IP addresses allowed in the nginx configuration
.../github-webhook/ (webhook endpoint) open to all IP addresses, protected by HMAC signature of the payload

Jenkins clones the repository and reads the declarative pipeline from jenkins/Jenkinsfile.


3. Quality Gates

Frontend and backend tests are executed in parallel, each within its own Docker container.

Backend

  • Container: python:3.14-slim-bookworm
  • Creation of a virtual environment (venv)
  • Installation of dependencies
  • Execution of pytest with JUnit report generation
  • post.always → publication of test results

Frontend

  • Container: node:22-bookworm-slim
  • npm ci
  • typecheck
  • npm test (Vitest, JUnit report)
  • npm run build
  • post.always → publication of test results

4. Image Build and Publication

Docker images are built and pushed to the registry (Docker Hub) tagged with the git-sha.

This approach provides:

  • reproducibility (ability to roll back to a specific tag)
  • complete image history

5. Security Scanning

Scans are performed in non-blocking mode — they do not cause the build to fail but generate reports in the Jenkins dashboard.

Tool Scope
pip-audit Python dependencies of the backend
npm audit JS/TS dependencies of the frontend
Trivy The complete built Docker image (immediately after the build)

6. Deployment

On the remote virtual machine, with a secret .env file mounted via withCredentials (the file is not committed to the repository), the following command is executed:

docker compose up -d --remove-orphans --wait

using the newly built images.

Unused images are removed after successful pipeline completion:

docker image prune -f

The application is accessible and ready to use at:

http://cloud-ip:20773

7. Monitoring

A Grafana dashboard is configured on the local server to monitor the local server hosting the "production" version of the application.

The Prometheus + cAdvisor/node-exporter stack tracks:

  • overall server status (CPU / RAM / disk I/O)
  • Docker containers statuses (filesystem usage, CPU, network, and memory per container)

8. Rollback Strategy

A dedicated pipeline is implemented for rollback: jenkins/rollback/Jenkinsfile.

Procedure:

  1. Locate the last successful build of the required version in Jenkins
  2. In the console output, find the line Building commit XXXXXXXX (the commit hash corresponds to the image tag on Docker Hub)
  3. Navigate to the anime-backlog-rollback job in Jenkins
  4. Select Build with Parameters
  5. Paste the required commit hash into the ROLLBACK_SHA field
  6. Start the build — the production version will be restored on the deployment server

8. Flowchart

flowchart

CI/CD Pipeline: anime-backlog-web (in Russian)

Written by skeirss

CI/CD Pipeline: anime-backlog-web

О проекте

anime-backlog-web — самописное приложение для отслеживания аниме-тайтлов, состоящее из отдельных Docker-контейнеров:

  • Backend — Python
  • Frontend — Node.js / Next.js
  • База данных — PostgreSQL

1. Подготовка инфраструктуры

Terraform

С помощью Terraform создаётся виртуальная машина в Yandex Cloud. В главном конфигурационном файле запрашиваются:

  • 1 загрузочный диск
  • 1 виртуальная сеть
  • 1 подсеть
  • 1 виртуальная машина с минимальными характеристиками
  • подключение диска и сети к ВМ

cloud-terraform/main.tf

Cloud-init

Первоначальная настройка ВМ (bootstrap), выполняется один раз при первом запуске:

  • добавление пользователя
  • добавление SSH-ключа

cloud-terraform/cloud-init.yml

Ansible

Более детальная конфигурация облачной машины:

  • установка и настройка Docker
  • настройка firewall
  • установка fail2ban
  • усиление безопасности sshd

После связки Terraform → Cloud-init → Ansible виртуальная машина полностью готова к деплою приложения.

ansible/harden.yml


2. Запуск pipeline

git push в удалённый репозиторий на GitHub → GitHub отправляет webhook на:

https://jenkins.bernd32.xyz/github-webhook/

Безопасность доступа:

Ресурс Доступ
https://jenkins.bernd32.xyz (сам Jenkins) только для IP, разрешённых в конфигурации nginx
.../github-webhook/ (endpoint для вебхуков) открыт для всех IP, защищён HMAC-подписью payload

Jenkins клонирует репозиторий и считывает декларативный pipeline из jenkins/Jenkinsfile.


3. Quality Gates

Тесты фронтенда и бэкенда запускаются параллельно, каждый в своём Docker-контейнере.

Backend

  • Контейнер: python:3.14-slim-bookworm
  • Создание venv
  • Установка зависимостей
  • Запуск pytest с JUnit-отчётом
  • post.always → публикация результатов тестов

Frontend

  • Контейнер: node:22-bookworm-slim
  • npm ci
  • typecheck
  • npm test (Vitest, JUnit-отчёт)
  • npm run build
  • post.always → публикация результатов тестов

4. Сборка и публикация образов

Docker-образы собираются и выгружаются в registry (Docker Hub) с тегом git-sha.

Это даёт:

  • воспроизводимость (откат на конкретный тег)
  • полную историю образов

5. Проверка безопасности

Проверки выполняются в non-blocking режиме — не приводят к падению сборки, а формируют отчёты в панели Jenkins.

Инструмент Что сканирует
pip-audit Python-зависимости бэкенда
npm audit JS/TS-зависимости фронтенда
Trivy Собранный Docker-образ целиком (сразу после сборки)

6. Деплой

На удалённом хосте ВМ, с подключённым через withCredentials секретным .env-файлом (не коммитится в репозиторий), выполняется:

docker compose up -d --remove-orphans --wait

с только что собранными образами.

После успешного завершения pipeline:

docker image prune -f

Приложение доступно по адресу:

http://cloud-ip:20773

7. Мониторинг

В Grafana на локальном сервере настроен дашборд для мониторинга локального сервера с "production"-версией приложения.

Стек Prometheus + cAdvisor/node-exporter отслеживает:

  • общее состояние сервера (CPU / RAM / disk I/O)
  • состояние Docker-контейнеров (использование FS, CPU, сети, памяти по каждому контейнеру)

8. Rollback-стратегия

Для отката реализован отдельный pipeline: jenkins/rollback/Jenkinsfile.

Порядок действий:

  1. Найти последний успешный билд нужной версии
  2. В console output найти строку Building commit XXXXXXXX (хеш коммита = тег образа на Docker Hub)
  3. Перейти в job anime-backlog-rollback в Jenkins
  4. Выбрать Build with Parameters
  5. В поле ROLLBACK_SHA вставить нужный хеш коммита
  6. Запустить билд — версия на проде будет восстановлена

9. Flowchart

flowchart