为什么 uWSGI 在 Docker 无法启动?
Why does uWSGI fail to start in Docker?
我对使用 uWSGI 来服务 Python 应用程序比较陌生,我正尝试以 emperor 模式与 vassal 启动 uWSGI 进程,但每次我尝试在 [=59= 内部启动 uWSGI ] 使用以下命令(如 root
):
# /usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
我得到的回复是:
[uWSGI] getting INI configuration from /etc/uwsgi/emperor.ini
2.0.13.1
emperor.ini
配置文件如下所示:
# files/etc/uwsgi/emperor.ini
[uwsgi]
emperor = /etc/uwsgi/apps-enabled
die-on-term = true
log-date = true
而唯一的 vassal 的配置如下:
# files/etc/uwsgi/apps-enabled/application.ini
[uwsgi]
app_dir = /var/www/server
plugin = python
master = true
callable = app
chdir = %(app_dir)
mount = /=%(app_dir)/start.py
protocol = uwsgi
socket = :8079
uid = www-data
gid = www-data
buffer-size = 32768
enable-threads = true
single-interpreter = true
processes = 1
stats = 127.0.0.1:1717
(NB: 上面的文件名是根据它们相对于 Docker 文件的位置给出的,然后将它们复制到正确的位置,基本上删除前缀 files
)
目前我使用的 uWSGI Docker 图像是基于 ubuntu:trusty
基础图像构建的(虽然我已经尝试过 ubuntu:latest
和 alpine:latest
并且遇到了同样的问题),虽然我试图用主管启动 uWSGI 进程,如前所述,当直接从命令行 运行 时它也会失败。在 Docker 图像中,我使用 pip
安装 uWSGI,但也尝试使用 apt-get
得到相同的结果。
我还应该提到我已经尝试了不同版本的 uWSGI 2.0.13.1 和 1。9.something 如果有帮助的话,结果相同。
# Dockerfile
FROM ubuntu:trusty
MAINTAINER Sean Quinn "me@mail.com"
RUN apt-get update \
&& apt-get install -y \
ack-grep git nano \
supervisor \
build-essential gcc python python-dev python-pip
RUN sed -i 's/^\(\[supervisord\]\)$/\nnodaemon=true/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(\[supervisord\]\)$/\nloglevel=debug/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(files = .*\)$/;/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(\[include\]\)$/\nfiles = \/etc\/supervisor\/conf.d\/*.conf/' /etc/supervisor/supervisord.conf
ENV UWSGI_VERSION 2.0.13.1
RUN pip install uwsgi==${UWSGI_VERSION}
RUN mkdir -p /etc/uwsgi \
&& mkdir -p /etc/uwsgi/apps-available \
&& mkdir -p /etc/uwsgi/apps-enabled \
&& mkdir -p /var/log/uwsgi
COPY files/etc/supervisor/conf.d/uwsgi.conf /etc/supervisor/conf.d/uwsgi.conf
COPY files/etc/uwsgi/emperor.ini /etc/uwsgi/emperor.ini
VOLUME /etc/uwsgi/apps-enabled
VOLUME /var/www
ENTRYPOINT ["/usr/bin/supervisord"]
CMD ["-c", "/etc/supervisor/supervisord.conf"]
如前所述,supervisord
进程尝试使用以下主管配置启动 uWSGI 进程。
# files/etc/supervisor/conf.d/uwsgi.conf
[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
user=root
应用程序 Python 文件安装在 /var/www
的子目录中,应用程序 uWSGI 配置安装到 /etc/uwsgi/apps-enabled
.
奇怪的是,如果我在一个新的 Ubuntu VM(Docker 之外)上安装 supervisor 和 uWSGI,并且所有配置和文件都已就位,我可以看到 uWSGI 正确处理emperor.ini
并阅读 vassal .ini
文件。我还没有尝试将 nginx 添加到等式中,因为我想首先确保 uWSGI 正在启动并正确读取配置文件。
有什么方法可以增加日志记录或确定为什么我只看到似乎是 uWSGI 二进制文件的版本号?这就像 uWSGI 进程完全忽略了命令行选项。我觉得我错过了一些显而易见的东西。
提前感谢任何人可以提供的帮助!
tl;dr don't use UWSGI_VERSION
as an environment variable, apparently it forces uWSGI to only print the version number instead of start?
我相信我解决了我自己的问题!
在 Docker 的集线器上试验其他 uWSGI 图像后,我发现它们也 运行 陷入同样的问题,所以我开始进一步研究可能的配置问题。我尝试更改权限等。
然而我注意到当我使用jpetazzo/nsenter进入我看到uWSGI启动的运行容器时(而不是像上面突出显示的那样简单地输出uWSGI版本信息)。使用docker exec
输入时,uWSGI只会打印版本信息。玩了一会儿之后,我发现从使用 docker exec
启动的容器中发出命令 su -
我再次看到 uWSGI 启动。
经过一些检查,我发现 root
用户在一个 shell 与另一个用户之间的环境变量存在一些差异。它引导我找到 UWSGI_VERSION
环境变量,这似乎是罪魁祸首,因为删除 UWSGI_VERSION
允许 uWSGI 启动。
我修改了我的 Docker 文件以使用 UWSGI_PIP_VERSION
作为环境变量来指示要安装的 uWSGI 版本,这似乎是 UWSGI_VERSION
的安全替代方案。 YMMV.
我对使用 uWSGI 来服务 Python 应用程序比较陌生,我正尝试以 emperor 模式与 vassal 启动 uWSGI 进程,但每次我尝试在 [=59= 内部启动 uWSGI ] 使用以下命令(如 root
):
# /usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
我得到的回复是:
[uWSGI] getting INI configuration from /etc/uwsgi/emperor.ini
2.0.13.1
emperor.ini
配置文件如下所示:
# files/etc/uwsgi/emperor.ini
[uwsgi]
emperor = /etc/uwsgi/apps-enabled
die-on-term = true
log-date = true
而唯一的 vassal 的配置如下:
# files/etc/uwsgi/apps-enabled/application.ini
[uwsgi]
app_dir = /var/www/server
plugin = python
master = true
callable = app
chdir = %(app_dir)
mount = /=%(app_dir)/start.py
protocol = uwsgi
socket = :8079
uid = www-data
gid = www-data
buffer-size = 32768
enable-threads = true
single-interpreter = true
processes = 1
stats = 127.0.0.1:1717
(NB: 上面的文件名是根据它们相对于 Docker 文件的位置给出的,然后将它们复制到正确的位置,基本上删除前缀 files
)
目前我使用的 uWSGI Docker 图像是基于 ubuntu:trusty
基础图像构建的(虽然我已经尝试过 ubuntu:latest
和 alpine:latest
并且遇到了同样的问题),虽然我试图用主管启动 uWSGI 进程,如前所述,当直接从命令行 运行 时它也会失败。在 Docker 图像中,我使用 pip
安装 uWSGI,但也尝试使用 apt-get
得到相同的结果。
我还应该提到我已经尝试了不同版本的 uWSGI 2.0.13.1 和 1。9.something 如果有帮助的话,结果相同。
# Dockerfile
FROM ubuntu:trusty
MAINTAINER Sean Quinn "me@mail.com"
RUN apt-get update \
&& apt-get install -y \
ack-grep git nano \
supervisor \
build-essential gcc python python-dev python-pip
RUN sed -i 's/^\(\[supervisord\]\)$/\nnodaemon=true/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(\[supervisord\]\)$/\nloglevel=debug/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(files = .*\)$/;/' /etc/supervisor/supervisord.conf \
&& sed -i 's/^\(\[include\]\)$/\nfiles = \/etc\/supervisor\/conf.d\/*.conf/' /etc/supervisor/supervisord.conf
ENV UWSGI_VERSION 2.0.13.1
RUN pip install uwsgi==${UWSGI_VERSION}
RUN mkdir -p /etc/uwsgi \
&& mkdir -p /etc/uwsgi/apps-available \
&& mkdir -p /etc/uwsgi/apps-enabled \
&& mkdir -p /var/log/uwsgi
COPY files/etc/supervisor/conf.d/uwsgi.conf /etc/supervisor/conf.d/uwsgi.conf
COPY files/etc/uwsgi/emperor.ini /etc/uwsgi/emperor.ini
VOLUME /etc/uwsgi/apps-enabled
VOLUME /var/www
ENTRYPOINT ["/usr/bin/supervisord"]
CMD ["-c", "/etc/supervisor/supervisord.conf"]
如前所述,supervisord
进程尝试使用以下主管配置启动 uWSGI 进程。
# files/etc/supervisor/conf.d/uwsgi.conf
[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
user=root
应用程序 Python 文件安装在 /var/www
的子目录中,应用程序 uWSGI 配置安装到 /etc/uwsgi/apps-enabled
.
奇怪的是,如果我在一个新的 Ubuntu VM(Docker 之外)上安装 supervisor 和 uWSGI,并且所有配置和文件都已就位,我可以看到 uWSGI 正确处理emperor.ini
并阅读 vassal .ini
文件。我还没有尝试将 nginx 添加到等式中,因为我想首先确保 uWSGI 正在启动并正确读取配置文件。
有什么方法可以增加日志记录或确定为什么我只看到似乎是 uWSGI 二进制文件的版本号?这就像 uWSGI 进程完全忽略了命令行选项。我觉得我错过了一些显而易见的东西。
提前感谢任何人可以提供的帮助!
tl;dr don't use
UWSGI_VERSION
as an environment variable, apparently it forces uWSGI to only print the version number instead of start?
我相信我解决了我自己的问题!
在 Docker 的集线器上试验其他 uWSGI 图像后,我发现它们也 运行 陷入同样的问题,所以我开始进一步研究可能的配置问题。我尝试更改权限等。
然而我注意到当我使用jpetazzo/nsenter进入我看到uWSGI启动的运行容器时(而不是像上面突出显示的那样简单地输出uWSGI版本信息)。使用docker exec
输入时,uWSGI只会打印版本信息。玩了一会儿之后,我发现从使用 docker exec
启动的容器中发出命令 su -
我再次看到 uWSGI 启动。
经过一些检查,我发现 root
用户在一个 shell 与另一个用户之间的环境变量存在一些差异。它引导我找到 UWSGI_VERSION
环境变量,这似乎是罪魁祸首,因为删除 UWSGI_VERSION
允许 uWSGI 启动。
我修改了我的 Docker 文件以使用 UWSGI_PIP_VERSION
作为环境变量来指示要安装的 uWSGI 版本,这似乎是 UWSGI_VERSION
的安全替代方案。 YMMV.