The author has selected the Technology Education Fund to receive a donation as part of the Write for DO donate program.
Introduce
Docker is an open source application that allows administrators to create, manage, deploy, and scale applications using containers. A container can be thought of as a package containing the dependencies that an application requires to run at the operating system level. This means that each application deployed using Docker lives in a separate environment and its requests are handled separately.
Flask is a web micro framework built on Python. It’s called a micro-framework because it doesn’t require specific tools or plug-ins to run. The Flask framework is lightweight and flexible, yet highly structured, making it especially popular for small web applications written in Python.
Deploying a Flask application with Docker will allow you to replicate the application on different servers with minimal reconfiguration.
In tutorial For this, you will create a Flask application and deploy it with Docker. This guide will also demonstrate how to update the application after deployment.
Prerequisites
To follow this guide, you will need the following:
Step 1 – Set Up the Average App
To get started, you’ll create a directory structure containing your Flask application. This tutorial will create a folder named TestApp
in /var/www
, but you can modify the command to whatever name you want.
- sudo mkdir /var/www/TestApp
Go to the newly created section TestApp
category:
Next, create the base folder structure for the Flask application:
- sudo mkdir -p app/static app/templates
The -p
flag indicates that mkdir
will create a directory and socks both parent directories do not exist. In this case, mkdir
will create app
parent directory during creation static
and templates
folders.
The app
folder will contain all files related to Flask application such as view and the design. Views are the code you write in response to requests to your application. The design Create application components and support common patterns within an application or across applications.
The static
folder is where content like images, CSS and files are stored JavaScript. The templates
folder is where you will put the HTML templates for your project.
Now that the base directory structure is complete, you need to create the necessary files to run the Flask application. First, let's create a __init__.py
file inside app
folder using nano or a text editor of your choice. This file tells the Python interpreter that app
directory is a package and should be treated as such.
Run the following command to create the file:
- sudo nano app/__init__.py
Packages in Python allow you to group modules into namespaces or logical hierarchies. This approach allows the code to be broken down into individual and manageable blocks to perform specific functions.
Next, you will add the code in __init__.py
that will create a Flask instance and import the logic from views.py
file that you will create after saving this file. Add the following code to your new file:
/var/www/TestApp/app/__init__.py
from flask import Flask
app = Flask(__name__)
from app import views
Once you've added that code, save and close the file. You can save and close the file by pressing Ctrl+X,
then when prompted, Y
and Enter
.
With __init__.py
file created, you are ready to create views.py
your input file app
category. This file will contain most of your application logic.
Next, add the code to your views.py
file. This code will return hello world!
string to users who visit your site:
/var/www/TestApp/app/views.py
from app import app
@app.route("https://toiyeuit.com/")
def home():
return "hello world!"
The @app.route
The line above the function is called the decorator. Decorator is a Python language convention widely used by Flask; their purpose is to modify the functions immediately after them. In this case, the decorator tells Flask which URL to fire home()
function. The hello world
Text returned by home
the function will be visible to the user on the browser.
With views.py
Apply on the spot, you're ready to create uwsgi.ini
file. This file will contain uWSGET configuration for our application. uWSGI is an implementation option for Nginx as both a protocol and an application server; The application server can serve uWSGI, FastCGI and HTTP protocols.
To create this file, run the following command:
Next, add the following content to your file to configure the uWSGI server:
/var/www/TestApp/uwsgi.ini
[uwsgi]
module = main
callable = app
master = true
This code defines the module that the Flask application should be served from. In this case, this is main.py
file, referenced here as main
. The callable
optional uWSGI instructions to use app
version exported by the main application. The master
the option allows your app to keep running, so there's very little downtime even when reloading the entire app.
Next, create main.py
file, which is the entry point to the application. The entry point instructs uWSGI how to interact with the application.
Next, copy and paste the following into the file. This imports the Flask instance named app
from the previously created apk.
/var/www/TestApp/main.py
from app import app
Finally, create a requirements.txt
to specify the dependencies that pip
the package manager will install to your Docker deployment:
- sudo nano requirements.txt
Add the following line to add Flask as a dependency:
/var/www/TestApp/requirements.txt
Flask>=2.0.2
This specifies the Flask version to be installed. At the time of writing this tutorial, 2.0.2 is the latest Flask version and specifies >=2.0.2
will make sure you get version 2.0.2 or later. Since you are creating a basic test application in this tutorial, the syntax may not be outdated due to future updates to Flask, but if you want to be safe and still receive minor updates , you can specify that you don't want to install a major version in the future by specifying something like Flask>=2.0.2,. Bạn có thể kiểm tra các bản cập nhật tại trang web chính thức cho Flask hoặc trên trang đích của Python Package Index cho thư viện Flask.
Save and close the file. You have successfully set up your Flask application and are ready to set up Docker.
Step 2 - Docker Setup
In this step you will create two files, Dockerfile
and start.sh
, to create your Docker deployment. The Dockerfile
is a text document containing the commands used to assemble the image. The start.sh
file is a shell script that will build an image and create a container from Dockerfile
.
First, let's create Dockerfile
.
Next, add your desired configuration to the Dockerfile
. These commands specify how the image will be built and what additional requirements should be included.
/var/www/TestApp/Dockerfile
FROM tiangolo/uwsgi-nginx-flask:python3.8-alpine
RUN apk --update add bash nano
ENV STATIC_URL /static
ENV STATIC_PATH /var/www/app/static
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt
In this example, the Docker image will be built on top of the existing image, tiangolo/uwsgi-nginx-flask
, you can find on DockerHub. This particular Docker image is a good choice over the others because it supports multiple Python versions and operating system images.
The first two lines specify the original image that you will use to run the application and install the bash command processor and nano
text editor. It also installs git
clients to pull and push to version control hosting services like GitHub, GitLab, and Bitbucket. ENV STATIC_URL /static
is an environment variable specific to this Docker image. It defines the static directory where all content like images, CSS files, and JavaScript files are served from.
The last two lines will copy requirements.txt
file into the container so it can be executed, and then parsed requirements.txt
to install the specified dependencies.
Save and close the file after adding your configuration.
With you Dockerfile
in place, you are almost ready to write start.sh
script will create the Docker container. Before writing start.sh
script, first make sure you have an open port to use in the configuration. To check if a port is empty, run the following command:
Nếu đầu ra của lệnh trên là 1
, the port is free and usable. Otherwise, you will need to select another port to use in start.sh
configuration file.
Once you've found an open port to use, create start.sh
script:
The start.sh
script is a shell script that will build an image from Dockerfile
and create a container from the resulting Docker image. Add your configuration to the new file:
/var/www/TestApp/start.sh
#!/bin/bash
app="docker.test"
docker build -t ${app} .
docker run -d -p 56733:80
--name=${app}
-v $PWD:/app ${app}
The first line is called shebang. It specifies that this is a bash file and will be executed as commands. The next line specify the name you want to give the image and container and save it as a variable named app
. The next line instructs Docker to build the image from Dockerfile
located in the current directory. This will create an image named docker.test
in this example.
The last three lines create a new container named docker.test
exposed at the port 56733
. Finally, it associates the current directory with /var/www
directory of the container.
You use -d
flag to start a container in daemon mode or as a background process. You include -p
flag to associate a port on the host with a specific port on the Docker container. In this case you are binding the port 56733
go to Port 80
on the Docker container. The -v
flags specifying a Docker volume to mount on the container and in this case you are mounting the entire project directory to /var/www
on the Docker container.
Save and close the file after adding your configuration.
Perform start.sh
script to create a Docker image and build a container from the resulting image:
Once the script finishes running, use the following command to list all running containers:
You will receive output that shows the containers:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test
You will see that docker.test
container is running. Now that it's running, visit the IP address at the specified port in your browser: http://ip-address:56733
You will see a page similar to the following:
In this step, you have successfully deployed your Flask application on Docker. Next, you'll use templates to display content to users.
Step 3 - Provide Sample File
Templates are files that expose static and dynamic content to users accessing your application. In this step, you will create an HTML template to create the homepage for the application.
Start by creating home.html
file in app/templates
category:
- sudo nano app/templates/home.html
Add the code for your template. This code will create an HTML5 page containing the title and some text.
/var/www/TestApp/app/templates/home.html
Welcome home
This is the home page of our application.
Save and close the file once you've added your template.
Next, modify app/views.py
file to serve the newly created file:
First, add the following line at the beginning of your file to import the render_template
method from Binh. This method parses an HTML file to display a web page to the user.
/var/www/TestApp/app/views.py
from flask import render_template
...
At the end of the file, you will also add a new route to display the template file. This code specifies that the user is provided with the content of home.html
submit whenever they visit /template
route on your app.
/var/www/TestApp/app/views.py
...
@app.route('/template')
def template():
return render_template('home.html')
Update app/views.py
the file will look like this:
/var/www/TestApp/app/views.py
from flask import render_template
from app import app
@app.route("https://toiyeuit.com/")
def home():
return "Hello world!"
@app.route('/template')
def template():
return render_template('home.html')
Save and close the file when done.
For these changes to take effect, you need to stop and restart the Docker container. Run the following command to rebuild the container:
- sudo docker stop docker.test && sudo docker start docker.test
Access your app at http://your-ip-address:56733/template
to see the new model being offered.
In this section, you created a Docker sample file to serve visitors to your application. In the next step, you'll see how changes you make to your application can take effect without having to restart the Docker container.
Step 4 - Update the app
Sometimes you'll need to make changes to your application, whether it's installing new requirements, updating your Docker container, or changing HTML and logic. In this section, you will configure touch-reload
to make these changes without restarting the Docker container.
Python automatic download monitors the entire file system for changes and refreshes the application when changes are detected. Autoloading is not recommended in production as it can become resource consuming very quickly. In this step you will use touch-reload
to see the changes to a specific file and reload it when the file is updated or replaced.
To do this, start by opening uwsgi.ini
file:
Next, add the highlighted line to the end of the file:
/var/www/TestApp/uwsgi.ini
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini
This specifies a file to be modified to trigger a full app reload. Once you've made the changes, save and close the file.
To demonstrate this, let's make a small change to your application. Start by opening yours app/views.py
file:
Replace the string returned by the home
function:
/var/www/TestApp/app/views.py
from flask import render_template
from app import app
@app.route("https://toiyeuit.com/")
def home():
return "There has been a change"
@app.route('/template')
def template():
return render_template('home.html')
Save and close the file after you've made changes.
Next, if you open your app home page at http://ip-address:56733
, you will notice that the changes are not reflected. This is because the reload condition is a change to uwsgi.ini
file. To reload the app, use touch
to trigger the condition:
Reload the application homepage in your browser again. You will find that the application has incorporated the changes:
In this step, you set up a touch-reload
condition to update your application after making the changes.
Inference
In this tutorial, you created and deployed a Flask application to a Docker container. You have also configured touch-reload
to refresh your application without restarting the container.
With your new application on Docker, you can now scale easily. To learn more about using Docker, check out their official documentation.
.