The author selected the Tech Education Fund to receive a donation as part of the Write for DOnations program.
作者选择了Tech Education Fund作为“ Write for DOnations”计划的一部分来接受捐赠。
介绍 (Introduction)
Docker is an open-source application that allows administrators to create, manage, deploy, and replicate applications using containers. Containers can be thought of as a package that houses dependencies that an application requires to run at an operating system level. This means that each application deployed using Docker lives in an environment of its own and its requirements are handled separately.
Docker是一个开源应用程序,允许管理员使用容器创建,管理,部署和复制应用程序。 容器可以看作是一个包,其中包含应用程序在操作系统级别运行所需的依赖项。 这意味着使用Docker部署的每个应用程序都生活在其自己的环境中,并且其要求得到单独处理。
Flask is a web micro-framework that is built on Python. It is called a micro-framework because it does not require specific tools or plug-ins to run. The Flask framework is lightweight and flexible, yet highly structured, making it preferred over other frameworks.
Flask是基于Python构建的Web微框架。 之所以称为微框架,是因为它不需要特定的工具或插件即可运行。 Flask框架轻巧灵活,但结构高度,使其优于其他框架。
Deploying a Flask application with Docker will allow you to replicate the application across different servers with minimal reconfiguration.
使用Docker部署Flask应用程序将使您能够以最小的重新配置跨不同服务器复制应用程序。
In this tutorial, you will create a Flask application and deploy it with Docker. This tutorial will also cover how to update an application after deployment.
在本教程中,您将创建一个Flask应用程序并将其与Docker一起部署。 本教程还将介绍部署后如何更新应用程序。
先决条件 (Prerequisites)
To follow this tutorial, you will need the following:
要遵循本教程,您将需要以下内容:
A non-root user with sudo privileges configured by following the Initial Server Setup with Ubuntu 18.04 guide.
通过遵循带有Ubuntu 18.04的初始服务器设置指南配置的具有sudo特权的非root用户。
One Ubuntu 18.04 server with Docker installed, set up by following this tutorial or with the DigitalOcean one-click Docker image.
通过遵循本教程或使用DigitalOcean 一键式Docker映像来安装一台已安装Docker的Ubuntu 18.04服务器。
Nginx installed by following step one of the How To Install Nginx on Ubuntu 18.04 tutorial.
Nginx的安装由下面的步骤一个如何在Ubuntu 18.04安装Nginx的教程。
第1步-设置Flask应用程序 (Step 1 — Setting Up the Flask Application)
To get started, you will create a directory structure that will hold your Flask application. This tutorial will create a directory called TestApp
in /var/www
, but you can modify the command to name it whatever you’d like.
首先,您将创建一个包含Flask应用程序的目录结构。 本教程将在/var/www
创建一个名为TestApp
的目录,但是您可以修改命令以将其命名为任意名称。
sudo mkdir /var/www/TestApp
须藤mkdir / var / www / TestApp
Move in to the newly created TestApp
directory:
移至新创建的TestApp
目录:
cd /var/www/TestApp
cd / var / www / TestApp
Next, create the base folder structure for the Flask application:
接下来,为Flask应用程序创建基本文件夹结构:
- sudo mkdir -p app/static app/templates sudo mkdir -p应用程序/静态应用程序/模板
The -p
flag indicates that mkdir
will create a directory and all parent directories that don’t exist. In this case, mkdir
will create the app
parent directory in the process of making the static
and templates
directories.
-p
标志指示mkdir
将创建一个目录以及所有不存在的父目录。 在这种情况下, mkdir
将在创建static
目录和templates
目录的过程中创建app
父目录。
The app
directory will contain all files related to the Flask application such as its views and blueprints. Views are the code you write to respond to requests to your application. Blueprints create application components and support common patterns within an application or across multiple applications.
app
目录将包含与Flask应用程序相关的所有文件,例如其视图和蓝图 。 视图是您编写的用于响应对应用程序请求的代码。 蓝图创建应用程序组件并支持一个应用程序内或多个应用程序之间的通用模式。
The static
directory is where assets such as images, CSS, and JavaScript files live. The templates
directory is where you will put the HTML templates for your project.
static
目录是资产(例如图像,CSS和JavaScript文件)所在的位置。 templates
目录是放置项目HTML模板的位置。
Now that the base folder structure is complete, create the files needed to run the Flask application. First, create an __init__.py
file inside the app
directory. This file tells the Python interpreter that the app
directory is a package and should be treated as such.
现在基本文件夹结构已经完成,创建运行Flask应用程序所需的文件。 首先,在app
目录中创建一个__init__.py
文件。 该文件告诉Python解释器该app
目录是一个软件包,应这样对待。
Run the following command to create the file:
运行以下命令来创建文件:
- sudo nano app/__init__.py 须藤纳米应用程序/ __init__.py
Packages in Python allow you to group modules into logical namespaces or hierarchies. This approach enables the code to be broken down into individual and manageable blocks that perform specific functions.
Python中的软件包允许您将模块分组为逻辑名称空间或层次结构。 这种方法使代码可以分解为执行特定功能的单个可管理块。
Next, you will add code to the __init__.py
that will create a Flask instance and import the logic from the views.py
file, which you will create after saving this file. Add the following code to your new file:
接下来,将代码添加到__init__.py
,这将创建Flask实例并从views.py
文件导入逻辑,该文件将在保存此文件后创建。 将以下代码添加到新文件中:
from flask import Flask
app = Flask(__name__)
from app import views
Once you’ve added that code, save and close the file.
添加该代码后,保存并关闭文件。
With the __init__.py
file created, you’re ready to create the views.py
file in your app
directory. This file will contain most of your application logic.
创建__init__.py
文件后,您就可以在app
目录中创建views.py
文件了。 该文件将包含您的大多数应用程序逻辑。
- sudo nano app/views.py 须藤nano app / views.py
Next, add the code to your views.py
file. This code will return the hello world!
string to users who visit your web page:
接下来,将代码添加到您的views.py
文件中。 此代码将返回hello world!
访问您网页的用户的字符串:
from app import app
@app.route('/')
def home():
return "hello world!"
The @app.route
line above the function is called a decorator. Decorators modify the function that follows it. In this case, the decorator tells Flask which URL will trigger the home()
function. The hello world
text returned by the home
function will be displayed to the user on the browser.
函数上方的@app.route
行称为装饰器 。 装饰器修改其后的功能。 在这种情况下,装饰器告诉Flask哪个URL将触发home()
函数。 由home
函数返回的hello world
文本将在浏览器上显示给用户。
With the views.py
file in place, you’re ready to create the uwsgi.ini
file. This file will contain the uWSGI configurations for our application. uWSGI is a deployment option for Nginx that is both a protocol and an application server; the application server can serve uWSGI, FastCGI, and HTTP protocols.
放置views.py
文件后,就可以创建uwsgi.ini
文件了。 该文件将包含我们应用程序的uWSGI配置。 uWSGI是Nginx的部署选项,既是协议又是应用程序服务器。 应用服务器可以服务uWSGI,FastCGI和HTTP协议。
To create this file, run the following command:
要创建此文件,请运行以下命令:
- sudo nano uwsgi.ini 须藤纳米uwsgi.ini
Next, add the following content to your file to configure the uWSGI server:
接下来,将以下内容添加到您的文件中以配置uWSGI服务器:
[uwsgi]
module = main
callable = app
master = true
This code defines the module that the Flask application will be served from. In this case, this is the main.py
file, referenced here as main
. The callable
option instructs uWSGI to use the app
instance exported by the main application. The master
option allows your application to keep running, so there is little downtime even when reloading the entire application.
这段代码定义了将向Flask应用程序提供服务的模块。 在这种情况下,这是main.py
文件,在此称为main
。 callable
选项指示uWSGI使用主应用程序导出的app
实例。 master
选项允许您的应用程序继续运行,因此即使重新加载整个应用程序,停机时间也很少。
Next, create the main.py
file, which is the entry point to the application. The entry point instructs uWSGI on how to interact with the application.
接下来,创建main.py
文件,这是应用程序的入口点。 入口点指示uWSGI如何与应用程序进行交互。
- sudo nano main.py 须藤nano main.py
Next, copy and paste the following into the file. This imports the Flask instance named app
from the application package that was previously created.
接下来,将以下内容复制并粘贴到文件中。 这将从先前创建的应用程序包中导入名为app
的Flask实例。
from app import app
Finally, create a requirements.txt
file to specify the dependencies that the pip
package manager will install to your Docker deployment:
最后,创建一个requirements.txt
文件以指定pip
软件包管理器将安装到Docker部署的依赖项:
- sudo nano requirements.txt 须藤纳米需求.txt
Add the following line to add Flask as a dependency:
添加以下行以将Flask添加为依赖项:
Flask==1.0.2
This specifies the version of Flask to be installed. At the time of writing this tutorial, 1.0.2
is the latest Flask version. You can check for updates at the official website for Flask.
这指定了要安装的Flask的版本。 在编写本教程时,最新的Flask版本是1.0.2
。 您可以在Flask的官方网站上查看更新。
Save and close the file. You have successfully set up your Flask application and are ready to set up Docker.
保存并关闭文件。 您已经成功设置了Flask应用程序,并准备设置Docker。
第2步-设置Docker (Step 2 — Setting Up Docker)
In this step you will create two files, Dockerfile
and start.sh
, to create your Docker deployment. The Dockerfile
is a text document that contains 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 the Dockerfile
.
在此步骤中,您将创建两个文件Dockerfile
和start.sh
,以创建您的Docker部署。 Dockerfile
是一个文本文档,其中包含用于组装映像的命令。 start.sh
文件是一个Shell脚本,它将通过Dockerfile
构建映像并创建容器。
First, create the Dockerfile
.
首先,创建Dockerfile
。
- sudo nano Dockerfile 须藤Nano Dockerfile
Next, add your desired configuration to the Dockerfile
. These commands specify how the image will be built, and what extra requirements will be included.
接下来,将所需的配置添加到Dockerfile
。 这些命令指定如何构建映像以及将包括哪些额外要求。
FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7
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 off an existing image, tiangolo/uwsgi-nginx-flask
, which you can find on DockerHub. This particular Docker image is a good choice over others because it supports a wide range of Python versions and OS images.
在此示例中,Docker映像将基于现有映像tiangolo/uwsgi-nginx-flask
构建 ,您可以在DockerHub上找到它 。 这个特定的Docker映像是一个很好的选择,因为它支持广泛的Python版本和OS映像。
The first two lines specify the parent image that you’ll use to run the application and install the bash command processor and the nano
text editor. It also installs the git
client for pulling and pushing to version control hosting services such as GitHub, GitLab, and Bitbucket. ENV STATIC_URL /static
is an environment variable specific to this Docker image. It defines the static folder where all assets such as images, CSS files, and JavaScript files are served from.
前两行指定用于运行应用程序并安装bash命令处理器和nano
文本编辑器的父映像。 它还安装了git
客户端,用于拉入和推送到版本控制托管服务,例如GitHub,GitLab和Bitbucket。 ENV STATIC_URL /static
是特定于此Docker映像的环境变量。 它定义了从中提供所有资产(例如图像,CSS文件和JavaScript文件)的静态文件夹。
The last two lines will copy the requirements.txt
file into the container so that it can be executed, and then parses the requirements.txt
file to install the specified dependencies.
最后两行会的复制requirements.txt
文件放入容器中,以便它可以被执行,然后解析requirements.txt
文件安装指定的依赖关系。
Save and close the file after adding your configuration.
添加配置后,保存并关闭文件。
With your Dockerfile
in place, you’re almost ready to write your start.sh
script that will build the Docker container. Before writing the start.sh
script, first make sure that you have an open port to use in the configuration. To check if a port is free, run the following command:
放置好Dockerfile
之后,几乎可以编写用于构建Docker容器的start.sh
脚本了。 在编写start.sh
脚本之前,首先请确保您具有在配置中使用的开放端口。 要检查端口是否空闲,请运行以下命令:
sudo nc localhost 56733 < /dev/null; echo $?
sudo nc本地主机56733 </ dev / null; 回声$?
If the output of the command above is 1
, then the port is free and usable. Otherwise, you will need to select a different port to use in your start.sh
configuration file.
如果以上命令的输出为1
,则该端口是空闲且可用的。 否则,您将需要在start.sh
配置文件中选择其他端口。
Once you’ve found an open port to use, create the start.sh
script:
找到要使用的开放端口后,创建start.sh
脚本:
- sudo nano start.sh 须藤nano start.sh
The start.sh
script is a shell script that will build an image from the Dockerfile
and create a container from the resulting Docker image. Add your configuration to the new file:
start.sh
脚本是一个Shell脚本,它将根据Dockerfile
生成映像,并根据生成的Docker映像创建容器。 将配置添加到新文件:
#!/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 a shebang. It specifies that this is a bash file and will be executed as commands. The next line specifies the name you want to give the image and container and saves as a variable named app
. The next line instructs Docker to build an image from your Dockerfile
located in the current directory. This will create an image called docker.test
in this example.
第一行叫做shebang 。 它指定这是一个bash文件,将作为命令执行。 下一行指定要提供图像和容器的名称,并将其另存为名为app
的变量。 下一行指示Docker从位于当前目录中的Dockerfile
构建映像。 在此示例中,这将创建一个名为docker.test
的映像。
The last three lines create a new container named docker.test
that is exposed at port 56733
. Finally, it links the present directory to the /var/www
directory of the container.
最后三行创建一个名为docker.test
的新容器,该容器在端口56733
处公开。 最后,它将当前目录链接到容器的/var/www
目录。
You use the -d
flag to start a container in daemon mode, or as a background process. You include the -p
flag to bind a port on the server to a particular port on the Docker container. In this case, you are binding port 56733
to port 80
on the Docker container. The -v
flag specifies a Docker volume to mount on the container, and in this case, you are mounting the entire project directory to the /var/www
folder on the Docker container.
您可以使用-d
标志以守护程序模式或作为后台进程启动容器。 您包含-p
标志以将服务器上的端口绑定到Docker容器上的特定端口。 在这种情况下,您将端口56733
绑定到Docker容器上的端口80
。 -v
标志指定要在容器上安装的Docker卷,在这种情况下,您要将整个项目目录安装到Docker容器上的/var/www
文件夹。
Execute the start.sh
script to create the Docker image and build a container from the resulting image:
执行start.sh
脚本以创建Docker映像并从生成的映像构建容器:
- sudo bash start.sh 须藤bash start.sh
Once the script finishes running, use the following command to list all running containers:
脚本完成运行后,使用以下命令列出所有正在运行的容器:
- sudo docker ps 须藤码头工人ps
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 find that the docker.test
container is running. Now that it is running, visit the IP address at the specified port in your browser: http://ip-address:56733
您会发现docker.test
容器正在运行。 现在它正在运行,请在浏览器中的指定端口上访问IP地址: http:// ip-address : 56733
You’ll see a page similar to the following:
您会看到类似于以下内容的页面:
In this step you have successfully deployed your Flask application on Docker. Next, you will use templates to display content to users.
在此步骤中,您已成功在Docker上部署了Flask应用程序。 接下来,您将使用模板向用户显示内容。
步骤3 —提供模板文件 (Step 3 — Serving Template Files)
Templates are files that display static and dynamic content to users who visit your application. In this step, you will create a HTML template to create a home page for the application.
模板是向访问您的应用程序的用户显示静态和动态内容的文件。 在此步骤中,您将创建一个HTML模板来为该应用程序创建一个主页。
Start by creating a home.html
file in the app/templates
directory:
首先在app/templates
目录中创建一个home.html
文件:
- sudo nano app/templates/home.html 须藤纳米应用程序/模板/ home.html
Add the code for your template. This code will create an HTML5 page that contains a title and some text.
添加您的模板的代码。 这段代码将创建一个HTML5页面,其中包含标题和一些文本。
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Welcome home</title>
</head>
<body>
<h1>Home Page</h1>
<p>This is the home page of our application.</p>
</body>
</html>
Save and close the file once you’ve added your template.
添加模板后,保存并关闭文件。
Next, modify the app/views.py
file to serve the newly created file:
接下来,修改app/views.py
文件以提供新创建的文件:
- sudo nano app/views.py 须藤nano app / views.py
First, add the following line at the beginning of your file to import the render_template
method from Flask. This method parses an HTML file to render a web page to the user.
首先,在文件开头添加以下行,以从Flask导入render_template
方法。 此方法解析HTML文件,以将网页呈现给用户。
from flask import render_template
...
At the end of the file, you will also add a new route to render the template file. This code specifies that users are served the contents of the home.html
file whenever they visit the /template
route on your application.
在文件末尾,您还将添加一条新路径来渲染模板文件。 这段代码指定当用户访问应用程序上的/template
路由时,就会向他们提供home.html
文件的内容。
...
@app.route('/template')
def template():
return render_template('home.html')
The updated app/views.py
file will look like this:
更新后的app/views.py
文件将如下所示:
from flask import render_template
from app import app
@app.route('/')
def home():
return "Hello world!"
@app.route('/template')
def template():
return render_template('home.html')
Save and close the file when done.
完成后保存并关闭文件。
In order for these changes to take effect, you will need to stop and restart the Docker containers. Run the following command to rebuild the container:
为了使这些更改生效,您将需要停止并重新启动Docker容器。 运行以下命令来重建容器:
sudo docker stop docker.test && sudo docker start docker.test
sudo docker停止docker.test && sudo docker启动docker.test
Visit your application at http://your-ip-address:56733/template
to see the new template being served.
访问您的应用程序, http:// your-ip-address :56733/template
为http:// your-ip-address :56733/template
以查看正在提供的新模板。
In this you’ve created a Docker template file to serve visitors on your application. In the next step you will see how the changes you make to your application can take effect without having to restart the Docker container.
在此,您创建了一个Docker模板文件来为应用程序中的访问者提供服务。 在下一步中,您将看到对应用程序所做的更改如何生效而无需重新启动Docker容器。
第4步-更新应用程序 (Step 4 — Updating the Application)
Sometimes you will need to make changes to the application, whether it is installing new requirements, updating the Docker container, or HTML and logic changes. In this section, you will configure touch-reload
to make these changes without needing to restart the Docker container.
有时您需要对应用程序进行更改,无论是安装新需求,更新Docker容器还是HTML和逻辑更改。 在本部分中,您将配置touch-reload
以进行这些更改,而无需重新启动Docker容器。
Python autoreloading watches the entire file system for changes and refreshes the application when it detects a change. Autoreloading is discouraged in production because it can become resource intensive very quickly. In this step, you will use touch-reload
to watch for changes to a particular file and reload when the file is updated or replaced.
Python自动重装监视整个文件系统的更改,并在检测到更改时刷新应用程序。 不鼓励在生产中使用自动重装,因为它会很快占用大量资源。 在此步骤中,您将使用touch-reload
监视特定文件的更改,并在更新或替换文件时重新加载。
To implement this, start by opening your uwsgi.ini
file:
要实现此目的, uwsgi.ini
打开uwsgi.ini
文件:
- sudo nano uwsgi.ini 须藤纳米uwsgi.ini
Next, add the highlighted line to the end of the file:
接下来,将突出显示的行添加到文件末尾:
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini
This specifies a file that will be modified to trigger an entire application reload. Once you’ve made the changes, save and close the file.
这指定了将被修改以触发整个应用程序重新加载的文件。 进行更改后,保存并关闭文件。
To demonstrate this, make a small change to your application. Start by opening your app/views.py
file:
为了演示这一点,请对您的应用程序进行一些小的更改。 首先打开您的app/views.py
文件:
- sudo nano app/views.py 须藤nano app / views.py
Replace the string returned by the home
function:
替换home
函数返回的字符串:
from flask import render_template
from app import app
@app.route('/')
def home():
return "<b>There has been a change</b>"
@app.route('/template')
def template():
return render_template('home.html')
Save and close the file after you’ve made a change.
进行更改后,保存并关闭文件。
Next, if you open your application’s homepage at http://ip-address:56733
, you will notice that the changes are not reflected. This is because the condition for reload is a change to the uwsgi.ini
file. To reload the application, use touch
to activate the condition:
接下来,如果您在http:// ip-address : 56733
打开应用程序的主页,您将注意到所做的更改未得到反映。 这是因为重新加载的条件是对uwsgi.ini
文件的更改。 要重新加载应用程序,请使用touch
激活条件:
- sudo touch uwsgi.ini 须藤触摸uwsgi.ini
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 changes.
在此步骤中,您设置了touch-reload
条件,以在进行更改后更新您的应用程序。
结论 (Conclusion)
In this tutorial, you created and deployed a Flask application to a Docker container. You also configured touch-reload
to refresh your application without needing to restart the container.
在本教程中,您创建了Flask应用程序并将其部署到Docker容器。 您还配置了touch-reload
来刷新应用程序,而无需重新启动容器。
With your new application on Docker, you can now scale with ease. To learn more about using Docker, check out their official documentation.
通过Docker上的新应用程序,您现在可以轻松扩展。 要了解有关使用Docker的更多信息,请查看其官方文档 。