Reputation: 457
I have taken VPS from godaddy and built a machine with Ubuntu 16.04. I want to host a Python (Django) application. I successfully installed Nginix. Unfortunately, I am not able to install Nginix with pip on this machine.
When I run:
sudo pip install uwsgi
I am getting the following error.
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('\r\n', '\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('\r\n', '\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/
Here is my gcc version
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)
I was able to install on Amazon EC2 (Ubuntu 5.4.0-6ubuntu1~16.04.4) using
`sudo pip install uwsgi`
Upvotes: 5
Views: 14353
Reputation: 3825
You can try installing the C compiler and python development files by running
apt-get install build-essential python3-dev
and then try to install uwsgi
link to relevant documentation
Upvotes: 14
Reputation: 42
Deployment of a Flask application for public access requires a real webserver be installed in front of the application. That, in turn, requires, a mechanism for linking the webserver to the Flask application.
In this post, we'll install the uWSGI package and use it to link a rudimentary Flask application to an Nginx server. As part of the uWSGI installation, we'll set up a Python virtual environment to house both the Flask application and the uWSGI package.
In order to follow this post, you should have a recent version of Python and Nginx (see sidebar).
NOTE: As of January 28, 2019, these same instructions work for installing uWSGI version 2.0.17.1.
We used my Antsle to create a Ubuntu 16.04 installation (named "helium") where we have installed recent releases of Python and Nginx (see sidebar).
We're going to install uWSGI in a Python virtual environment, so first we set up a new virtual environment and activate it. NOTE: You can, of course, set up your virtual environment anywhere you have rights, but my common practice is to put them all in my home account under a single "venvs" directory.
$ 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
Once the virtual environment is activated, the system prompt is prefixed with the name of the virtual environment - (sam). Check the Python version. Next we use which -a to check for the multiple python3 installations: Ubuntu distro, our Python 3.7.0 installation, and the python3 in the (sam) virtual environment.
(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
With the virtual environment in place, we can install Flask and uWSGI. NOTE: The uWSGI install will fail unless you have a complete Python installation. In particular, you need to have the python3-dev package and the libssl-dev package installed. (See this post.)
Both Flask and uWSGI are installed in the virtual environment. Check the versions.
(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
Installations Complete: Here's the Plan
Now everything we need is installed: Python, Nginx, Flask and uWSGI. This is what we are going to do:
We set up and run a simple Flask application without using either Nginx or uWSGI. Test the application using curl.
We hook up our rudimentary Flask application to the Nginx server by using a uWSGI configuration file.
As a bonus, we set up a second virtual environment ("western") with all the trimmings - uWSGI, Flask application, Nginx service, etc. - and run both applications at the same time.
There are many different ways to structure a Flask application. We'll use the following directory structure.
/home/joe
|
|-- /alex (project directory)
|
| -- /paa (application directory)
. |
. | -- /static (css, js, etc.)
. | -- /templates (html files)
. |
. | -- __init__.py
. | -- routes.py
. | :
. | :
|
| -- config.py
| -- run_me.py
| :
| :
This structure is a little overblown for the rudimentary Flask application we are going to build, but it is illustrative of the setup for a simple application (meaning no Blueprints). Also, we have made a few files and directories with artificially distinct names so that dependencies are a little clearer than in most tutorials.
File: __init__.py (shown below)
from flask import Flask
ned = Flask(__name__)
ned.config.from_object('config')
NOTE: Only the root name of the config.py file (shown below) is used in the ned.config.from_object() call.
File: routes.py (shown below)
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'
NOTE: Our default practice is to use single quotes for strings, but the apostrophe in "Ned's Greeting" necessitates double quotes for the title value.
File: run_me.py (shown below)
from paa import ned
from paa import routes
if __name__ == '__main__':
ned.run()
NOTE: Flask defaults to serving the application at address localhost:5000 unless some other host and port are specified in the "ned.run()" statement. As you'll see later, there is no need for those parameters when using uWSGI and Nginx in this example.
File: config.py (shown below)
SECRET_KEY = 'ivegotasecret'
We've included a Flask SECRET_KEY configuration value here for the sake of completeness. It is not necessary in the example shown above. In any real Flask application (using Nginx and uWSGI), though, you're going to use the "session" object at some point, and you cannot do that unless you have set the SECRET_KEY configuration value. See this StackOverflow question/answer for a full description of the Flask "session" object.
In order to test the Flask application using the curl command, we need to have two terminal sessions - one to execute the Flask app and one to execute the curl command.
To run the Flask application, set up in the .../alex directory:
(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]
In another terminal window, enter the curl command:
joe@helium:~$ curl localhost:5000
<title>Ned's Greeting</title>
<span style="color: blue"><b>Howdy Doodly, Neighbor!
Now we leave this minimally operational Flask application on the shelf while we put Nginx and uWSGI together.
The uwsgi.ini file sets values for all of the parameters required to link a Python-Flask application to the Nginx server.
The module parameter identifies the Python file to run (run_me.py) and the Flask application object (ned).
The master parameter is a standard setting for production environments.
The processes parameter is commonly set to 5 as a default. To get an optimal setting requires experimentation with the application under load.
The socket parameter provides the name of the socket connection between uWSGI and Nginx. Note that the socket value is also identified in the Nginx configuration file. These have to match in order for uWSGI to link correctly with Nginx - a common mechanism for coordinating application elements.
The chmod-socket parameter is supposed to provide the "uWSGI user" access to the socket. The value 664 is specified in the documentation, but it did not work for us, so we show it here as 666, which did work for us.
The vacuum parameter directs uWSGI to delete the Unix socket when the uWSGI server terminates.
The uid and gid parameters identify the user and group running the uWSGI server.
The die-on-term parameter directs uWSGI to "brutally reload all the workers and the master process" when the application exits.
The uwsgi.ini parameter file is shown below:
[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
The Nginx configuration file shown below links up with the uWSGI server via the include and uwsgi_pass parameters.
/etc/nginx/conf.d/helium.conf
server {
listen 8181;
server_name localhost;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/joe/alex/baker.sock;
}
}
The /etc/nginx/conf.d/helium.conf file is included in the last line of the standard "starter" configuration file that comes with installation of the Nginx server from the Nginx.org site.
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;
}
To restart the Nginx server:
$ sudo service nginx restart
In order to start uWSGI properly for the .../alex/paa application, you have to activate the sam virtual environment, then run the uWSGI server.
The --ini uwsgi.ini parameter directs uWSGI to our .ini file.
The --daemonize uwsgi.log parameter runs this instance of the uWSGI server as a daemon process and directs the server to write its log output to uwsgi.log.
The --safe-pidfile /tmp/alex.pid parameter saves the pid for this uWSGI server process to the file "/tmp/alex.pid". That pid number is referenced to "gracefully" reload the uWSGI server or to stop it. (See this.)
(sam) joe@helium:~/alex$ uwsgi --ini uwsgi.ini --daemonize uwsgi.log --safe-pidfile /tmp/alex.pid
And here's the greeting displayed from the command line with "curl localhost:8181":
(sam) joe@helium:~$ curl localhost:8181
<title>Ned's Greeting</title>
<span style="color: blue"><b>Howdy Doodly, Neighbor!</b></span>
There we have it: the Flask application is joined to Nginx via uWSGI.
But we could not resist checking this out.
One immediate implication of installing uWSGI into a Python virtual environment is that we should be able to run multiple Flask applications from separate virtual environments - each through its own uWSGI connection to Nginx. And it turns out that we can.
We're just going to sketch this implementation because it is so straightforward. We created a second virtual environment named "western" and installed both Flask and uWSGI as before. We made a project directory named "scifi" and a "noir" directory for the Flask application. The listings below show the substitutions in the western/scifi/noir setup. Compare to the sam/alex/paa setup above.
scifi/noir/init.py
from flask import Flask
hitchcock = Flask(__name__)
hitchcock.config.from_object('config')
scifi/noir/views.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'
scifi/run_fi.py
from noir import hitchcock
from noir import views
if __name__ == '__main__':
hitchcock.run()
scifi/config.py
SECRET_KEY = 'ivegotasecret'
scifi/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
We distinguish the two separate Flask applications by serving them via separate ports. The uWSGI servers takes care of linking the Flask applications to the correct ports for the Nginx server.
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;
}
}
Upvotes: -4
Reputation: 292
I have the same issue with installing uwsgi on Ubuntu 16.04. Conda solved my problem.
conda install -c conda-forge uwsgi
Upvotes: 19