Learn how to set up Nginx and Gunicorn in same container. Our Nginx Support team is here to help you with your questions and concerns.
Nginx and Gunicorn in the same container | Setup Guide
Today, we are going to take a look at integrating Gunicorn and Nginx within a Docker container.
An Introduction to Gunicorn
Gunicorn is a WSGI compliant web server for Python Applications. It receives requests sent by a Client to the Web Server and then forwards them to Web Frameworks or Python applications to run the application code for the request.
Furthermore, the Gunicorn server is compatible with different web frameworks. Also, implementation is simple and light on server resource usage.
An Introduction to Gunicorn & Nginx
Gunicorn can handle requests very fast. Also, it only allows those requests through, that need to arrive at our web application.
When a request comes from Nginx, Gunicorn converts it into a format that our web application can understand and ensures that your code is run when necessary.
In other words, Gunicorn handles requests quickly, and Nginx acts as a reverse proxy, translating requests for optimal execution.
If we are running Django & Gunicorn within a Docker container, we can limit access to a specific domain.
This involves running NGINX alongside Gunicorn and Django. Although this is not recommended, it comes in handy in certain situations.
To do this, Django will be running via Gunicorn as a daemon process and NGINX as a non-daemon process.
Simplifying Django and Nginx Deployment in a Docker Container
Let’s break down the steps to deploy a Django application with Nginx using Docker. We’ll keep it simple and easy to follow.
- To begin with, we have to set up the local environment. So, go to the and create a project folder:
cd path/to/your/dev/folder
mkdir -p django-nginx
- Then, create a Python virtual environment as seen here:
python3 -m venv venv
On Windows, it might look like:
C:\Python311\python.exe -m venv venv
- Next, we have to activate the virtual environment:
source venv/bin/activate
On Windows:
.\venv\Scripts\activate
- Now, it is time to install Django and Gunicorn. So, head to the project folder:
cd django-nginx
- Then, create a source folder to hold the Django project:
mkdir -p src
- Next, add Django and Gunicorn to requirements.txt:
echo "django" >> src/requirements.txt
echo "gunicorn" >> src/requirements.txt
We can add any other project requirements we may have.
- We can install the requirements as seen here:
$(venv) python -m pip install -r src/requirements.txt
Alternatively:
venv/bin/python -m pip install -r src/requirements.txt
- Now, it is time to create Django Project. So, move to the source directory and create a Django project named ‘cfehome’:
cd src
$(venv) django-admin startproject cfehome .
Alternatively:
cd src
../venv/bin/django-admin startproject cfehome - At this point, we have to add Nginx Configuration. So, go back to the main project folder:
cd path/to/your/dev/folder/django-nginx
- Then, create a folder for Nginx configuration:
mkdir nginx
- Now, create `nginx/default.conf`with this content:
upstream django_project {
server localhost:8000;
}
error_log /var/log/nginx/error.log;
server {
listen 80;
server_name codingforentrepreneurs.com *.codingforentrepreneurs.com;
root /www/data/;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://django_project;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
- Now, create `config/entrypoint.sh` in the source directory:
#!/bin/bash
RUN_PORT="8000"
/opt/venv/bin/python manage.py migrate --no-input
/opt/venv/bin/gunicorn cfehome.wsgi:application --bind "0.0.0.0:${RUN_PORT}" --daemon
nginx -g 'daemon off;'
- Then, create `Dockerfile`in the main project folder:
FROM python:3.11-slim
RUN apt-get update && apt-get install nginx -y
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log
COPY ./src ./app
WORKDIR /app
RUN python -m venv /opt/venv && \
/opt/venv/bin/python -m pip install pip --upgrade && \
/opt/venv/bin/python -m pip install -r requirements.txt
RUN chmod +x config/entrypoint.sh
CMD ["./config/entrypoint.sh"]
- Finally, it is time to build and run the Docker image:
docker build -t django-nginx -f Dockerfile .
docker run -p 8000:80 --name django-nginx --rm django-nginx
Now you have a simplified guide to deploy your Django application with Nginx using Docker!
Troubleshooting Tips
While deploying a Python Flask application with both Gunicorn and Nginx within a single container, users may run into issues. Usually, the Nginx component fails to initiate. This guide provides solutions and considerations for a seamless deployment.
1: Kubernetes Deployment
To fix the issue, we can try Kubernetes-based deployment. This involves separating Gunicorn and Nginx into different pods:
- First, create a Deployment and Service (ClusterIP) for Gunicorn.
- Then, create another Deployment and Service (NodePort or LoadBalancer) for Nginx.
- Now, configure Nginx to reference the Gunicorn Service as the backend host in its configuration using the `proxy_pass` directive.
This solution offers independent scalability and customization of each pod. Additionally, the automatic recreation of Pods is managed by the Deployment during application updates.
Also, we do not need to restart Nginx if the Python service (Gunicorn) crashes.
2: Docker Compose
Alternatively, we can use Docker Compose and simplify the YAML file structure:
version: '3.8'
services:
backend:
build: .
proxy:
image: nginx
volumes:
- ./nginx-conf:/etc/nginx/conf.d
ports:
- '8888:80'
This method helps avoid challenges associated with running multiple processes in one container. Also, it simplifies the Dockerfile structure for Gunicorn.
3: Daemon Mode for Gunicorn
If maintaining a single container is preferred, we can modify the Gunicorn startup in daemon mode to resolve issues. Update the Dockerfile CMD to:
CMD gunicorn --bind :8000 --workers 3 wsgi:app -D
This will help Gunicorn and Nginx function within a single container.
4: Kubernetes Pod with Two Containers
In case the containers work independently but communicate, we can consider a single pod with two containers:
apiVersion: v1
kind: Pod
spec:
containers:
- name: gunicorn-container
image:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
At the end of the day, choosing the right solution depends on our deployment goals and preferences.
[Need assistance with a different issue? Our team is available 24/7.]
Conclusion
In brief, our Support Experts demonstrated how to integrate Nginx and Gunicorn in the same container.
PREVENT YOUR SERVER FROM CRASHING!
Never again lose customers to poor server speed! Let us help you.
Our server experts will monitor & maintain your server 24/7 so that it remains lightning fast and secure.
0 Comments