在Docker中安装uWSGI
2017-06-28 15:45:02 +08 字数:1542 标签: Docker uWSGI简介 ¶
uWSGI是一个由unbit提供的Web应用服务器,实现了WSGI规范。
由于主题是C语言,所以在利用pip install uWSGI
来安装时,需要配置编译环境。
在Alpine中尝试安装 ¶
由于直接写Dockerfile时失败了,并且错误提示不足。
于是,孤跑了一个python:2.7.13-alpine
的Docker容器,然后尝试安装uWSGI。
$ docker run --rm -it python:2.7.13-alpine sh
以下开始试错。
gcc ¶
直接执行pip install uWSGI
,得到近百行的错误提示。
其中有用的部分如下:
File "uwsgiconfig.py", line 742, in __init__
raise Exception("you need a C compiler to build uWSGI")
Exception: you need a C compiler to build uWSGI
这表明,需要安装一个C编译器。 由于是首次安装软件,需要先更新源。
apk update
apk add gcc
这步是比较耗时的,约10分钟,具体取决于网速。
这也是为什么,孤选择不直接通过build一个Dockerfile来试错。
libc-dev ¶
安装gcc后,再执行pip install uWSGI
,关键错误如下:
In file included from core/socket.c:1:0:
./uwsgi.h:165:19: fatal error: stdio.h: No such file or directory
compilation terminated.
In file included from core/logging.c:2:0:
./uwsgi.h:165:19: fatal error: stdio.h: No such file or directory
compilation terminated.
In file included from core/utils.c:1:0:
./uwsgi.h:165:19: fatal error: stdio.h: No such file or directory
compilation terminated.
In file included from core/protocol.c:1:0:
./uwsgi.h:165:19: fatal error: stdio.h: No such file or directory
compilation terminated.
连stdio.h
都没有,这当然是缺乏C语言的标准库所致。
apk add libc-dev
linux-headers ¶
再来,关键错误如下:
In file included from core/logging.c:2:0:
./uwsgi.h:238:26: fatal error: linux/limits.h: No such file or directory
compilation terminated.
In file included from core/utils.c:1:0:
./uwsgi.h:238:26: fatal error: linux/limits.h: No such file or directory
compilation terminated.
In file included from core/protocol.c:1:0:
./uwsgi.h:238:26: fatal error: linux/limits.h: No such file or directory
compilation terminated.
In file included from core/socket.c:1:0:
./uwsgi.h:238:26: fatal error: linux/limits.h: No such file or directory
compilation terminated.
虽然有了C的标准库,但是缺乏Linux相关的头文件。
apk add linux-headers
这也是最后一个必要的编译依赖了。
此后,pip install uWSGI
顺利完成。
运行问题 ¶
编译有依赖,运行也有依赖。 二者通常是不同的,而后者通常是前者的子集。
由于三个模块都是编译用的,所以编译完成后可以删除。
而如果删除了编译依赖,运行时会出现问题。
Error loading shared library libuuid.so.1: No such file or directory (needed by /usr/local/bin/uwsgi) Error relocating /usr/local/bin/uwsgi: uuid_unparse: symbol not found Error relocating /usr/local/bin/uwsgi: uuid_generate: symbol not found
所幸,加上libuuid就没问题了。
其它问题 ¶
由于uWSGI功能众多,所以,使用的参数不同,需要的功能也会有差异。
在使用--static-map
等参数时,可能会有额外的编译依赖,否则会有运行时报错。
pcre-dev ¶
!!! no internal routing support, rebuild with pcre support !!!
PCRE(Perl Compatible Regular Expressions)是一个Perl库,包括 perl 兼容的正则表达式库。
编译依赖为pcre-dev,运行依赖为pcre。
mailcap ¶
!!! no /etc/mime.types file found !!!
运行时,某些功能需要访问/etc/mime.types
文件。
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。 是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
这个东西对应的Alpine库是mailcap。
Dockerfile(部分) ¶
FROM python:2.7.15-alpine
RUN apk update && apk add \
libuuid \
pcre \
mailcap \
gcc \
libc-dev \
linux-headers \
pcre-dev \
&& pip install --no-cache-dir uWSGI>=2.0.15 \
&& apk del \
gcc \
libc-dev \
linux-headers \
&& rm -rf /tmp/*
总结 ¶
对一个纯净的Alpine来说,uWSGI有gcc、libc、linux-headers三个编译依赖。
编译完成后如果删除依赖,则还需要一个运行时依赖libuuid。
通过上述方法,可以更快的确定这一点,做出更好的Docker镜像。
如果使用Debian作为基础镜像,过程会简单一些,因为镜像自带的库比较全。 但是,镜像文件就大多了。
另附 ¶
由于有部分Python库,无法在Alpine上使用,比如opencv-python。 原因是,Alpine的libc不是GNU的,而是musl libc。 详见:Cannot install opencv-contrib-python from Alpine Linux · Issue #75 · skvark/opencv-python。
I completely forgot that Alpine Linux is based on musl libc and not on GNU libc and thus it’s not a GNU/Linux distribution. Manylinux supports only GNU/Linux.
因此,基于Debian的镜像,有时也是必须的。
好在slim
版的镜像也不大。
以下就是一个基于python:3.5.6-slim-stretch
,安装uWSGI的示例。
FROM python:3.5.6-slim-stretch
# Install uWSGI
RUN apt-get update && apt-get install -y \
libc6-dev \
gcc \
mime-support \
&& pip install --no-cache-dir uWSGI>=2.0.15 \
&& apt-get remove -y \
gcc \
libc6-dev \
&& rm -rf /var/lib/apt/lists/*