Sokoni (Swahili for "marketplace") is a production-ready Django eβcommerce application demonstrating a complete DevOps lifecycle: containerization, CI/CD automation, Infrastructure as Code, monitoring & observability, and comprehensive DevSecOps practices.
This project serves as the practical capstone for my 12-week Starter DevOps Program at the Nairobi DevOps Community, showcasing the transition from learning to hands-on application of industry-standard DevOps tools and practices.
- Project Overview
- Architecture Diagram
- Tech Stack
- Repository Structure
- Local Development
- Configuration (Environment Variables)
- CI/CD Pipeline
- Containerization & Docker Registry
- Infrastructure as Code (Terraform)
- Monitoring & Observability
- DevSecOps
- Live Demo
- Deliverables Checklist
- Contributing
- Acknowledgments
- License
Features:
- User authentication & authorization
- Product catalog with categories, tags, and search
- Shopping cart with session management
- Coupon & discount system
- Order processing & tracking
- Payment integration (Paystack)
- Wishlist functionality
- Admin dashboard for inventory management
DevOps Highlights:
- Multi-stage Docker builds with security best practices
- GitHub Actions CI/CD with automated testing, security scanning, and deployment
- Terraform-managed AWS infrastructure (ECS Fargate, RDS, ALB, VPC)
- AWS Managed Prometheus + Grafana for monitoring
- Comprehensive security scanning (Trivy, CodeQL, SonarQube, OWASP ZAP)
- Secret management via AWS Secrets Manager & SSM Parameter Store
Disclaimer: This setup is designed to be as budget-friendly as possible without compromising on security.
| Layer | Technology |
|---|---|
| Backend | Django 5.2, Python 3.12, Gunicorn |
| Database | PostgreSQL (RDS in production) |
| Containerization | Docker (multi-stage builds), Docker Compose |
| Orchestration | AWS ECS Fargate |
| Infrastructure | Terraform (Terraform Cloud workflow) |
| CI/CD | GitHub Actions |
| Monitoring | django-prometheus, AWS Managed Prometheus, AWS OTel Collector, Grafana |
| Security Scanning | Trivy, CodeQL, SonarQube, OWASP ZAP, detect-secrets, GitLeaks |
| Secret Management | AWS Secrets Manager, SSM Parameter Store, detect-secrets |
| Load Balancing | AWS Application Load Balancer (ALB) |
| Logging | CloudWatch Logs |
| Payments | Paystack API |
sokoni/
βββ .github/
β βββ workflows/ # GitHub Actions CI/CD pipelines
β β βββ pipeline.yml # Main deployment pipeline
β β βββ sast.yml # Static Application Security Testing
β β βββ dast.yml # Dynamic Application Security Testing
β β βββ trivy.yml # Container vulnerability scanning
β β βββ lint.yml # Code linting
β β βββ branch-rules.yml # Branch protection enforcement
β βββ infra/ # Terraform Infrastructure as Code
β βββ prod/ # Production environment
β βββ staging/ # Staging environment
βββ accounts/ # User authentication app
βββ cart/ # Shopping cart app
βββ coupons/ # Discount coupons app
βββ docs/ # Additional documentation
βββ orders/ # Order processing app
βββ payments/ # Payment integration app
βββ products/ # Product catalog app
βββ sokoni/ # Django project settings
βββ static/ # Static assets
βββ templates/ # Django templates
βββ wishlist/ # Wishlist app
βββ .dockerignore
βββ .env.example
βββ .gitignore
βββ .pre-commit-config.yaml # Linting config file
βββ .secrets.baseline # Baseline for secret detection
βββ compose.yaml # Docker Compose for local dev
βββ Dockerfile # Multi-stage production image
βββ entrypoint.sh # Container entrypoint script
βββ LICENSE
βββ manage.py
βββ README.md
βββ requirements.txt # Python dependencies
βββ sonar-project.properties # SonarQube config file
Prerequisites:
- Python 3.12+
- PostgreSQL 14+
Setup:
# 1. Clone the repository
git clone https://github.com/victorgpt0/sokoni.git
cd sokoni
# 2. Create and activate virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Configure environment variables
cp .env.example .env
# Edit .env with your database credentials and API keys
# 5. Run database migrations
python manage.py migrate
# 6. Create superuser
python manage.py createsuperuser
# 7. (Optional) Seed database with sample data
python manage.py seed_dev # Full dataset
python manage.py seed_dev --small # Smaller dataset
# 8. Run tests
python manage.py test
# 9. Start development server
python manage.py runserverAccess:
- Main site: http://localhost:8000
- Admin panel: http://localhost:8000/admin
- Metrics endpoint: http://localhost:8000/metrics
Prerequisites:
- Docker 20.10+
- Docker Compose 2.0+
Setup:
# 1. Clone the repository
git clone https://github.com/victorgpt0/sokoni.git
cd sokoni
# 2. Configure environment
cp .env.example .env
# Edit .env with your configuration
# 3. Start services
docker compose up --build
# 4. Run migrations (first time only)
docker compose exec server python manage.py migrate
# 5. Create superuser (first time only)
docker compose exec server python manage.py createsuperuser
# 6. (Optional) Seed database
docker compose exec server python manage.py seed_devAccess:
- Application: http://localhost:8000
Note: To enable multi-service setup with PostgreSQL, uncomment the database service in compose.yaml.
Create a .env file based on .env.example:
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/sokoni # pragma: allowlist secret
# Django Security
SECRET_KEY=your-secret-key-here
DEBUG=True
ALLOWED_HOSTS=localhost,127.0.0.1
CSRF_TRUSTED_ORIGINS=http://localhost:8000
# Email Configuration
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
[email protected]
EMAIL_HOST_PASSWORD=your-app-password
# Paystack Payment Gateway
PAYSTACK_PUBLIC_KEY=pk_xxxxxx
PAYSTACK_SECRET_KEY=sk_xxxxxxProduction (AWS):
DATABASE_URLis stored in SSM Parameter Store (/sokoni/{env}/database_url)- Grafana admin password is stored in AWS Secrets Manager
- All secrets are injected into ECS tasks via IAM roles
| Workflow | Trigger | Purpose |
|---|---|---|
| pipeline.yml | Push to main, staging |
Run Django Tests, Build, Scan and Push Docker Image to AWS ECR, Terraform Cloud deployment |
| sast.yml | Push/PR to main, staging; Weekly schedule |
CodeQL, SonarQube, GitLeaks scanning |
| dast.yml | Push/PR to main, staging; Weekly schedule |
OWASP ZAP dynamic security testing |
| trivy.yml | Weekly schedule | Docker image vulnerability scanning |
| lint.yml | PRs to main, staging |
Code formatting & linting checks |
| branch-rules.yml | PRs to main |
Enforce PRs from staging only |
graph LR
A[Code Push] --> B[Run Tests]
B --> C[Build Docker Image]
C --> D[Trivy Scan]
D --> E[Push to Registry]
E --> F[Update TF Variable]
F --> G[Terraform Plan]
G --> H[Terraform Apply]
H --> I[Deploy to ECS]
Required GitHub Secrets:
TF_API_TOKENβ Terraform Cloud API tokenSONAR_ORGβ SonarQube organization nameSONAR_TOKENβ SonarQube authenticationSONAR_PROJECT_KEYβ SonarQube Project KeyTEST_DB_URLβ Test database connection stringAWS_ECR_ROLE_ARNβ IAM role for ECR accessAWS_TF_ROLE_ARNβ IAM role for TF accessTF_MAIN_IMAGE_VAR_IDβ Terraform Cloud Production Docker Image Variable IDTF_MAIN_WORKSPACE_IDβ Terraform Cloud Production Workspace IDTF_STAGING_IMAGE_VAR_IDβ Terraform Cloud Staging Docker Image Variable IDTF_STAGING_WORKSPACE_IDβ Terraform Cloud Staging Workspace ID
- Multi-stage build for optimized image size
- Non-root user (
appuser) for security - Health checks on port 8000
- Gunicorn WSGI server with 4 workers
- Static file collection via
entrypoint.sh
# Build locally
docker build -t victorgpt0/sokoni:latest .
# Run locally
docker run -p 8000:8000 --env-file .env victorgpt0/sokoni:latest
# Push to DockerHub
docker login
docker push victorgpt0/sokoni:latest
# Or push to AWS ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker tag victorgpt0/sokoni:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/sokoni:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/sokoni:latestInfrastructure is defined in .github/infra/ with separate environments for staging and production.
- Organization:
victorgpt0 - Workspaces:
sokoni-production(main branch)sokoni-staging(staging branch)
- Execution: Remote execution via Terraform Cloud
- State: Managed remotely in Terraform Cloud
Networking:
- VPC with public and private subnets across 2 AZs
- Internet Gateway
- Security Groups for ALB, ECS, RDS, Grafana
Compute:
- ECS Fargate cluster
- ECS service for Django app (with auto-scaling capability)
- Application Load Balancer (ALB) with HTTPS support
Database:
- RDS PostgreSQL instance (Multi-AZ optional)
- Automated backups
Monitoring:
- AWS Managed Prometheus (AMP) workspace
- AWS OTel Collector sidecar for metrics collection
- Grafana on ECS with IAM permissions to query AMP
Secrets & Configuration:
- SSM Parameter Store for
DATABASE_URL - Secrets Manager for Grafana admin password
- IAM roles with least-privilege policies
Logging:
- CloudWatch Log Groups for ECS tasks
Key variable in variables.tf:
container_imageβ Docker image URI (set via Terraform Cloud workspace variable)
# Local apply (requires AWS credentials)
cd .github/infra/prod
terraform init
terraform plan -var="container_image=<your-image-uri>"
terraform apply -var="container_image=<your-image-uri>"
# CI/CD applies automatically via GitHub Actions + Terraform CloudDjango Prometheus Integration:
- Middleware:
django_prometheus.middleware.PrometheusBeforeMiddleware&PrometheusAfterMiddleware - Metrics endpoint:
/metrics - Custom metrics:
sokoni/metrics.py
Exposed Metrics:
- HTTP request duration & count
- Database query performance
- Cache hit/miss rates
- Custom business metrics
AWS OTel Collector Sidecar:
- Collects metrics from Django app
- Pushes to AWS Managed Prometheus via remote_write
- IAM role:
sokoni-production-amp-remote-write-role
AWS Managed Prometheus:
- Workspace:
sokoni-prometheus-production-workspace - Query endpoint exposed for Grafana
Grafana:
- Runs on ECS Fargate
- Connects to AMP with IAM authentication
- Admin credentials in Secrets Manager
- Access via ECS service public IP on port 3000
CloudWatch Logs:
- Log group:
/ecs/sokoni-{env} - Streams:
ecsβ Django application logsadotβ OTel collector logsgrafanaβ Grafana logsmigrationsβ Database migration logs
Trivy (Container Images):
- Scheduled weekly scans
- Scans for OS packages and application dependencies
- Severity levels: CRITICAL, HIGH
- Results uploaded as SARIF artifacts
CodeQL (SAST):
- Static analysis for Python code
- Detects security vulnerabilities and code quality issues
- Runs on push/PR to
mainandstaging
SonarQube (SAST):
- Code quality and security analysis
- Configured via
sonar-project.properties - Organization:
victorgpt0
OWASP ZAP (DAST):
- Dynamic security testing against running container
- Baseline scan for common web vulnerabilities
- Reports uploaded as artifacts
GitLeaks:
- Scans commit history for leaked secrets
- Runs in CI on every push
Pre-commit Hooks:
detect-secretsscans for hardcoded secrets before commit- Baseline file:
.secrets.baseline - Also checks for AWS credentials
Runtime Secrets:
- AWS Secrets Manager for sensitive credentials
- SSM Parameter Store for configuration
- No secrets in environment variables or code
β
Non-root container user
β
Multi-stage Docker builds
β
Minimal base images (python:3.12-slim)
β
Security group rules with least privilege
β
HTTPS enforcement via ALB
β
Database encryption at rest (RDS)
β
IAM roles with scoped policies
β
Regular dependency updates
β
Automated security scanning in CI/CD
Production URL: sokoni.dev
| Deliverable | Status | Location |
|---|---|---|
| β Django E-commerce App | Complete | Root directory |
| β Source Control (GitHub) | Complete | https://github.com/victorgpt0/sokoni |
| β Branching Strategy | Complete | main β staging β development |
| β Dockerfile | Complete | Dockerfile |
| β Docker Compose | Complete | compose.yaml (Postgres commented) |
| β CI/CD Pipeline | Complete | .github/workflows/pipeline.yml |
| β Run Tests in CI | Complete | .github/workflows/pipeline.yml |
| β Build & Push Image | Complete | .github/workflows/pipeline.yml |
| β Trivy Security Scan | Complete | .github/workflows/trivy.yml |
| β Terraform IaC | Complete | .github/infra/ |
| β AWS Infrastructure | Complete | ECS, RDS, ALB, VPC, Security Groups |
| β Prometheus Integration | Complete | django-prometheus + AMP |
| β Grafana Dashboard | Complete | ECS service in monitoring.tf |
| β Secret Management | Complete | Secrets Manager, SSM, detect-secrets |
| β SAST (CodeQL, SonarQube) | Complete | .github/workflows/sast.yml |
| β DAST (OWASP ZAP) | Complete | .github/workflows/dast.yml |
| β Comprehensive README | Complete | This file |
| β Architecture Diagram | Complete | See above |
| β Live Demo Link | Complete | https://sokoni.dev |
| Pending |
Legend:
- β Complete
β οΈ Partial / Pending
main (production)
β
staging (pre-production)
β
development (active development)
β
feature/* (feature branches)
- Fork the repository
- Create a feature branch from
development:git checkout -b feature/amazing-feature
- Install pre-commit hooks:
pip install pre-commit pre-commit install
- Make your changes and commit:
git commit -m 'Add amazing feature' - Push to your fork:
git push origin feature/amazing-feature
- Open a Pull Request to
development
- All code must pass
pre-commithooks (Black, isort, detect-secrets) - Write tests for new features
- Maintain test coverage above 80%
- Follow Django best practices
- Document complex logic
- Nairobi DevOps Community - For the 12-week Starter DevOps Program
- Django Community - For the excellent web framework
- Tailwind CSS - For the utility-first CSS framework
- Paystack - For awesome payment integration
- AWS - For well documented cloud infrastructure
- HashiCorp - For Terraform Cloud
- Aqua Security - For Trivy
- OWASP - For ZAP security scanner
This project is licensed under the MIT License. See LICENSE file for details.
For questions or issues:
- GitHub Issues: https://github.com/victorgpt0/sokoni/issues
- Documentation: See
docs/directory - Seeding Guide:
docs/SEEDING.md - Docker Guide:
docs/DOCKER.md
Built with β€οΈ for the Kenyan e-commerce ecosystem
Demonstrating production-ready DevOps practices from code to cloud.