Deploying dockerized Flask/Django based applications on AWS EC-2 instances using Gunicorn and Nginx

Harris Minhas
DiveDeepAI
Published in
5 min readAug 22, 2022

In this blog, you will get to know about containerizing applications that are written in python frameworks such as django and flask. After containerizing the application using docker and gunicorn, how we can export it to deployment on ec2 instances as our main servers. We will also get to know to set nginx up to reverse proxy our requests for our containerized app.

For any developer looking to grow, the knowledge of deploying applications to production environments is becoming increasingly necessary with the passage of time.

Historically speaking, deployments meant maintaining an on-premise server with a complete IT department looking after the equipment and making it function.However, after the advent of cloud computing, for small businesses, this need has been eliminated by these cloud provisioning platforms like google with GCP, Microsoft with Azure and Amazon with AWS.

Now, all the heavy lifting required to maintain the servers has been offloaded to these cloud provision platforms and developers have a server to SSH into and deploy the application using proxy servers such as nginx or apache. (The architecture of the system can obviously be different but we are assuming the above mentioned for the sake of this tutorial)

This article is going to walk you through the steps required to deploy flask/django based web applications on EC2 servers that are provided by AWS.

EC2 instances come in many shapes and sizes and you can set your preferred options using the AWS management console but the ones we are going to consider is a ubuntu based machine with RAM that is sufficient to run our application.

SSH into the EC2 instance:

The first step in setting up your application for deployment is to ssh into the EC2 instance using the credentials and the pem files provided by the AWS management console at the time of the creation of the EC2 instance.

If one is comfortable using the CLI to ssh into the server, the following command can be used for this purpose.

ssh -i /path/key-pair-name.pem instance-user-name@instance-public-dns-name

If not, there are many UI based tools that help in the process such as termius.

For more details, you can visit the AWS documentation at

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html

Preparing the application:

If you have an application that is written in python based web frameworks such as flask or django, you can dockerize it using gunicorn in the following manner.

Lets say you have a fully functioning flask based web application that you want to deploy. You would first have to write a dockerfile that can detail all the steps that are required to run your application within the docker container.

A common dockerfile can look like this.

An example of a dockerfile

The steps include copying the source code of the project inside the container and making sure that the requirements file is run with the python package manager known as pip with the appropriate python version. Gunicorn is used to make sure that the flask application is ready to handle production traffic as the default flask server is not designed to handle it. Gunicorn works by adding workers to handle requests to your flask code so that your app can handle more requests per seconds.

After doing this, the docker container for your application is ready to be deployed to production, provided however that your application does not require any other container to run alongside it. Sometime that is the case while in other cases it is not.

In cases in which more than one docker containers are required to make your code work, you would have to write a simple docker compose yaml file to define multiple containers. An example for such a case can be if your application has to use third party solutions for asynchronous processing such as celery.

A common docker compose file can look like this:

Common Docker Compose file

For more details on how to write a docker compose application, you can always refer to the following documented https://docs.docker.com/compose/compose-file/

Setting nginx up:

Nginx is a web server that can be used as a load balancer, reverse proxy as well as an HTTP cache.

We can set nginx up in either one of the two ways. Either inside the docker compose file or in the server outside the container on the EC-2 instance.

If you are new to docker, I would recommend you install nginx on server and use the service to reverse proxy your requests to the running docker container instance. The following commands should be run to get nginx running as a service on server.

For debian-based ubuntu servers,

sudo apt update

sudo apt install nginx

After installation, you can get the nginx service running by running

systemctl start nginx

To check the status of the service, you can use,

systemctl status nginx

If your nginx service is running perfectly, you should see an output similar to this,

Output for nginx status if working well

The next step is to configure the nginx particulars in its configuration files for the reverse proxy to route the request to the docker app container.

For that purpose, what you can do is to write the following lines of code in the configuration file, by default found in the etc/nginx/sites-enabled/ folder.

Nginx configuration file

This is true if your docker container for the app runs at the 8080 port on the server. You can check the port of your docker container by running “docker ps” from the command line.

After setting up the configuration, you can restart your nginx service by running “systemctl restart nginx”

Conclusion:

In this blogpost, you learnt about containerizing applications that are written in python frameworks such as django and flask. After containerizing the application using docker and gunicorn, how we can export it to deployment on ec2 instances as our main servers. We also learnt how to set nginx up to reverse proxy our requests for our containerized app. Hope it helped you learn a thing or two about deploying python based web applications.

--

--