Deploying 3-tier Backend Application Using Docker And Nginx
Introduction
The 3-tier backend application comprises three containers:
NGINX
MySQL
Django-App
This setup demonstrates how these components collaborate to deliver a robust, scalable, and maintainable web application.
What is NGINX?
NGINX acts as a reverse proxy, handling requests from clients and forwarding them to backend servers. Its functionalities include load balancing, caching, and SSL termination.
Key Uses of NGINX:
Load Balancing:
Distributes incoming requests across multiple servers to optimize resource use and avoid overloading a single server.Security and Anonymity:
Hides backend server details from clients, making it harder for attackers to target backend servers directly.
Acts as a security layer by filtering and blocking malicious requests.
SSL/TLS Termination:
Handles SSL/TLS encryption for secure HTTPS connections.
Offloads this task from backend servers, improving performance.
Caching:
Caches responses and serves them directly to clients.
Reduces response time and improves speed.
Centralized Access Control and Authentication:
Enforces authentication and authorization, serving as a single control point for managing access.
Important Things to Remember
MySQL Data Directory:
- If the MySQL data directory is created in your working directory, either remove it or provide the necessary permissions for the server to access it.
Requirements for Docker-Compose File:
Dependency Check: Use
depends_on
to specify container dependencies.Healthcheck: Ensures dependent containers only start when required services are ready.
Networks: Containers must be on the same network to interact.
docker network create --driver bridge my_bridge_network
#Volumes: Specify volumes in the services section of the compose file.
docker volume create my_volume
#Environment Variables: Use a .env file to set variables like:
DB_NAME=test_db
DB_USER=root
DB_PASSWORD=root
DB_PORT=3306
DB_HOST=mysql
NGINX Configuration Directory
The NGINX directory includes:
Dockerfile
default.conf
default.conf File Example
upstream django {
server django_app:8000;
}
server {
listen 80; # Default port for NGINX
server_name localhost; # Replace with your server's IP address
location / {
proxy_pass http://django;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Key Points:
Upstream: Defines a group of backend servers (e.g., Django).
Proxy Settings: Configure headers to manage forwarded requests.
Dockerfile:
FROM nginx:1.23.3-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
docker-compose.yml Example
version: "3.8"
services:
nginx:
build: ./nginx
image: nginx
container_name: "nginx_cont"
ports:
- "80:80"
restart: always
depends_on:
- django_app
networks:
- three-tier
mysql:
image: mysql
container_name: "mysql-3-tier"
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=test_db
volumes:
- three-tier-database:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-proot"]
interval: 10s
timeout: 5s
retries: 5
start_period: 60s
networks:
- three-tier
django_app:
container_name: "django_container"
build:
context: .
image: django_app
ports:
- "8000:8000"
restart: always
command: sh -c "python manage.py migrate --noinput && gunicorn notesapp.wsgi --bind 0.0.0.0:8000"
env_file:
- ".env"
depends_on:
- mysql
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/admin || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- three-tier
networks:
three-tier:
volumes:
three-tier-database:
Command Explanation
sh -c "python manage.py migrate --noinput && gunicorn notesapp.wsgi --bind 0.0.0.0:8000"
python manage.py migrate --noinput:
# Applies pending database migrations.
# Ensures database schema syncs with Django models.
gunicorn notesapp.wsgi --bind 0.0.0.0:8000:
# Launches the Django application using Gunicorn.
# Listens on all network interfaces (0.0.0.0) and port 8000.
Key Highlights
The
.env
file manages sensitive configurations (e.g., database credentials).A named volume (
three-tier-database
) ensures data persistence for MySQL.NGINX serves as a central point for load balancing, caching, and security.
Docker Compose simplifies orchestration, ensuring service dependencies are met.
This structured setup ensures a reliable, scalable, and high-performance backend architecture.
Subscribe to my newsletter
Read articles from Arun Pandey directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by