docker镜像环境下部署 uWSGI + nginx + flask
- flask 一个用Python编写的轻量级Web应用框架,它被设计为易于扩展和简单易用,适合于快速开发小型到中型的Web应用。(官网,中文网,github)
- uWSGI uWSGI是一个应用服务器,它实现了WSGI协议并提供了高性能的Web应用程序托管环境。它支持多种协议,包括HTTP、FastCGI、SCGI等,使得Python应用程序可以与不同类型的Web服务器通信。(官网,github)
- nginx 一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名.(官网,中文文档,github)
环境
Ubuntu 22
安装docker环境
代码语言:txt复制apt-get update && apt install docker.io
配置docker镜像加速
代码语言:txt复制vim /etc/docker/daemon.json
{
"registry-mirrors": [
";,
";,
";,
";
]
}
加载配置,运行docker
代码语言:txt复制#重载配置
systemctl daemon-reload
#重启docker
systemctl restart docker
#设置开机自启命令
systemctl enable docker
构建镜像
创建一个自定义目录,并在该目录下创建以下目录及文件
代码语言:txt复制mkdir -p /home/flask && cd /home/flask && mkdir -p app logs conf
#### 目录结构
├── app
│ ├── app.py # 项目入口文件
│ └── requirements.txt # 项目上需要的python依赖组件
├── conf
│ └── debian.sources
│ └── uwsgi.ini # uwsgi 服的配置文件
│ └── nginx.conf # nginx 服务配置文件
├── Dockerfile
├── logs # 日志目录
app.py
代码语言:txt复制import logging
from flask import Flask
app = Flask(__name__)
# 配置 Flask 日志
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('/var/log/flask_app.log'),
logging.StreamHandler()
]
)
@app.route('/')
def hello_world():
app.logger.info('Accessing the root route')
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
requirements.txt
代码语言:txt复制对应的组件也可以不用写具体版本,也可以写 >=xxx 版本;
pip
uWSGI == 2.0.28
Flask == 3.1.0
debian.sources
代码语言:txt复制这个就是系统包文件,因为下面我们用的基础镜像是debian系统,更新自动组件慢,这里换成国内镜像加速地址,不一定是huaweicloud,还有很多;
Types: deb
#
URIs:
Suites: bookworm bookworm-updates
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
Types: deb
#
URIs:
Suites: bookworm-security
Components: main
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
#### uwsgi.ini
代码语言:txt复制[uwsgi]
module = app:app
master = true
processes = 2
threads = 2
socket = 127.0.0.1:8000
vacuum = true
die-on-term = true
buffer-size = 65536
# 日志配置
logto = /var/log/uwsgi/uwsgi.log
nginx.conf
代码语言:txt复制端口选82、日志文件access-1.log 主要是为了和系统默认值区分,
server {
listen 82;
server_name _;
access_log /var/log/nginx/access-1.log;
error_log /var/log/nginx/error-1.log;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
}
注意:如果 uwsgi.ini 里是http = 127.0.0.1:8000 这种http监听,那么nginx配置这里就直接是:
location / {
proxy_pass http://127.0.0.1:8000/
}
如果是socket= 127.0.0.1:8000 这种socket监听,那么nginx配置这里就直接是:
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
}
参考:
Dockerfile
代码语言:txt复制# 使用 Python 基础镜像
FROM python:3.9-slim
# 设置非交互式前端
ENV DEBIAN_FRONTEND=noninteractive
# 设置工作目录
WORKDIR /app
# 更新镜像源
COPY conf/debian.sources /etc/apt/sources.list.d/debian.sources
# 复制其他项目文件
COPY app/ .
COPY conf/uwsgi.ini /etc/uwsgi/uwsgi.ini
COPY conf/nginx.conf /etc/nginx/conf.d/app.conf
# 安装 Nginx 和编译工具
# 创建日志目录和日志文件并给 www-data:www-data
# 安装 requirements.txt 文件里的组件
RUN apt-get update && apt-get install -y gcc \
&& apt install -y net-tools curl vim procps iputils-ping \
&& apt-get install -y --fix-broken -o Dpkg::Options::="--force-confnew" nginx \
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/log/nginx /var/log/uwsgi \
&& touch /var/log/flask_app.log \
&& chown -R www-data:www-data /var/log/uwsgi/ /var/log/nginx/ \
&& pip install -i --upgrade --no-cache-dir -r requirements.txt
# 暴露端口
EXPOSE 80
# 启动服务
CMD ["sh", "-c", "nginx -t && service nginx start && uwsgi --ini /etc/uwsgi/uwsgi.ini"]
代码语言:txt复制注意:安装nginx的时候 -o Dpkg::Options::="--force-confnew" 带了这个参数,是因为如果不带它会一直报如下错误:
5.208 dpkg: dependency problems prevent configuration of nginx:
5.208 nginx depends on nginx-common (<< 1.22.1-9.1~); however:
5.208 Package nginx-common is not configured yet.
5.208 nginx depends on nginx-common (>= 1.22.1-9); however:
5.208 Package nginx-common is not configured yet.
5.208
5.208 dpkg: error processing package nginx (--configure):
5.208 dependency problems - leaving unconfigured
5.208 Setting up iproute2 (6.1.0-3) ...
5.288 Processing triggers for libc-bin (2.36-9+deb12u9) ...
5.302 Errors were encountered while processing:
5.302 nginx-common
5.302 nginx
5.309 E: Sub-process /usr/bin/dpkg returned an error code (1)
这是因为系统依赖导致的问题,网上对这个报错没有答案,测试了好多次加上如上参数ok;
- --fix-broken 该参数用于修复损坏的依赖关系。要是系统中存在一些因之前的安装、升级或卸载操作而导致依赖关系损坏的软件包,使用 --fix-broken 可以尝试修复这些问题。在安装新软件包前,apt-get 会先尝试解决已存在的依赖问题,之后再进行新软件包的安装。
- Dpkg::Options::="--force-confnew" 表示当安装或升级软件包时,如果遇到配置文件有更新的情况,强制使用新的配置文件(confnew)替换旧的配置文件。这意味着系统会采用软件包提供的最新配置,而不是保留你之前手动修改过的旧配置文件。
构建镜像
代码语言:txt复制docker build -t my-flask-app .
运行容器
代码语言:txt复制docker run -d -p 80:82 -v ./logs/:/var/log/nginx -v ./logs/:/var/log/uwsgi -v ./logs/:/var/log my-flask-app
公网访问