如何在Ubuntu 18.04上使用Docker构建和部署Flask应用程序

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:

要遵循本教程,您将需要以下内容:

第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文件导入逻辑,该文件将在保存此文件后创建。 将以下代码添加到新文件中:

/var/www/TestApp/app/__init__.py
/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.

添加该代码后,保存并关闭文件。

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! 访问您网页的用户的字符串:

/var/www/TestApp/app/views.py
/var/www/TestApp/app/views.py
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服务器:

/var/www/TestApp/uwsgi.ini
/var/www/TestApp/uwsgi.ini
[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文件,在此称为maincallable选项指示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实例。

/var/www/TestApp/main.py
/var/www/TestApp/main.py
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添加为依赖项:

/var/www/TestApp/requirements.txt
/var/www/TestApp/requirements.txt
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.

在此步骤中,您将创建两个文件Dockerfilestart.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 。 这些命令指定如何构建映像以及将包括哪些额外要求。

/var/www/TestApp/Dockerfile
/ var / www / TestApp / 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映像创建容器。 将配置添加到新文件:

/var/www/TestApp/start.sh
/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 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页面,其中包含标题和一些文本。

/var/www/TestApp/app/templates/home.html
/var/www/TestApp/app/templates/home.html
<!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文件,以将网页呈现给用户。

/var/www/TestApp/app/views.py
/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 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文件的内容。

/var/www/TestApp/app/views.py
/var/www/TestApp/app/views.py
...

@app.route('/template')
def template():
    return render_template('home.html')

The updated app/views.py file will look like this:

更新后的app/views.py文件将如下所示:

/var/www/TestApp/app/views.py
/var/www/TestApp/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/templatehttp:// 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:

接下来,将突出显示的行添加到文件末尾:

/var/www/TestApp/uwsgi.ini
/var/www/TestApp/uwsgi.ini
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函数返回的字符串:

/var/www/TestApp/app/views.py
/var/www/TestApp/app/views.py
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的更多信息,请查看其官方文档

翻译自: https://www.digitalocean.com/community/tutorials/how-to-build-and-deploy-a-flask-application-using-docker-on-ubuntu-18-04

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值