This project demonstrates a complete CI/CD pipeline implementation for a Python Django web application using GitHub Actions, Docker, and Kubernetes deployment with Helm charts. The main focus is on showcasing modern DevOps practices and automated deployment workflows.
This repository serves as a demonstration of CI/CD best practices featuring:
- GitHub Actions workflows for automated testing and deployment
- Multi-matrix CI builds across different Python versions and operating systems
- Docker containerization and automated image building
- Helm chart packaging and deployment automation
- Kubernetes deployment with proper environment management
- Artifact management and workflow orchestration
A Django todo list application that includes:
- User authentication system (
accountsapp) - Todo list management with CRUD operations (
listsapp) - REST API endpoints (
apiapp) - Static file management and responsive UI
- Database integration with migration support
- Python 3.8/3.9 - Application runtime with multi-version support
- Django 4.x - Web framework
- Django REST Framework - API development
- MySQL - Database (deployed via Helm sub-chart)
- GitHub Actions - CI/CD automation
- Docker - Application containerization
- Helm 3.x - Kubernetes package management
- Kubernetes - Container orchestration
- Kind - Local Kubernetes development
- Coverage.py - Code coverage reporting
- Flake8 - Code linting and style checking
- Django Test Framework - Unit and integration testing
strategy:
matrix:
PythonVersion: [ 3.8, 3.9 ]
OsTypes: [ ubuntu-latest, windows-latest ]- Cross-platform testing on Ubuntu and Windows
- Multi-version Python support (3.8, 3.9)
- Automated dependency installation and testing
- Code coverage reporting with coverage.py
- Code quality checks with flake8 linting
- Complexity analysis for maintainable code
- Conditional execution (only on main branch)
- Artifact-based deployment using matrix job outputs
- Docker Hub integration with secure credential management
- Tagged releases using commit SHA
- Helm chart validation with linting
- Template verification and testing
- Chart packaging for deployment
- Artifact publishing for deployment workflows
- Development environment - Automatic deployment
- Staging environment - Promotion-based deployment
- Reusable deployment workflows for consistency
- Concurrency control - Prevents conflicting deployments
- Manual workflow dispatch - On-demand deployments with environment selection
- Artifact management - Efficient build artifact sharing between jobs
- Environment-specific configurations - Separate values for different stages
├── .github/workflows/
│ ├── main.yml # Main CI/CD pipeline
│ └── reusable-deployment.yml # Reusable deployment workflow
├── src/ # Django application source
│ ├── Dockerfile # Application containerization
│ ├── requirements.txt # Python dependencies
│ ├── manage.py # Django management script
│ ├── accounts/ # User authentication app
│ ├── api/ # REST API endpoints
│ ├── lists/ # Todo list management
│ └── todolist/ # Django project settings
├── helm-charts/todoapp/ # Helm chart for Kubernetes
│ ├── Chart.yaml # Chart metadata
│ ├── values.yaml # Default configuration
│ ├── charts/mysql/ # MySQL sub-chart
│ ├── templates/ # Kubernetes manifests
│ └── values/stg.yaml # Staging environment config
├── cluster.yml # Kind cluster configuration
└── bootstrap.sh # Local deployment script
- Git - Version control
- Python 3.8+ - Local development
- Docker - Container runtime
- Kind - Local Kubernetes (optional)
- Helm 3.x - Chart management (optional)
- kubectl - Kubernetes CLI (optional)
-
Clone the repository
git clone https://github.com/zave52/cicd-python-app.git cd cicd-python-app -
Set up Python environment
# Create virtual environment python -m venv venv # Activate virtual environment # On Windows: venv\Scripts\activate # On Unix/macOS: source venv/bin/activate # Install dependencies cd src pip install -r requirements.txt
-
Run the application locally
# Apply database migrations python manage.py migrate # Create superuser (optional) python manage.py createsuperuser # Run development server python manage.py runserver
-
Access the application
- Web Interface: http://localhost:8000
- Admin Panel: http://localhost:8000/admin
- API Endpoints: http://localhost:8000/api/
# Run tests
python manage.py test
# Generate coverage report
coverage run --source='.' manage.py test
coverage report
# Run linting
flake8 . --show-source --statistics
# Check code complexity
flake8 . --max-complexity=6# Build Docker image
cd src
docker build -t todoapp:local .
# Run container
docker run -p 8000:8000 todoapp:local# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose down-
Create local cluster
kind create cluster --config cluster.yml
-
Deploy using bootstrap script
chmod +x bootstrap.sh ./bootstrap.sh
-
Access the application
kubectl port-forward svc/todoapp-service 8080:80 -n todoapp # Open http://localhost:8080
# Install dependencies
helm dependency update helm-charts/todoapp
# Deploy to development
helm install todoapp-dev helm-charts/todoapp
# Deploy to staging
helm install todoapp-staging helm-charts/todoapp -f helm-charts/todoapp/values/stg.yaml
# Upgrade deployment
helm upgrade todoapp-dev helm-charts/todoappThis project uses GitHub Environments for deployment management. You need to create two environments in your GitHub repository:
- development - For development deployments
- staging - For staging deployments
To create environments:
- Go to your GitHub repository
- Navigate to Settings → Environments
- Click New environment
- Create both
developmentandstagingenvironments
Set up the following secrets at the repository level:
DOCKERHUB_USERNAME # Docker Hub username
DOCKERHUB_TOKEN # Docker Hub access tokenConfigure the following secrets for BOTH environments (development and staging):
# Database Configuration
MYSQL_ROOT_PASSWORD # MySQL root password
MYSQL_USER # MySQL database user
MYSQL_PASSWORD # MySQL user password
# Application Configuration
APP_SECRET_KEY # Django secret key
APP_DB_NAME # Database name for the application
APP_DB_HOST # Database host (usually mysql-service for K8s)Example values for development environment:
MYSQL_ROOT_PASSWORD=rootpassword123
MYSQL_USER=todoapp_user
MYSQL_PASSWORD=userpassword123
APP_SECRET_KEY=your-super-secret-django-key-here
APP_DB_NAME=todoapp_db
APP_DB_HOST=mysql-0.mysql.mysql.svc.cluster.localNote: Use different, more secure values for the staging environment.
- Push to main - Full CI/CD pipeline execution
- Pull requests - CI testing only
- Manual dispatch - On-demand deployment with environment selection
env:
DockerImageName: todoapp # Docker image name for buildsstrategy:
matrix:
PythonVersion: [ 3.8, 3.9 ]
OsTypes: [ ubuntu-latest, windows-latest ]if: ${{ github.ref_name == 'main' }}- name: Upload python artifacts
uses: actions/upload-artifact@v4
with:
name: python-artifacts-${{ matrix.OsTypes }}-${{ matrix.PythonVersion }}
path: .uses: ./.github/workflows/reusable-deployment.yml
secrets: inherit
with:
environment: staging
version: ${{ github.sha }}with:
environment: staging
helm-values-path: ./todoapp/values/stg.yaml
helm-release-name: todoapp-stagingThe application includes health check endpoints for Kubernetes probes:
- Health Check:
/api/health/ - Readiness Check:
/api/ready/
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and ensure tests pass
- Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
-
Docker build failures
- Ensure all dependencies are in
requirements.txt - Check Dockerfile syntax and paths
- Ensure all dependencies are in
-
Test failures in CI
- Run tests locally first:
python manage.py test - Check for environment-specific issues
- Run tests locally first:
-
Helm deployment issues
- Validate charts:
helm lint helm-charts/todoapp - Check Kubernetes cluster status:
kubectl get nodes
- Validate charts:
-
GitHub Actions failures
- Check secret configuration
- Verify artifact dependencies between jobs
This project is licensed under the MIT License - see the LICENSE file for details.