1. 概述
在使用 Docker 时,通过 Gunicorn 运行应用可以显著提升应用的可扩展性和性能,特别是在部署 Flask 应用时。然而,从直接使用 flask run
启动 Flask 应用,过渡到使用 Gunicorn 启动,可能会遇到一些挑战。
本教程将逐步讲解如何在 Docker 中运行 Gunicorn 服务器。
2. Gunicorn 简介
Gunicorn 是一个 Python WSGI HTTP 服务器,可以高效运行 Flask、Django 或其他 Python Web 应用。
Flask 自带的开发服务器是单线程的,不适合用于生产环境。而 Gunicorn 支持多进程处理请求,能够显著提升并发性能。
Docker 则提供了一个隔离的运行环境,使我们可以将应用及其依赖打包在一起,确保不同环境之间的一致性。
因此,将 Gunicorn 与 Docker 结合使用,可以让 Flask 应用在生产环境中高效运行。
3. 在 Docker 中配置 Gunicorn
在本节中,我们将创建一个简单的项目,演示如何在 Docker 中设置并运行 Gunicorn。
3.1. 创建 Flask 应用
首先,我们创建一个简单的 Flask 应用:
from flask import Flask, request, jsonify
app = Flask(__name__)
default_message = "Hello, this is a Flask app running on Gunicorn inside Docker!"
@app.route('/', methods=['GET'])
def home():
return jsonify({"message": default_message})
if __name__ == "__main__":
app.run(debug=False, host='0.0.0.0', port=8080)
我们把这个文件命名为 flaskfile.py。虽然我们保留了 app.run()
用于本地测试,但在 Docker 中我们使用 Gunicorn 作为主服务器。
3.2. 创建 Dockerfile
接下来,在与 Flask 应用同一目录下创建 Dockerfile,并添加以下内容:
# 使用官方 Python 镜像作为基础镜像
FROM python:3.9
# 设置容器内的工作目录
WORKDIR /code
# 将本地文件复制到容器中
COPY . /code
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 暴露 8080 端口
EXPOSE 8080
# 启动 Gunicorn,使用 4 个 worker 并监听 8080 端口
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8080", "flaskfile:app"]
各指令说明如下:
FROM python:3.9
:指定基础镜像WORKDIR /code
:设置容器内的工作目录COPY . /code
:复制本地文件到容器RUN pip install --no-cache-dir -r requirements.txt
:安装依赖EXPOSE 8080
:暴露容器的 8080 端口CMD ["gunicorn", ...]
:启动 Gunicorn,flaskfile:app
表示从 flaskfile.py 中导入app
实例
3.3. 创建 requirements.txt
确保在同一目录下创建 requirements.txt 文件,内容如下:
flask
gunicorn
这将确保构建镜像时安装所需的依赖。
3.4. 构建并运行容器
构建镜像:
$ docker build -t my_flask_app .
运行容器:
$ docker run -it -p 8080:8080 my_flask_app
参数说明:
-it
:以交互模式运行容器-p 8080:8080
:将宿主机的 8080 映射到容器的 8080my_flask_app
:使用的镜像名称
3.5. 验证应用是否正常运行
使用 curl
测试接口:
$ curl http://localhost:8080/
{"message":"Hello, this is a Flask app running on Gunicorn inside Docker!"}
✅ 应该能正常返回 JSON 响应。
4. 最佳实践(适用于生产环境)
以下是一些适用于生产环境的建议:
✅ 启用 Gunicorn 日志记录
添加 --access-logfile
参数,将访问日志输出到标准输出:
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8080", "--access-logfile", "-", "flaskfile:app"]
✅ 使用反向代理进行负载均衡
对于大型项目,可以在多个 Gunicorn 容器前部署 Nginx 做负载均衡。
✅ 使用环境变量配置参数
避免在 Dockerfile 中硬编码配置项(如端口、worker 数量),可使用 .env
文件配合 docker run
的 --env-file
参数。
5. 常见问题与排查建议
问题 1:端口冲突
如果你本地的 8080 端口已被占用,可以映射其他端口:
$ docker run -it -p 5000:8080 my_flask_app
这样访问地址变为 http://localhost:5000/
问题 2:Gunicorn worker 超时
如果某个请求处理时间过长,worker 可能被强制终止。可以通过设置超时时间解决:
CMD ["gunicorn", "-w", "4", "-t", "60", "-b", "0.0.0.0:8080", "--access-logfile", "-", "flaskfile:app"]
上面的 -t 60
表示每个请求最多处理 60 秒。
问题 3:应用导入失败
确保 flaskfile.py
中的 app
实例是在顶层定义的:
from flask import Flask
app = Flask(__name__)
⚠️ 如果 app
是在函数内部或其他作用域中定义的,Gunicorn 将无法正确导入,导致启动失败。
6. 总结
本文讲解了如何在 Docker 中运行 Gunicorn 服务器,并结合 Flask 应用演示了整个流程。
通过 Gunicorn 与 Docker 的结合,我们可以高效地部署 Python Web 应用,使其具备生产级的并发处理能力和环境一致性。
✅ 使用 Gunicorn 作为 WSGI 服务器,结合 Docker 容器化部署,是现代 Python Web 应用部署的主流方式之一。