Deploying Django to AWS with Docker and Let's Encrypt
In this tutorial, we'll deploy a Django app to AWS EC2 with Docker. The app will run behind an HTTPS Nginx proxy that uses Let's Encrypt SSL certificates. We'll use AWS RDS to serve our Postgres database along with AWS ECR to store and manage our Docker images.
Django on Docker Series:
Objectives
By the end of this tutorial, you'll be able to:
- Set up a new EC2 instance
- Install Docker on an EC2 instance
- Configure and use an Elastic IP address
- Set up an IAM role
- Utilize Amazon Elastic Container Registry (ECR) image registry to store built images
- Configure AWS RDS for data persistence
- Configure an AWS Security Group
- Deploy Django to AWS EC2 with Docker
- Run the Django app behind an HTTPS Nginx proxy with Let's Encrypt SSL certificates
Prerequisites
This post builds on the Dockerizing Django with Postgres, Gunicorn, and Nginx and Securing a Containerized Django Application with Let's Encrypt posts.
It assumes that you can:
- Containerize a Django app along with Postgres, Nginx, and Gunicorn.
- Secure a containerized Django app running behind an HTTPS Nginx proxy with Let's Encrypt SSL certificates.
- Use SSH to connect to a remote server and SCP to copy files over to the server.
AWS EC2
First, create an AWS account if you don't already have one.
Next, navigate to the EC2 console and click Launch instance:
Enter a name for your instance and select Ubuntu Server 22.04 LTS (HVM) for the server image (AMI):
Stick with the t2.micro instance:
Create a new key pair for accessing your instance via SSH by clicking on "Create new key pair". When configuring the security group, stick with the default "Create new security group" and select "Allow HTTPS traffic from the internet" and "Allow HTTP traffic from the internet":
These rules are needed to issue certificates and to access the app.
The key pair will automatically download upon created.
Security group inbound rules are used to limit access to your instance from the internet. Unless you have some additional security requirements, you'll probably want to allow HTTP and HTTPS traffic from anywhere for instances hosting web apps. SSH must be allowed for you to connect to the instance for set up and deployment. In a production setup, limit the IPs from which SSH is allowed.
Click Launch. On the next screen, click View All Instances.
It will take a few minutes for the instance to spin up.
Configure EC2 Instance
In this section, we'll install Docker on the instance, add an Elastic IP, and configure an IAM role.
Install Docker
Navigate back to the EC2 console, select the newly created instance, and grab the public IP address:
Connect to your EC2 instance using the .pem
key that we downloaded in the "AWS EC2" step.
$ ssh -i /path/to/your/djangoletsencrypt.pem ubuntu@public-ip-or-domain-of-ec2-instance
Your
.pem
was probably downloaded into path like ~/Downloads/your-key-pair-name.pem. If you're not sure where to store it, move it into the "~/.ssh" directory. You may have to also change the permissions -- e.g.,chmod 400 -i /path/to/your/your-key-pair-name.pem
.
Start by installing the latest version of Docker and version 1.29.2 of Docker Compose:
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
$ sudo apt update
$ sudo apt install docker-ce
$ sudo usermod -aG docker ${USER}
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker -v
Docker version 20.10.8, build 3967b7d
$ docker-compose -v
docker-compose version 1.29.2, build 5becea4c
Install AWS CLI
First, install unzip:
$ sudo apt install unzip
Download AWS CLI ZIP:
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
Unzip its content:
$ unzip awscliv2.zip
Install AWS CLI:
$ sudo ./aws/install
Verify installation:
$ aws --version
Elastic IP
By default, instances receive new public IP address every time they start and re-start.
Elastic IP allows you to allocate static IPs for your EC2 instances, so the IP stays the same all the time and can be re-associated between instances. It's recommended to use one for your production setup.
Navigate to Elastic IPs and click Allocate Elastic IP address:
Then, click Allocate:
Select the newly created elastic IP address, click the Actions dropdown -> Associate this Elastic IP address:
Select your instance and click Associate:
IAM Role
We'll Docker pull images from AWS ECR to our EC2 instance during deployment. Since we won't be allowing public access to the Docker image on ECR, you'll need to create an IAM role with permissions to pull Docker images from ECR and attach it to your EC2 instance.
Navigate to the IAM console.
Click Roles in the left sidebar and then Create role:
Back to Top