无法在 Ubuntu 16.04 上安装 uwsgi 和 pip



我从 godaddy 那里获得了 VPS,并用 Ubuntu 16.04 构建了一台机器。我想托管一个Python(Django)应用程序。我成功安装了Nginix。不幸的是,我无法在这台机器上安装 Nginix 和 pip。

当我运行时:

sudo pip install uwsgi

我收到以下错误。

Collecting uwsgi
Downloading uwsgi-2.0.15.tar.gz (795kB)
100% |################################| 798kB 1.1MB/s
Installing collected packages: uwsgi
Running setup.py install for uwsgi ... error
Complete output from command /usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-vbfqylz9/uwsgi/setup.py';f=getattr(tokenize, 'open', open) (__file__);code=f.read().replace('rn', 'n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-5ob0jjzo-record/install-record.txt --single-version-externally-managed --compile:
/usr/lib/python3.5/distutils/dist.py:261: UserWarning: Unknown distribution option: 'descriptions'
warnings.warn(msg)
running install
using profile: buildconf/default.ini
detected include path: ['/usr/lib/gcc/x86_64-linux-gnu/5/include', '/usr/local/include', '/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed', '/usr/include/x86_64-linux-gnu', '/usr/include']
Patching "bin_name" to properly install_scripts dir
detected CPU cores: 24
configured CFLAGS: -O2 -I. -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -DUWSGI_HAS_IFADDRS -DUWSGI_ZLIB -DUWSGI_LOCK_USE_MUTEX -DUWSGI_EVENT_USE_EPOLL -DUWSGI_EVENT_TIMER_USE_TIMERFD -DUWSGI_EVENT_FILEMONITOR_USE_INOTIFY -DUWSGI_VERSION=""2.0.15"" -DUWSGI_VERSION_BASE="2" -DUWSGI_VERSION_MAJOR="0" -DUWSGI_VERSION_MINOR="15" -DUWSGI_VERSION_REVISION="0" -DUWSGI_VERSION_CUSTOM="""" -DUWSGI_YAML -DUWSGI_XML -DUWSGI_XML_EXPAT -DUWSGI_PLUGIN_DIR=""."" -DUWSGI_DECLARE_EMBEDDED_PLUGINS="UDEP(python);UDEP(gevent);UDEP(ping);UDEP(cache);UDEP(nagios);UDEP(rrdtool);UDEP(carbon);UDEP(rpc);UDEP(corerouter);UDEP(fastrouter);UDEP(http);UDEP(ugreen);UDEP(signal);UDEP(syslog);UDEP(rsyslog);UDEP(logsocket);UDEP(router_uwsgi);UDEP(router_redirect);UDEP(router_basicauth);UDEP(zergpool);UDEP(redislog);UDEP(mongodblog);UDEP(router_rewrite);UDEP(router_http);UDEP(logfile);UDEP(router_cache);UDEP(rawrouter);UDEP(router_static);UDEP(sslrouter);UDEP(spooler);UDEP(cheaper_busyness);UDEP(symcall);UDEP(transformation_tofile);UDEP(transformation_gzip);UDEP(transformation_chunked);UDEP(transformation_offload);UDEP(router_memcached);UDEP(router_redis);UDEP(router_hash);UDEP(router_expires);UDEP(router_metrics);UDEP(transformation_template);UDEP(stats_pusher_socket);" -DUWSGI_LOAD_EMBEDDED_PLUGINS="ULEP(python);ULEP(gevent);ULEP(ping);ULEP(cache);ULEP(nagios);ULEP(rrdtool);ULEP(carbon);ULEP(rpc);ULEP(corerouter);ULEP(fastrouter);ULEP(http);ULEP(ugreen);ULEP(signal);ULEP(syslog);ULEP(rsyslog);ULEP(logsocket);ULEP(router_uwsgi);ULEP(router_redirect);ULEP(router_basicauth);ULEP(zergpool);ULEP(redislog);ULEP(mongodblog);ULEP(router_rewrite);ULEP(router_http);ULEP(logfile);ULEP(router_cache);ULEP(rawrouter);ULEP(router_static);ULEP(sslrouter);ULEP(spooler);ULEP(cheaper_busyness);ULEP(symcall);ULEP(transformation_tofile);ULEP(transformation_gzip);ULEP(transformation_chunked);ULEP(transformation_offload);ULEP(router_memcached);ULEP(router_redis);ULEP(router_hash);ULEP(router_expires);ULEP(router_metrics);ULEP(transformation_template);ULEP(stats_pusher_socket);"
*** uWSGI compiling server core ***
[thread 0][x86_64-linux-gnu-gcc -pthread] core/utils.o
[thread 2][x86_64-linux-gnu-gcc -pthread] core/protocol.o
[thread 3][x86_64-linux-gnu-gcc -pthread] core/socket.o
[thread 4][x86_64-linux-gnu-gcc -pthread] core/logging.o
[thread 7][x86_64-linux-gnu-gcc -pthread] core/master.o
[thread 13][x86_64-linux-gnu-gcc -pthread] core/master_utils.o
[thread 12][x86_64-linux-gnu-gcc -pthread] core/emperor.o
[thread 5][x86_64-linux-gnu-gcc -pthread] core/notify.o
[thread 16][x86_64-linux-gnu-gcc -pthread] core/mule.o
[thread 14][x86_64-linux-gnu-gcc -pthread] core/subscription.o
[thread 10][x86_64-linux-gnu-gcc -pthread] core/stats.o
[thread 15][x86_64-linux-gnu-gcc -pthread] core/sendfile.o
[thread 1][x86_64-linux-gnu-gcc -pthread] core/async.o
[thread 21][x86_64-linux-gnu-gcc -pthread] core/master_checks.o
----------------------------------------
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-vbfqylz9/uwsgi/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('rn', 'n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-5ob0jjzo-record/install-record.txt --single-version-externally-managed --compile" 
failed with error code 1 in /tmp/pip-build-vbfqylz9/uwsgi/

这是我的 gcc 版本

Using built-in specs.
COLLECT_GCC=gcc 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.5' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)

我能够在 Amazon EC2 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 上使用

`sudo pip install uwsgi`

我在 Ubuntu 16.04 上安装uwsgi时遇到了同样的问题。康达解决了我的问题。

conda install -c conda-forge uwsgi

您可以尝试通过运行来安装 C 编译器和 python 开发文件

apt-get install build-essential python3-dev

然后尝试安装uwsgi

相关文档的链接

部署用于公共访问的 Flask 应用程序需要在应用程序前面安装一个真正的 Web 服务器。反过来,这需要一种将Web服务器链接到Flask应用程序的机制。

在这篇文章中,我们将安装uWSGI软件包,并使用它来将一个基本的Flask应用程序链接到一个Nginx服务器。作为uWSGI安装的一部分,我们将建立一个Python虚拟环境来容纳Flask应用程序和uWSGI包。

为了关注这篇文章,你应该有一个最新版本的Python和Nginx(见侧栏)。

uWSGI安装

注意:自2019年1月28日起,这些相同的说明适用于安装uWSGI版本2.0.17.1。

我们使用我的Antsle创建了一个Ubuntu 16.04安装(名为"helium"),我们在其中安装了最新版本的Python和Nginx(见侧栏)。

我们将在Python虚拟环境中安装uWSGI,因此首先我们设置一个新的虚拟环境并激活它。注意:当然,您可以在任何拥有权限的地方设置虚拟环境,但我通常的做法是将它们全部放在我的家庭帐户中,放在一个"venvs"目录下。

$ cd                       # /home/joe is the working directory
$ mkdir venvs              # directory for virtual environments
$ cd venvs                 # 
$ python3 -m venv sam      # make sam virtual environment
$ source sam/bin/activate  # activate the virtual environment

激活虚拟环境后,系统提示符将以虚拟环境的名称 - (sam) 为前缀。检查 Python 版本。接下来我们使用 -a 来检查多个 python3 安装:Ubuntu 发行版、我们的 Python 3.7.0 安装和 (sam) 虚拟环境中的 python3。

(sam) joe@helium:~/venvs$ python --version
Python 3.7.0
(sam) joe@helium:~/venvs$ which -a python3
/home/joe/venvs/sam/bin/python3
/usr/local/bin/python3
/usr/bin/python3

有了虚拟环境,我们可以安装Flask和uWSGI。注意:uWSGI安装将失败,除非您有完整的Python安装。特别是,你需要安装 python3-dev 包和 libssl-dev 包。(请参阅此帖子。

Flask和uWSGI都安装在虚拟环境中。检查版本。

(sam) joe@helium:~/alex$ pip install flask
(sam) joe@helium:~/alex$ pip install uwsgi

(sam) joe@helium:~/venvs$ which flask
/home/joe/venvs/sam/bin/flask
(sam) joe@helium:~/venvs$ flask --version
Flask 1.0.2
Python 3.7.0 (default, Oct 19 2018, 14:09:51)
[GCC 5.4.0 20160609]
(sam) joe@helium:~/venvs$ which uwsgi
/home/joe/venvs/sam/bin/uwsgi
(sam) joe@helium:~/venvs$ uwsgi --version
2.0.17.1

安装完成:这是计划

现在我们需要的一切都已安装:Python,Nginx,Flask和uWSGI。这就是我们要做的:

  1. 我们设置并运行一个简单的Flask应用程序,而无需使用Nginx或uWSGI。使用 curl 测试应用程序。

  2. 我们使用uWSGI配置文件将我们基本的Flask应用程序连接到Nginx服务器。

  3. 作为奖励,我们设置了第二个虚拟环境("西方"),其中包含所有装饰 - uWSGI,Flask应用程序,Nginx服务等 - 并同时运行这两个应用程序。

基本烧瓶应用

有许多不同的方法来构建 Flask 应用程序。我们将使用以下目录结构。

/home/joe
|
|-- /alex       (project directory)
|
| -- /paa   (application directory)
.    |
.    | -- /static  (css, js, etc.)
.    | -- /templates  (html files)
.    |
.    | -- __init__.py
.    | -- routes.py
.    | :
.    | :
|
| -- config.py
| -- run_me.py
| :
| :

对于我们将要构建的基本 Flask 应用程序来说,这种结构有点夸张,但它说明了简单应用程序的设置(意味着没有蓝图)。此外,我们还制作了一些具有人为不同名称的文件和目录,以便依赖项比大多数教程中更清晰一些。

文件:__init__.py(如下所示)

from flask import Flask
ned = Flask(__name__)
ned.config.from_object('config')

注意:ned.config.from_object() 调用中仅使用 config.py 文件的根名称(如下所示)。

文件:routes.py(如下所示)

from paa import ned
@ned.route('/')
def slash():
title = "<title>Ned's Greeting</title>"
greeting = '<span style="color: blue"><b>Howdy Doodly, Neighbor!'
return f'{title}n{greeting}n'

注意:我们的默认做法是使用单引号作为字符串,但"Ned's Greeting"中的撇号需要双引号作为标题值。

文件:run_me.py(如下所示)

from paa import ned
from paa import routes
if __name__ == '__main__':
ned.run()

注意:Flask 默认在地址 localhost:5000 为应用程序提供服务,除非在 "ned.run()" 语句中指定了其他主机和端口。正如你稍后将看到的,在这个例子中使用uWSGI和Nginx时不需要这些参数。

文件:config.py(如下所示)

SECRET_KEY = 'ivegotasecret'

为了完整起见,我们在此处包含一个 Flask SECRET_KEY配置值。在上面显示的示例中,这不是必需的。但是,在任何真正的Flask应用程序(使用Nginx和uWSGI)中,您将在某个时候使用"session"对象,除非您设置了SECRET_KEY配置值,否则您无法这样做。有关 Flask "session" 对象的完整描述,请参阅此 StackOverflow 问题/答案。

烧瓶开发环境中的测试瓶应用

为了使用 curl 命令测试 Flask 应用程序,我们需要有两个终端会话 - 一个用于执行 Flask 应用程序,另一个用于执行 curl 命令。

要运行 Flask 应用程序,请在 .../alex 目录中设置:

(sam) joe@helium:~/alex$ export FLASK_APP=run_me.py
(sam) joe@helium:~/alex$ flask run
* Serving Flask app "run_me.py"
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
.
.
.
[ctl-C to end the application after the curl test]

在另一个终端窗口中,输入 curl 命令:

joe@helium:~$ curl localhost:5000
<title>Ned's Greeting</title>
<span style="color: blue"><b>Howdy Doodly, Neighbor!

现在,我们将这个操作最少的Flask应用程序放在架子上,同时将Nginx和uWSGI放在一起。

设置 uWSGI 参数以与烧瓶应用程序配合使用

uwsgi.ini 文件为将 Python-Flask 应用程序链接到 Nginx 服务器所需的所有参数设置值。

模块参数标识要运行的 Python 文件 (run_me.py) 和 Flask 应用程序对象 (ned)。

master 参数是生产环境的标准设置。

进程参数通常设置为 5 作为默认值。要获得最佳设置,需要在负载下对应用程序进行试验。

socket 参数提供 uWSGI 和 Nginx 之间的套接字连接的名称。请注意,套接字值也在 Nginx 配置文件中标识。这些必须匹配,以便uWSGI与Nginx正确链接 - 一种协调应用程序元素的通用机制。

chmod-socket 参数应该提供对套接字的"uWSGI 用户"访问。文档中指定了值 664,但它对我们不起作用,因此我们在此处将其显示为 666,这对我们有用。

vacuum 参数指示 uWSGI 在uWSGI 服务器终止时删除 Unix 套接字。

uid 和 gid 参数标识运行 uWSGI 服务器的用户和组。

当应用程序退出时,终止死亡参数指示uWSGI"残酷地重新加载所有工作线程和主进程"。

uwsgi.ini 参数文件如下所示:

[uwsgi]
module=run_me:ned
master = true
processes = 5
socket = baker.sock
chmod-socket = 666  
vacuum = true
uid = joe
gid = www-data
die-on-term = true

设置 nginx 以使用 uWSGI 参数

下面显示的 Nginx 配置文件通过 include 和 uwsgi_pass 参数与 uWSGI 服务器链接。

/etc/nginx/conf.d/helium.conf

server {
listen 8181;
server_name localhost;
location / {
include   uwsgi_params;
uwsgi_pass  unix:/home/joe/alex/baker.sock;
}
}

/etc/nginx/conf.d/helium.conf 文件包含在标准"starter"配置文件的最后一行中,该文件随从 Nginx.org 站点安装 Nginx 服务器一起提供。

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
worker_connections  1024;
}

http {
include       /etc/nginx/mime.types;
default_type  application/octet-stream;
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log  main;
sendfile        on;
#tcp_nopush     on;
keepalive_timeout  65;
#gzip  on;
include /etc/nginx/conf.d/helium.conf;
}

运行 Nginx 和 uWSGI 服务器

要重新启动 Nginx 服务器:

$ sudo service nginx restart

为了正确启动 uWSGI 的 .../alex/paa 应用程序,您必须激活 sam 虚拟环境,然后运行 uWSGI 服务器。

--ini uwsgi.ini 参数将 uWSGI 定向到我们的.ini文件。

--daemonize uwsgi.log 参数将此 uWSGI 服务器实例作为守护进程运行,并指示服务器将其日志输出写入 uwsgi.log。

--safe-pidfile/tmp/alex.pid参数将此 uWSGI 服务器进程的 pid 保存到文件 "/tmp/alex.pid" 中。引用该pid编号是为了"优雅地"重新加载uWSGI服务器或停止它。(请参阅此处。

(sam) joe@helium:~/alex$ uwsgi --ini uwsgi.ini --daemonize uwsgi.log --safe-pidfile /tmp/alex.pid

这是从命令行显示的问候语"curl localhost:8181":

(sam) joe@helium:~$ curl localhost:8181
<title>Ned's Greeting</title>
<span style="color: blue"><b>Howdy Doodly, Neighbor!</b></span>

我们有它:Flask应用程序通过uWSGI加入Nginx。

双倍的乐趣

但是我们忍不住检查一下。

将uWSGI安装到Python虚拟环境中的一个直接含义是,我们应该能够从单独的虚拟环境运行多个Flask应用程序 - 每个应用程序都通过自己的uWSGI连接到Nginx。事实证明,我们可以。

我们只是要勾勒出这个实现,因为它非常简单。我们创建了第二个名为"western"的虚拟环境,并像以前一样安装了Flask和uWSGI。我们为Flask应用程序创建了一个名为"scifi"的项目目录和一个名为"noir"的目录。下面的列表显示了西部/科幻/黑色设置中的替换。与上面的 sam/alex/paa 设置进行比较。

科幻/黑色/初始化.py

from flask import Flask
hitchcock = Flask(__name__)
hitchcock.config.from_object('config')

科幻/黑色/视图.py

from noir import hitchcock
@hitchcock.route('/')
def slash():
title = f"<title>Confusion Cinema</title>"
greeting = f'<span style="color: blue"><b>Some like hot, psycho birds!</b></span>n'
return f'{title}n{greeting}n'

科幻/run_fi.py

from noir import hitchcock
from noir import views
if __name__ == '__main__':
hitchcock.run()

科幻/配置.py

SECRET_KEY = 'ivegotasecret'

科幻/UWSGI.ini

[uwsgi]
module=run_fi:hitchcock
master = true
processes = 5
socket = marilyn.sock
chmod-socket = 666
vacuum = true
uid = joe
gid = www-data
die-on-term = true

我们通过单独的端口为两个独立的 Flask 应用程序提供服务来区分它们。uWSGI服务器负责将Flask应用程序链接到Nginx服务器的正确端口。

server {
listen 8181;
server_name localhost;
location / {
include   uwsgi_params;
uwsgi_pass  unix:/home/joe/alex/baker.sock;
}
}
server {
listen 8080;
server_name localhost;
location / {
include   uwsgi_params;
uwsgi_pass  unix:/home/joe/scifi/marilyn.sock;
}
}

最新更新