In this tutorial, we'll explain how to Build a web application using Flask and Docker on Ubuntu 24.04. We'll create a basic Flask application, containerize it with Docker.
Flask is a lightweight and flexible Python web framework that allows developers to build web applications quickly and efficiently. Known for its simplicity and ease of use, Flask provides the essential components needed for web development without imposing any dependencies or project structure, making it highly adaptable to various project requirements.
Deploying a Flask application on Docker offers several benefits. Docker ensures consistency across different environments by containerizing the application with all its dependencies, eliminating the "it works on my machine" problem.
This containerization simplifies the deployment process, as Docker containers can run on any system that supports Docker, ensuring the application behaves the same everywhere. Additionally, Docker facilitates scalability by allowing multiple instances of the Flask application to run concurrently, managed by tools like Docker Compose or Kubernetes.
This setup improves the application's ability to handle increased traffic and enhances its resilience and reliability. Docker also streamlines the development workflow by enabling developers to quickly spin up and tear down isolated environments, making it easier to test changes and maintain the application.
Prerequisites
- A Ubuntu 24.04 installed dedicated server or KVM VPS
- Basic understanding of Python and Flask and Liunx commands.
- A root user access or normal user with adminitrative privileges
Build a web application using Flask and Docker
Step 1: Setting Up the Flask Application
Create a project directory:
mkdir flask_docker
cd flask_docker
Step 2: Virtual Environment
We need to install Python enviornment package to create virtual enviornment.
Note: Here we are installing 3.12
version because in our server Python 3.12
installed. This may be different for your server. Please check the version of the Python and use the same version here.
sudo apt install python3.12-venv -y
now let's set up a virtual environment and activate it:
python3 -m venv venv
source venv/bin/activate
Step 3: Install Flask:
Execute following command to install Flask in the virtual environment.
pip install Flask
Create a file named app.py
in the project directory with the following content:
nano app.py
Add following code:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello, Flask!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Save and exit the file.
Step 3: Configure Firewall
We need to add HTTP
and HTTPS
ports in the firewall.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
Step 4: Dockerizing the Flask Application
In the project directory, create a file named Dockerfile with the following content:
nano Dockerfile
Add following content:
# Use the official Python image from the Docker Hub
FROM python:3.12-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install the dependencies
RUN pip install -r requirements.txt
# Copy the rest of the application code
COPY . .
# Expose the port the app runs on
EXPOSE 5000
# Define the command to run the app
CMD ["python", "app.py"]
Save and exit the file.
Create a requirements.txt
file. In the project directory, create a file named requirements.txt and add the package we have installed in the virtual environment:
pip freeze > requirements.txt
Next, we'll install Docker. Following commands are copied from official website:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
To install the latest version, run:
sudo apt-get install docker-ce -y
Build the Docker image:
Run the following command to build the Docker image:
docker build -t flask_app .
Step 5: Generate SSL Certificate
Before proceeding further, we need to generate standalone SSL certificate using Certbot. We need the certificate path to add in the docker compose file.
sudo apt install certbot -y
Run the following command to obtain an SSL certificate:
Note: Replace your_domain
with your domain.
sudo certbot certonly --standalone -d your_domain
After your execute above command it will provide the SSL certificate installed path. Copy SSL certificate saved path, we need it for next step to add in the nginx.conf
file. It looks like:
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
Step 5: Setting Up Docker Compose
First, create an Nginx configuration file. In the project directory, create a directory named nginx and a file named nginx.conf
inside it with the following content:
mkdir nginx && nano nginx/nginx.conf
Add following content:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
upstream flask_app {
server web:5000;
}
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name yourdomain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://flask_app;
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;
}
}
}
Note:
- Replace
ssl_certificate
andssl_certificate_key
path with your domain SSL certificate path that you have copied from last step. - Replace
yourdomain.com
with your domain name.
Save and exit the file.
Next, install Docker Compose using following command:
Download the latest version of Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
Verify the installation:
docker-compose --version
Docker Compose helps manage multi-container Docker applications. We'll use it to simplify the management of our Flask application.
Create a docker-compose.yml
file:
nano docker-compose.yml
In the project directory, create a file named docker-compose.yml with the following content:
version: '3.9'
services:
web:
build: .
container_name: flask_app
ports:
- "5000:5000"
nginx:
image: nginx:latest
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- /etc/letsencrypt:/etc/letsencrypt
ports:
- "80:80"
- "443:443"
depends_on:
- web
Save and exit the file.
Run the application using Docker Compose:
Run the following command to start the application:
docker-compose up -d
Open your browser and go to https://your_domain
. You should see "Hello, Flask!
".
Troubleshooting
If you will face any issue with the Docker container, check the logs. Execute following command to check the logs:
docker logs -f --until=2s [Docker container name]
Conclusion
In this tutorial, we seen how to built a web application using Flask and Docker. We containerized the Flask application, used Docker Compose for easier management, and set up Nginx as a load balancer to distribute traffic among multiple instances. This setup ensures that the application can handle increased traffic and is easier to manage and deploy.