A full-stack web application with a simple frontend and a Django backend, containerized with Docker and deployed on AWS Elastic Beanstalk. The application integrates multiple AWS services for persistence, content delivery, container image management, and operational logging, and includes a CI/CD pipeline that deploys on tag creation.
- Backend: Django (Python)
- Frontend: Simple static frontend served via CloudFront
- Container runtime: Docker (images stored in ECR)
- Hosting: Elastic Beanstalk (EB) on AWS
- Databases: Amazon RDS (primary relational DB), Amazon DynamoDB (user login data)
- Logs: File-based logging with automated rotation and archival to Amazon S3 at 5MB
- Static assets: Served via Amazon CloudFront
- CI/CD: GitHub Actions deploys new versions on tag push (.github/workflows/aws.yml)
- Prerequisites
- Local Development
- Configuration
- AWS Infrastructure
- Deployment
- CI/CD Pipeline
- Logging and Monitoring
- Database Setup
- Static Assets
- Security and IAM
- Project Structure
- Contributing
- License
- Git and GitHub account
- Docker (local development and builds)
- Python 3.x and pip (if running Django locally without Docker)
- AWS account with permissions to:
- Manage Elastic Beanstalk environments
- Manage ECR repositories
- Access and configure RDS, DynamoDB, S3, CloudFront
- Create and use IAM roles and policies
- AWS CLI configured locally (optional but recommended)
- GitHub repository secrets for CI/CD (see CI/CD Pipeline)
You can run the app locally with Docker or with a native Python environment.
-
Build the image:
docker build -t beanstalk-web-app:local . -
Set required environment variables (see Configuration). For quick testing, you can use a
.envfile and--env-file:docker run --env-file .env -p 8000:8000 beanstalk-web-app:local -
Visit:
- Backend: http://localhost:8000
- Frontend: Depending on app setup, frontend may be served by Django or via a dev server.
Using python3.13
-
Create and activate a virtual environment:
python3.13 -m venv .venv source .venv/bin/activate -
Install dependencies:
pip install -r requirements.txt -
Set environment variables (see below) or create a
.envfile. -
Run migrations and start the server:
python manage.py migrate python manage.py runserver 0.0.0.0:8000
The application expects the following environment variables (exact names may vary based on implementation):
- Django:
DJANGO_SECRET_KEY: Secret key for Django.DJANGO_DEBUG:true/falseto enable/disable debug.DJANGO_ALLOWED_HOSTS: Comma-separated list (e.g.,localhost,example.com).
- Database (RDS):
DB_ENGINE: Django DB engine (e.g.,django.db.backends.postgresql).DB_NAME: Database name.DB_USER: Database username.DB_PASSWORD: Database password.DB_HOST: RDS hostname.DB_PORT: RDS port (e.g.,5432).
- DynamoDB:
DYNAMODB_TABLE: Users table name for login data.AWS_REGION: AWS region for DynamoDB and other services.
- AWS services integration:
ECR_REPOSITORY: ECR repository name/URI (for CI/CD).S3_LOGS_BUCKET: Bucket for log archival.CLOUDFRONT_DISTRIBUTION_IDorCLOUDFRONT_URL: For static content distribution (depending on your setup).
- Other:
APP_ENV: Environment name (e.g.,dev,staging,prod).- Any additional app-specific settings used in your settings module.
Create a .env file in the project root for local runs, and configure equivalent environment variables in your Elastic Beanstalk environment.
- Elastic Beanstalk:
- Environment runs the Dockerized Django app.
- EB will pull the image from ECR during deployments.
- ECR:
- Stores container images tagged per release.
- RDS:
- Primary relational database (e.g., PostgreSQL/MySQL).
- DynamoDB:
- Stores user login data (e.g., credentials or session-like data).
- S3:
- Receives log archives from container log rotation (threshold 5MB).
- CloudFront:
- Serves static assets. You may configure origin to be S3 or the EB application depending on your static assets architecture.
Ensure the EB instance profile/role has permissions to access S3 (for logs), ECR (to pull images), RDS/DynamoDB (for data), and any other required services.
- Build and push Docker image to ECR:
- Authenticate Docker to ECR:
aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin <account-id>.dkr.ecr.$AWS_REGION.amazonaws.com - Build and tag:
docker build -t beanstalk-web-app:<version-tag> . docker tag beanstalk-web-app:<version-tag> <account-id>.dkr.ecr.$AWS_REGION.amazonaws.com/<ecr-repo>:<version-tag> - Push:
docker push <account-id>.dkr.ecr.$AWS_REGION.amazonaws.com/<ecr-repo>:<version-tag>
- Trigger EB deployment:
- The CI/CD pipeline automatically deploys on tag creation. See CI/CD Pipeline.
- Database migrations:
- If migrations aren’t automatically run in your entrypoint, run them on the EB environment after deployment:
python manage.py migrate
This repository includes a GitHub Actions workflow that deploys a new EB version when you create a Git tag.
- Workflow file: .github/workflows/aws.yml
- Trigger: Push of a tag (e.g.,
git tag v1.2.3 && git push origin v1.2.3) - Steps:
- Check out repository
- Authenticate with AWS (using secrets)
- Build Docker image
- Push image to ECR
- Update Elastic Beanstalk environment with new image tag
Required GitHub Secrets (example names, may vary based on workflow implementation):
AWS_ACCOUNT_IDAWS_REGIONAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYECR_REPOSITORYCONTAINER_NAMEELASTIC_BEANSTALK_APP_NAMEELASTIC_BEANSTALK_ENV_NAME
To deploy:
- Update code.
- Create and push a new tag:
git tag vX.Y.Z git push origin vX.Y.Z - GitHub Actions will run and deploy automatically.
- In-container logs:
- Application writes logs to a file inside the container (file.log)
- Automated log rotation: when the file reaches 5MB, it is rotated and uploaded to S3 (
S3_LOGS_BUCKET).
- S3:
- Logs are archived for long-term storage.
- After 7 days there are moved to a glacier storage.
- CloudWatch:
- Optionally configure EB to stream logs to CloudWatch for real-time monitoring, add a variable to the
.env.
- Optionally configure EB to stream logs to CloudWatch for real-time monitoring, add a variable to the
- RDS:
- Provision RDS in the same VPC/subnets as EB for connectivity.
- Configure
DB_*environment variables in EB. - Apply migrations using Django’s
python manage.py migratecommand inside the container.
- DynamoDB:
- Create the users table and set
DYNAMODB_TABLEin environment variables. - Ensure IAM permissions for read/write as needed by your login flow.
- Create the users table and set
Data migrations:
- Add Django migrations to your app as you evolve the schema.
- Use a migration step in your deployment process or run manually after deployment.
- Static assets are served via CloudFront for performance and caching.
- Django static collection:
- If using
collectstatic, ensure it runs and pushes assets to your chosen origin (S3 bucket or EB). - Configure CloudFront to point to that origin.
- If using
- Cache invalidation:
- Invalidate CloudFront distribution on deployments that change static assets (optional but recommended).
- Use AWS IAM roles for service-to-service permissions:
- EB instance profile for S3, ECR, DynamoDB, RDS (via security groups instead of IAM for DB).
- Network:
- Place EB/RDS in private subnets where possible.
- Restrict security groups to necessary ports (e.g., 80/443 for load balancer, DB ports internally).
- Django security:
- Disable debug in production (
DJANGO_DEBUG=false). - Set
DJANGO_ALLOWED_HOSTSproperly. - Rotate
DJANGO_SECRET_KEYand store securely.
- Disable debug in production (
MIT Licence. See LICENSE for details.
