Task Manager CI/CD Pipelines
Two GitLab CI pipelines powering a full-stack task management application — a Python backend and a Node.js frontend — each with automated testing, container security scanning, and multi-environment deployment.
Two GitLab CI pipelines — one for a Python backend, one for a Node.js frontend — that automate the full delivery lifecycle of a task management application: from linting and testing to container scanning and zero-downtime deployment across two environments.
What it does
The backend pipeline runs three stages. The validation stage installs dependencies via uv, lints with Ruff, runs pytest with coverage, and submits results to a self-hosted Sonarqube server with a blocking quality gate — the pipeline fails if code quality thresholds are not met. The package stage builds a Docker image using BuildKit with registry-based layer caching, then scans it with Trivy and rejects any image containing HIGH or CRITICAL CVEs. The deploy stage pushes the image and deploys it to the target environment over SSH using Docker Compose. The frontend pipeline runs two stages. The package stage installs Node.js dependencies with npm ci, produces a production build, then follows the same Docker build and Trivy scan flow as the backend. The deploy stage is identical in structure to the backend, using YAML anchors to avoid duplication. Both pipelines share the same deployment strategy: automatic deployment to staging on every push to the default branch, and manual-approval deployment to production on git tags.
Tech Stack
- CI platform: GitLab CI/CD
- Backend: Python 3.12, uv, Ruff, pytest + coverage
- Frontend: Node.js, npm
- Containerisation: Docker 29.3, BuildKit (docker-container driver), registry-based build cache
- Security scanning: Trivy — exits with code 1 on HIGH or CRITICAL CVEs
- Code quality: Self-hosted Sonarqube (backend) — blocking quality gate, coverage reporting, project versioning tied to git tag or commit SHA
- Deployment: SSH + Docker Compose, envsubst for environment-specific compose files, strict host key verification via ssh-keyscan
- Secrets management: GitLab CI variables — SSH private key stored base64-encoded, cleaned up in after_script
Impact
- Shift-left security: every image is scanned before it can reach any environment, blocking vulnerable builds at the source rather than at runtime
- Consistent environments: Docker Compose with templated configuration (compose.tpl.yml) ensures staging and production are deployed identically, reducing environment-specific bugs
- Fast feedback: Sonarqube’s blocking quality gate prevents regressions in code quality from ever reaching the main branch
- Safe production releases: git-tag-triggered, manual-approval deployments make every production release an explicit, traceable decision
- Efficient builds: BuildKit registry cache (mode=max) significantly reduces image build times on repeated runs by reusing intermediate layers across pipeline executions