Production Deployment with Docker Compose
![Production Deployment with Docker Compose](/_next/image/?url=https%3A%2F%2Fstatic-staging.d-libro.com%2F01-course-content-images%2F2031-10-Docker-Basics%2F010-main-figures%2Fproduction-deployment-with-docker-compose-id203110060410.webp&w=1920&q=75)
Deploying a web application in production requires a setup that is scalable, secure, and easy to manage. Docker Compose simplifies this process by allowing you to define and run multiple services—such as Django, PostgreSQL, and Nginx—in a single configuration.
In this guide, we’ll deploy the Django web application that we created in the previous section, transitioning it from local development to a production-ready environment using AWS Lightsail, Docker, and Nginx. By containerizing the application with Docker, we ensure that the same code runs consistently across different environments, demonstrating the portability and reliability of our setup.
If you prefer to jump straight into setting up the production server, you can skip the first step and clone the preconfigured code from GitHub.
Step 1: Initiate Git and Push the Code to GitHub
If you haven’t initiated a Git repository for your project, follow these steps to set it up and push your code to GitHub.
1. Initialize Git Repository (If Not Already Done)
Navigate to the project directory and initialize a Git repository:
cd path/to/your/project
git init
2. Add and Commit the Code
After updating the settings.py
and docker-compose-prod.yml
for production, commit the changes:
git add .
git commit -m "Updated settings for production deployment"
If this is your first commit, a simple message like 'First commit' is sufficient.
3. Connect to a GitHub Repository
If you haven’t already connected your project to a GitHub repository, create one on GitHub and link it to your local repository:
git remote add origin https://github.com/your-username/your-repository.git
4. Push Code to the GitHub Main Branch
Since we are handling different settings using the .env
file, we can use the main
branch instead of a separate production branch. Push the code to GitHub:
git branch -M main
git push -u origin main
To learn how to set up and use Git and GitHub, check out our Git and GitHub Introduction Guide. It provides a visual, step-by-step walkthrough.
Step 2: Prepare AWS Lightsail Instance
To deploy the application, you first need to set up a virtual server on AWS Lightsail. This instance will serve as the production environment where your Django application, database, and Nginx web server will run. We are using AWS Lightsail because it provides a simplified and cost-effective way to deploy applications compared to AWS EC2. Lightsail offers pre-configured virtual servers, making it easier and quicker to set up a production environment without managing complex AWS networking and infrastructure settings.
- Create an AWS account if you don't have one.
- Go to the Lightsail console and click Create instance.
- Choose Linux/Unix as the platform and Ubuntu 24.04 LTS as the OS.
![AWS Lightsail Setup AWS Lightsail Setup](https://static.d-libro.com/01-course-content-images/2031-10-Docker-Basics/020-image-insert/aws-lightsail-setup-id203110060410-img01.webp)
- Select an instance plan that meets your needs.
- Choose an instance name and click Create instance.
- Once the instance is running, connect to it using SSH.
To learn how to set up SSH, refer to our Linux Introduction Guide. The guide provides step-by-step instructions with plenty of visual illustrations.
Step 3: Install Docker and Docker Compose
To deploy the application in a containerized environment, you need to install Docker and Docker Compose on the production server. Docker allows you to package the application with its dependencies, ensuring consistency across different environments, while Docker Compose helps manage multiple services like Django and PostgreSQL.
Update the package list:
sudo apt update
Install Docker:
sudo apt install docker.io
Add the current user to the Docker group:
sudo usermod -aG docker $USER
Note: You need to log out and log back in for the changes to take effect.
Verify Docker installation:
docker --version
Install Docker Compose:
sudo apt install docker-compose
Verify Docker Compose installation:
docker-compose --version
Step 4: Clone the Project Files from GitHub
Once the production server is set up, you need to retrieve the latest version of your code from GitHub. Cloning the repository ensures that your application files are properly synced with the latest updates from your local development environment.
This ensures that you have all necessary files before proceeding with the deployment.
sudo apt install git
If you previously pushed your code to your own GitHub repository, use the following command to clone it and navigate into the project directory:
git clone https://github.com/your-username/your-repository.git
cd your-repository
If you skipped the first section and do not have your own repository, you can download our prepared code and navigate into the project directory. The code for this guide is stored in the production
branch, so make sure to switch to it after cloning.
git clone https://github.com/bloovee/ch6-docker-compose-demo.git
cd ch6-docker-compose-demo
For practice purposes, we are including the .env
file in the GitHub repository with a Django SECRET_KEY
and other environment variables.
Disclaimer:
In a real-world production setup, sensitive information such as SECRET_KEY
, database credentials, and API keys should never be stored in a public repository. Exposing these secrets can lead to security risks, including unauthorized access and data breaches.
For actual deployments, always use environment variables, secret management tools (e.g., AWS Secrets Manager, Docker Secrets, or .env
files excluded from Git), and follow best practices for securing sensitive data.
Step 5: Place .env File for Production
Now that you have cloned the project files onto your production server, the next step is to create and configure the .env
file with production-specific environment variables.
Create the .env File
Navigate to the project directory and create the .env
file in the project directory.
vim .env
Add Production-Specific Environment Variables
Copy and paste the following into the .env
file:
SECRET_KEY=your-secure-random-key
DEBUG=False
ALLOWED_HOSTS=your-server-ip,your-domain.com
- Keeps the
SECRET_KEY
secure by storing it in an environment variable rather than hardcoding it insettings.py
. - Disables
DEBUG
mode to prevent sensitive error messages from being displayed in production. ALLOWED_HOSTS
: Defines the allowed hostnames or IP addresses that can access the application, ensuring that unauthorized requests are blocked. You can find your AWS Lightsail instance IP in the AWS Console. If you're using a domain, add it here as well.
![AWS Lightsail Public IP Address AWS Lightsail Public IP Address](https://static.d-libro.com/01-course-content-images/2031-10-Docker-Basics/020-image-insert/aws-lightsail-public-ip-address-id203110060410-img02.webp)
Save and Exit
In Vim, press ESC
, then type:
:wq
and press ENTER
.
If you want to master Vim operations, refer to our Linux Introduction Guide.
Once the .env
file is properly placed, Django will automatically load these environment variables, ensuring the application runs with the correct production settings.
Step 6: Update Nginx Settings
Nginx will act as a reverse proxy for the Django application, forwarding client requests to the Gunicorn server running inside the Docker container and serving static files efficiently.
sudo vim /etc/nginx/sites-available/django
Replace your-server-ip
and your-domain.com
with your server’s IP address or domain name.
server {
listen 80;
server_name your-server-ip your-domain.com;
Save and exit the file (ESC
→ :wq
→ ENTER
).
Step 7: Build, Run Migrations, Collect Static Files, and Create Superuser
Before running the application, you need to set up the database schema, collect static files, and create an admin user. Follow these steps to ensure everything is properly configured.
# Start the application in detached mode (production)
docker-compose -f docker-compose-prod.yml up --build -d
# Apply database migrations
docker-compose -f docker-compose-prod.yml run --rm web python manage.py migrate
# Collect static files for production
docker-compose -f docker-compose-prod.yml run --rm web python manage.py collectstatic --noinput
# Create a Django superuser
docker-compose -f docker-compose-prod.yml run --rm web python manage.py createsuperuser
Follow the prompts to set up the superuser credentials. Once completed, your application is ready for testing.
Step 8: Test the Deployment
After completing the setup, verify that your application is running correctly. Make sure to use HTTP (not HTTPS) for testing. If you want to use HTTPS, additional configuration is required.
Access the Django admin panel:
Open a browser and visit: http://your-server-ip/admin/
Log in using the superuser credentials you created earlier. Create some book categories from the admin panel to test the UI in the next step.
Check the main application:
Open a browser and visit: http://your-server-ip/
This should display your web application.
Step 9: Stop or Delete the Instance
Once you have completed your practice, you can stop or delete the AWS Lightsail instance to avoid unnecessary costs.
1. Stop the Instance (Recommended for Temporary Pause)
Stopping the instance will preserve all data while preventing it from incurring charges for compute resources.
- Log in to AWS Lightsail.
- Navigate to your instance.
- Click Stop.
2. Delete the Instance (Permanent Removal)
If you no longer need the instance and want to permanently remove it:
- Log in to AWS Lightsail.
- Navigate to your instance.
- Click Delete and confirm the action.
Important: Deleting an instance cannot be undone and will remove all associated data. If you need to keep your project, backup your database and files before deleting the instance.
FAQ: Production Deployment with Docker Compose
What is the purpose of using Docker Compose in production deployment?
Docker Compose allows you to define and run multiple services, such as Django, PostgreSQL, and Nginx, in a single configuration, simplifying the deployment process and ensuring consistency across different environments.
Why is AWS Lightsail chosen for deploying the application?
AWS Lightsail is chosen because it provides a simplified and cost-effective way to deploy applications compared to AWS EC2, with pre-configured virtual servers that make it easier and quicker to set up a production environment.
How do you ensure the security of sensitive information in a production setup?
In a production setup, sensitive information like SECRET_KEY and database credentials should be stored in environment variables or secret management tools, and not in public repositories, to prevent unauthorized access and data breaches.
What role does Nginx play in the deployment process?
Nginx acts as a reverse proxy for the Django application, forwarding client requests to the Gunicorn server running inside the Docker container and serving static files efficiently.
What should be done after testing the deployment to avoid unnecessary costs?
After testing, you can stop the AWS Lightsail instance to preserve data and prevent charges, or delete it if no longer needed, ensuring to back up any important data before deletion.