构建 Flask docker 镜像时分配端口

问题描述 投票:0回答:3

我最近使用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 中分配的端口根本不适用于我的情况。我想了解这两种方法之间的区别以及何时使用每种方法。

docker flask docker-image
3个回答
6
投票

关于这种方法:

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

__name__

 解释器(使用命令 
"__main__"
 执行)直接启动应用程序时,
python
等于
python app.py
- 这是 python 技术细节,与 Flask 无关。在这种情况下,
app.run
函数被调用,并且它接受所述的各种参数。
app.run
使 Werkzeug 开发服务器运行。

这个块将 not 被运行,如果你正在使用像

gunicorn
这样的生产 WSGI 服务器执行程序,因为在这种情况下
__name__
将不等于
"__main__"
,所以
app.run
调用被绕过.

在实践中,将

app.run
调用放在这个
if
块中意味着您可以使用
python app.py
运行开发服务器,并避免在
gunicorn
或生产中的类似代码导入相同代码时运行开发服务器。


有很多参考上述方法的旧教程或帖子。 Flask 的现代版本带有

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

我不确定您是否对

flask
命令支持的选项的引用感到困惑,但要使其正常工作,您需要手动编写一些代码来对这些选项进行操作。这可以通过像
argparse
这样的 python 模块来完成,但是鉴于
flask
命令实际上支持开箱即用,这可能是多余的。

总而言之:您应该删除

if
块,并且您的 Dockerfile 应该包含:

CMD ["flask", "run", "--host=0.0.0.0", "--port=8000"]

您可能还希望检查

FLASK_ENV
环境变量 设置
development
以使用自动重新加载程序,并注意需要在此 Dockerfile 中更改
CMD
行以使用
gunicorn
运行或类似的生产,但这可能超出了这个问题的范围。


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"]

就有意义了

0
投票

我在我的烧瓶应用程序中做了以下更改,它开始工作了。

烧瓶应用:

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

Docker文件:

# Base image
FROM python:3.9-slim-buster

# Set the working directory
WORKDIR /app

# Copy the requirements file
COPY requirements.txt .

# Install dependencies
RUN pip3 install -r requirements.txt

# Copy the application code
COPY . .

# Expose the application port
EXPOSE 5000

# Start the application
CMD ["python3", "app.py"]
© www.soinside.com 2019 - 2024. All rights reserved.