构建flask docker镜像时分配端口

时间:2021-02-18 22:37:23

标签: docker flask docker-image

我最近使用 Flask 创建了一个应用程序,并将 py 文件放在一个 docker 容器中。但是,我对人们分配端口的在线案例感到困惑。

首先在我写的py文件的底部

if __name__ == "__main__":

app.run(host='0.0.0.0',port=8000, debug=True)

在某些情况下,我看到人们在制作 dockerfile 时在 CMD 中指定端口

CMD ["python3", "app.py", "--host=0.0.0.0", "--port=8000"]

根据我自己的经验,在 CMD 中分配的端口根本不适用于我的情况。我希望了解这两种方法之间的差异以及何时使用每种方法。

2 个答案:

答案 0 :(得分:2)

关于这种方法:

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

__name__ 等于 "__main__" 当应用程序直接使用 python 解释器启动时(使用命令 python app.py 执行) - 这是一个 python 技术,没有什么用烧瓶做。在这种情况下,调用 app.run 函数,它接受所述的各种参数。 app.run 使 Werkzeug 开发服务器运行。

这个块将被运行,如果你使用生产 WSGI 服务器执行程序,比如 gunicorn 因为 __name__ 将不等于 {{1}在这种情况下,"__main__" 调用被绕过。

实际上,将 app.run 调用放在此 app.run 块中意味着您可以使用 if 运行开发服务器,并避免在使用 {{ 导入相同代码时运行开发服务器1}} 或类似的生产。


有很多参考上述方法的较旧的教程或帖子。现代版本的 Flask 附带了 python app.py 命令,旨在取代它。所以基本上没有那个 gunicorn,您可以启动开发服务器,以类似于 flask 的方式导入您的应用程序对象:

if

这会自动在 gunicorn 中查找名为 flask run -h 0.0.0.0 -p 8000 的对象,并接受主机和端口选项,如您在 app 中所见:

app.py

这种方法的一个优点是,如果您使用自动重新加载器并引入语法错误,开发服务器不会崩溃。当然,相同的代码将与 flask run --help 之类的生产服务器兼容。


考虑到上述情况,关于您传递的命令:

Options:
  -h, --host TEXT                 The interface to bind to.
  -p, --port INTEGER              The port to bind to.

我不确定您是否对 gunicorn 命令支持的选项的引用感到困惑,但是要使该选项起作用,您需要手动编写一些代码来使用这些选项执行某些操作。这可以通过像 python app.py --host=0.0.0.0 --port=8000 这样的 python 模块来完成,但鉴于 flask 命令实际上支持开箱即用,这可能是多余的。

总结:您可能应该删除 argparse 块,并且您的 Dockerfile 应该包含:

flask

您可能还希望检查 if 环境变量 is setCMD ["flask", "run", "--host=0.0.0.0", "--port=8000"] 以使用自动重新加载器,并注意需要更改 FLASK_ENV 行在此 Dockerfile 中与 development 或类似产品一起运行,但这可能超出了本问题的范围。

答案 1 :(得分:1)

CMD ["python3", "app.py", "--host=0.0.0.0", "--port=8000"] 表示:Python 运行应用程序 app.py 并将 --host 和 --port 参数传递给该应用程序。由您的 app.py 对这些参数进行处理。如果您的应用不处理这些标志,则您无需将它们添加到 CMD。

如果您的代码中有 app.run(host='0.0.0.0',port=8000),那么您的应用程序将始终侦听容器内的端口 8000。在这种情况下,您可以只使用 CMD ["python3", "app.py"]

如果您希望能够更改应用程序正在侦听的端口和主机,您可以添加一些代码来从命令行读取值。一旦您将应用设置为从命令行查看值,就可以运行 CMD ["python3", "app.py", "--host=0.0.0.0", "--port=8000"]