DEV Community

Miracle Olorunsola
Miracle Olorunsola

Posted on

How I Took a Broken Microservices App to Production with Docker & CI/CD

The Challenge

I was given a multi-service application with:

A Node.js frontend
A FastAPI backend
A Python worker
Redis as a queue

The catch?

It was intentionally broken.

My task wasn’t to build it was to:

  • Fix it
  • Containerize it
  • Ship it with a full CI/CD pipeline

Step 1: Debugging the System
Before touching Docker, I read the entire codebase.

Issues I found:
Hardcoded localhost breaking container networking
Missing environment variables
Redis connection failures
API crashing on startup
Frontend calling wrong endpoints

Fix approach:

Replaced hardcoded values with env variables
Standardized service communication (api, redis)
Added proper error handling

Step 2: Containerization

Each service got its own Dockerfile.

Key decisions:

  • Used python:3.11-alpine for minimal size
  • Created non-root users (appuser)
  • Added HEALTHCHECK to every service
  • Avoided copying .env files into images

Step 3: Docker Compose Setup

This was where things got interesting.

What I implemented:

  • Internal bridge network
  • Redis hidden from host
  • depends_on with health conditions
  • Resource limits for all containers
depends_on:
  redis:
    condition: service_healthy
Enter fullscreen mode Exit fullscreen mode

Step 4: CI/CD Pipeline

I built a GitHub Actions pipeline with strict stages:

- Lint
flake8 (Python)
eslint (Node)
hadolint (Docker)
Test
pytest with mocked Redis
coverage report upload
Enter fullscreen mode Exit fullscreen mode
- Build
Tagged images with SHA + latest
Pushed to local registry
Enter fullscreen mode Exit fullscreen mode
- Security Scan
Trivy scan
Fail on CRITICAL vulnerabilities
Enter fullscreen mode Exit fullscreen mode
- Integration Test
Spin up full stack
Submit job → poll → verify completion
Enter fullscreen mode Exit fullscreen mode
- Deploy
Rolling update
Health check gating
Automatic rollback on failure
Enter fullscreen mode Exit fullscreen mode

Challenges I Faced

  • Docker daemon not running (blocked everything)
  • ESLint breaking due to Node version mismatch
  • Trivy failing due to missing images
  • Race conditions between services
  • Containers “starting” but not “ready”

Key Takeaways

  • Health checks > startup order
  • Containers must be self-sufficient
  • CI/CD pipelines should fail fast DevOps is about system thinking, not just tools

Repo

Top comments (0)