Nowadays, putting shiny new applications in containers seems to be the way of the future and for good reason. They offer platform portability, hardware efficiency and enhanced security. In this tutorial, we are going to take a very simple Flask API, put it in a Docker container and then test it out using Postman.

如今,将闪亮的新应用程序放入容器中似乎是未来的方式,并且有充分的理由。 它们提供平台可移植性,硬件效率和增强的安全性。 在本教程中,我们将使用一个非常简单的Flask API,将其放入Docker容器中,然后使用Postman对其进行测试。

To start off, we need to get a few things set up. Below, I created a small API just to use as an example. Please keep in mind that this does not have any error handling nor utilize any authentication. It’s usage is only for demonstration purposes. I highly recommend having error handling and user authentication in your API’s.

首先,我们需要进行一些设置。 下面,我创建了一个小的API只是作为示例。 请记住,它没有任何错误处理,也没有使用任何身份验证。 它的用法仅用于演示目的。 我强烈建议您在API中进行错误处理和用户身份验证。

from flask import Flask
from flask import request
from flask import make_response
from flask import redirect
from flask_cors import CORS, cross_origin
import storage


app = Flask(__name__)
CORS(app)


@app.route('/')
def Main():
    return 'Welcome to the Test API!'


@app.route('/booklist/v1/', methods=['GET'])
def GetAll():
    if request.method == "GET":
        result = storage.GetBookList()
        return result


@app.route('/booklist/v1/', methods=['POST'])
def Insert():
    if request.method == "POST":
        book = request.args
        result = storage.InsertBook(book)
        return result


@app.route('/booklist/v1/', methods=['PUT'])
def Update():
    if request.method == "PUT":
        book = request.args
        result = storage.UpdateBook(book)
        return result


if __name__ == "__main__":
    app.run(debug = True, host = "0.0.0.0")

In the example above, App.py is the entry point for the API. Storage.py is where all our database work is done. Model.py handles the mapping for SqlAlchemy. If you are curious as to what the actual database looked like, table.md shows the create statement for our test table and attribute data types.

在上面的示例中,App.py是API的入口点。 Storage.py是我们所有数据库工作完成的地方。 Model.py处理SqlAlchemy的映射。 如果您对实际数据库的外观感到好奇,table.md会显示测试表和属性数据类型的create语句。

Once you have finished building your API and testing it (or if you are using the example above), we need to create a Dockerfile. This file lists out the instructions to build a Docker image. For the example API, the file looks like this:

完成API的构建并对其进行测试后(或者如果您使用的是上面的示例),我们需要创建一个Dockerfile。 该文件列出了构建Docker映像的说明。 对于示例API,文件如下所示:

FROM python


WORKDIR /program


COPY requirements.txt .


RUN pip3 install -r requirements.txt


COPY src/ .


CMD ["python3", "./app.py"]

The file starts out with the FROM instruction which initializes the build stage and sets the base image to python. WORKDIR creates a working directory for the container. COPY adds the requirements.txt file to the file system of the container. Remember that the requirements.txt is a list of all the python modules our API is using. The RUN instruction uses pip to look at that file and install those modules. The second COPY instruction grabs the contents of the src directory which contains our project files (App.py, Storage.py and Model.py). Lastly, the CMD instruction runs the python command on the app.py in the container.

该文件从FROM指令开始,该指令初始化构建阶段并将基础映像设置为python。 WORKDIR为容器创建一个工作目录。 COPY将requirements.txt文件添加到容器的文件系统中。 请记住,requirements.txt是我们的API使用的所有python模块的列表。 RUN指令使用pip查看该文件并安装这些模块。 第二条COPY指令获取src目录的内容,该目录包含我们的项目文件(App.py,Storage.py和Model.py)。 最后,CMD指令在容器中的app.py上运行python命令。

Now that the Dockerfile is ready to go, we can go ahead and run that build command!

既然Dockerfile已经准备就绪,我们就可以继续运行该build命令了!

sudo docker build -t api-test .

“api-test” can be whatever you want to name the image, it just has to be lowercase. A successful build will show us this:

“ api-test”可以是您要命名图像的任何名称,只需要小写即可。 成功的构建将向我们展示以下内容:




容器的ip地址与本机是一样的么 容器api_python

To verify that the image was created:

要验证是否创建了图像:

sudo docker images


容器的ip地址与本机是一样的么 容器api_python_02

Now that the image is built, we can go ahead an run it. To do so, we will use the following command:

现在已经构建了映像,我们可以继续运行它。 为此,我们将使用以下命令:

sudo docker run -d -p 5000:5000 api-test

The output of the this command will give us a Container Id.

此命令的输出将为我们提供一个容器ID。


容器的ip地址与本机是一样的么 容器api_API_03

To see that the container is in fact running:

要查看容器实际上正在运行:

sudo docker ps -a


容器的ip地址与本机是一样的么 容器api_python_04

If you’re like me and forget to fully test something before trying to run the container, you might get a status that has “Exited” in it. One that I find helpful is running this command with <CONTAINER ID OR CONTAINER NAME> being the Container Id or the Container Name that got assigned to your container when you created it. Either name or id will work just fine.

如果您像我一样,却忘记了在尝试运行容器之前对所有内容进行全面测试,则可能会得到一个状态为“已退出”的容器。 我发现有帮助的一个是运行此命令,其中<CONTAINER ID或CONTAINER NAME>是创建容器时分配给您的容器的容器ID或容器名称。 名称或ID都可以正常工作。

sudo docker logs <CONTAINER ID OR CONTAINER NAME>

Just like it says, it will show you the logs for that container and any errors that were discovered when trying to run it. Fortunately for us, our example API is in a container and running. So, let’s try and make a couple requests to it. To do so, we’ll utilize Postman. Our first request will be a simple Get request that shows the default page for the API. <HOSTNAME> is whatever the hostname or IP address your container is running on.

就像它说的那样,它将向您显示该容器的日志以及在尝试运行该容器时发现的所有错误。 对我们来说幸运的是,我们的示例API在容器中并且正在运行。 因此,让我们尝试向它提出几个请求。 为此,我们将利用Postman 。 我们的第一个请求将是一个简单的Get请求,该请求显示API的默认页面。 <HOSTNAME>是运行容器的主机名或IP地址。

http://<HOSTNAME>:5000/


This next request will query the database getting us a list of books and their authors.

下一个请求将查询数据库,为我们提供书籍及其作者的列表。

http://<HOSTNAME>:5000/booklist/v1/


容器的ip地址与本机是一样的么 容器api_Docker_05

For something a little more exciting, we can do a POST request as well:

对于更令人兴奋的事情,我们也可以执行POST请求:

http://<HOSTNAME>:5000/booklist/v1/?name=The Lord of the Rings&author=J R R Tokien


As you probably already noticed, I made a mistake when adding the authors name. You can see the mistake here when we do another GET request on the “booklist/v1/” route:

您可能已经注意到,在添加作者姓名时我犯了一个错误。 当我们在“ booklist / v1 /”路由上执行另一个GET请求时,您会在这里看到错误:


容器的ip地址与本机是一样的么 容器api_API_06

No worries, because there is a fix for this. We have a PUT request that can be utilized:

不用担心,因为有针对此的修复程序。 我们有一个可以使用的PUT请求:

http://<HOSTNAME>:5000/booklist/v1/?name=The Lord of the Rings&author=J R R Tolkien


容器的ip地址与本机是一样的么 容器api_python_07

If we take one last peak at the route “booklist/v1/” and do a GET request, this will show the full results:

如果我们在“ booklist / v1 /”路线上到达最后一个高峰并执行GET请求,则会显示完整结果:


容器的ip地址与本机是一样的么 容器api_python_08

At this point, we have gone over a couple of common HTTP requests and how they work running inside a Docker container. It really isn’t very different than if the API was running as a standalone app on a server. In our case here though, we get the benefits of the API running in a container. Therefore, there is extra security, portability and efficiency. Feel free to use the example API I provided. Cheers!

至此,我们已经介绍了几个常见的HTTP请求以及它们如何在Docker容器中运行。 与API作为服务器上的独立应用程序运行相比,这确实没有太大区别。 不过,在本例中,我们获得了在容器中运行API的好处。 因此,存在额外的安全性,可移植性和效率。 随意使用我提供的示例API。 干杯!

More documentation on Docker can be found here