Skip to content

s1natex/Multi-Container-Application

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multi-Container-Application

A Docker Compose multi-container application

Project Pages:

Project Overview:

This project uses GitHub Actions to test → deploy → optionally destroy the infrastructure (manually via workflow_dispatch) It provisions a Python-based multi-container application using Docker and Docker Compose, consisting of a simple to-do list with a FastAPI backend and an HTML/CSS frontend Infrastructure is provisioned using Terraform on AWS and deployed through CI/CD pipelines.

Accessible services:

| Service      | Description                        | URL                                               |
| ------------ | -----------------------------------| ------------------------------------------------- |
| Frontend     | Static HTML+CSS via NGINX          | `http://<ec2-ip>:8080`                            |
| Backend API  | FastAPI proxied through NGINX      | `http://<ec2-ip>/`                                |
| API Direct   | FastAPI exposed on Blue/Green      | `http://<ec2-ip>:3001` (blue) or `:3002` (green)  |
| Health Check | FastAPI /health endpoint           | `http://<ec2-ip>:3001/health` or `:3002/health`   |
| Metrics      | FastAPI Prometheus endpoint        | `http://<ec2-ip>:3001/metrics` or `:3002/metrics` |
| -------------| -----------------------------------| --------------------------------------------------|
| Prometheus   | Monitoring system and data scraper | `http://<ec2-ip>:9090`                            |
| Grafana      | Dashboard UI (login: admin/admin)  | `http://<ec2-ip>:3003`                            |
| Node Exporter| System metrics exporter            | `http://<ec2-ip>:9100/metrics`                    |

GitHub Actions test.yml Workflow:

  • Workflow Trigger — Manually triggered by the user or optionally on repository changes
  • Runs the following jobs on Terraform and application code:
Terraform Jobs:
- Checkout Code
  Clones the repository to the runner

- Setup Terraform
  Installs Terraform CLI for command usage

- Terraform Init
  Initializes configuration, backends, and providers

- Terraform Format Check
  Enforces standard Terraform file formatting using terraform fmt -check

- Terraform Validate
  Verifies Terraform syntax and logical correctness
Python Unit Tests:
- Checkout Code
  Fetches the complete repo

- Set up Python
  Installs Python 3.10

- Install Dependencies
  Installs required packages via pip

- Force Correct httpx Version
  Ensures FastAPI test compatibility

- Run Unit Tests
  Executes pytest on backend test file (cd app/backend; pytest unit_tests.py)
Docker Compose Integration:
- Checkout Code
  Loads the repository into the runner environment

- Install Docker & Compose
  Ensures container tooling is available

- Run Docker Compose
  Starts the full application stack

- Test API Endpoint
  Confirms backend availability using curl on /todos

- Test Frontend
  Verifies HTML response from nginx on port 8080

- Clean up
  Shuts down containers using docker-compose down

GitHub Actions deploy.yml Workflow:

  • Workflow Trigger — Runs automatically after test.yml succeeds (workflow_run), or manually via workflow_dispatch
Job Initialization:
- Sets Terraform variable: TF_VAR_key_name
- Uses AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from repository secrets
  • Checkout Code — Clones the repo into the runner
  • Setup Terraform — Uses terraform_wrapper: false to enable direct output access
  • Create Backend Infrastructure — S3 bucket and DynamoDB table for state management
  • Terraform Init — Initializes the backend and modules
  • Terraform Apply — Provisions infrastructure
  • Save SSH Key — Extracts and secures generated EC2 SSH key (docker-key.pem)
  • Wait for EC2 Instance — Ensures instance is ready before SSH
  • Extract EC2 Public IP — Captures IP address from Terraform output for later use
IP=$(terraform -chdir=terraform output -raw public_ip | tr -d '
' | xargs)
echo "PUBLIC_IP=${IP}" >> $GITHUB_ENV
  • Deploy Application with Blue-Green Strategy:

    • Detects currently active API container (blue or green)
    • Spins up the inactive version (docker-compose.blue.yml or green.yml)
    • Waits for the container to respond on /health
    • Updates NGINX configuration to switch traffic
    • Removes the previously active version
  • Start Monitoring Stack — Prometheus, Grafana, and Node Exporter are launched with the app

  • Clean Up — Removes private SSH key from runner after deployment

GitHub Actions destroy.yml Workflow:

  • Destroys all provisioned resources, cleaning up Terraform-managed infrastructure using the remote backend

Monitoring Integration:

  • Prometheus scrapes system and application metrics:

    • System metrics via Node Exporter
    • App metrics via FastAPI /metrics using prometheus_fastapi_instrumentator
  • Grafana dashboards configured to visualize:

    • Request rates
    • Latency distributions
    • Error counts
    • CPU, memory, and disk usage from Node Exporter

Usage Instructions:

  • Trigger deployment with:
test.yml  # if all checks pass, triggers deploy.yml automatically
  • /health is used for internal deployment checks to ensure the active container is healthy before traffic is switched

  • To destroy the infrastructure manually:

Run destroy.yml

How to Run the Entire Project:

  1. Clone the repository
  2. Set GitHub Secrets for AWS access (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  3. Trigger test.yml manually via GitHub Actions UI or push changes
  4. Once tests pass, deploy.yml runs automatically to:
    • Create AWS infrastructure
    • SSH into the EC2 instance
    • Deploy the blue or green container
    • Set up Prometheus and Grafana monitoring
    • Route traffic with NGINX
  5. Access your app via public EC2 IP and monitor performance using Grafana

About

A Docker Compose multi-container application

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published