In this guide, we will be setting up a simple Python application using the Flask micro-framework on Ubuntu 16.04. The bulk of this article will be about how to set up the uWSGI application server to launch the application and Nginx to act as a front end reverse proxy.
Before starting on this guide, you should have a non-root user configured on your server. This user needs to have sudo
privileges so that it can perform administrative functions. To learn how to set this up, follow our initial server setup guide.
To learn more about uWSGI, our application server and the WSGI specification, you can read the linked section of this guide. Understanding these concepts will make this guide easier to follow.
When you are ready to continue, read on.
Our first step will be to install all of the pieces that we need from the repositories. We will install pip
, the Python package manager, in order to install and manage our Python components. We will also get the Python development files needed to build uWSGI and we’ll install Nginx now as well.
We need to update the local package index and then install the packages. The packages you need depend on whether your project uses Python 2 or Python 3.
If you are using Python 2, type:
- sudo apt-get update
- sudo apt-get install python-pip python-dev nginx
If, instead, you are using Python 3, type:
- sudo apt-get update
- sudo apt-get install python3-pip python3-dev nginx
Next, we’ll set up a virtual environment in order to isolate our Flask application from the other Python files on the system.
Start by installing the virtualenv
package using pip
.
If you are using Python 2, type:
- sudo pip install virtualenv
If you are using Python 3, type:
- sudo pip3 install virtualenv
Now, we can make a parent directory for our Flask project. Move into the directory after you create it:
- mkdir ~/myproject
- cd ~/myproject
We can create a virtual environment to store our Flask project’s Python requirements by typing:
- virtualenv myprojectenv
This will install a local copy of Python and pip
into a directory called myprojectenv
within your project directory.
Before we install applications within the virtual environment, we need to activate it. You can do so by typing:
- source myprojectenv/bin/activate
Your prompt will change to indicate that you are now operating within the virtual environment. It will look something like this (myprojectenv)user@host:~/myproject$
.
Now that you are in your virtual environment, we can install Flask and uWSGI and get started on designing our application:
We can use the local instance of pip
to install Flask and uWSGI. Type the following commands to get these two components:
Note
Regardless of which version of Python you are using, when the virtual environment is activated, you should use the pip
command (not pip3
).
- pip install uwsgi flask
Now that we have Flask available, we can create a simple application. Flask is a micro-framework. It does not include many of the tools that more full-featured frameworks might, and exists mainly as a module that you can import into your projects to assist you in initializing a web application.
While your application might be more complex, we’ll create our Flask app in a single file, which we will call myproject.py
:
- nano ~/myproject/myproject.py
Within this file, we’ll place our application code. Basically, we need to import Flask and instantiate a Flask object. We can use this to define the functions that should be run when a specific route is requested:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1 style='color:blue'>Hello There!</h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
This basically defines what content to present when the root domain is accessed. Save and close the file when you’re finished.
If you followed the initial server setup guide, you should have a UFW firewall enabled. In order to test our application, we need to allow access to port 5000.
Open up port 5000 by typing:
- sudo ufw allow 5000
Now, you can test your Flask app by typing:
- python myproject.py
Visit your server’s domain name or IP address followed by :5000
in your web browser:
http://server_domain_or_IP:5000
You should see something like this:
When you are finished, hit CTRL-C in your terminal window a few times to stop the Flask development server.
Next, we’ll create a file that will serve as the entry point for our application. This will tell our uWSGI server how to interact with the application.
We will call the file wsgi.py
:
- nano ~/myproject/wsgi.py
The file is incredibly simple, we can simply import the Flask instance from our application and then run it:
from myproject import app
if __name__ == "__main__":
app.run()
Save and close the file when you are finished.
Our application is now written and our entry point established. We can now move on to uWSGI.
The first thing we will do is test to make sure that uWSGI can serve our application.
We can do this by simply passing it the name of our entry point. This is constructed by the name of the module (minus the .py
extension, as usual) plus the name of the callable within the application. In our case, this would be wsgi:app
.
We’ll also specify the socket so that it will be started on a publicly available interface and the protocol so that it will use HTTP instead of the uwsgi
binary protocol. We’ll use the same port number that we opened earlier:
- uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
Visit your server’s domain name or IP address with :5000
appended to the end in your web browser again:
http://server_domain_or_IP:5000
You should see your application’s output again:
When you have confirmed that it’s functioning properly, press CTRL-C in your terminal window.
We’re now done with our virtual environment, so we can deactivate it:
- deactivate
Any Python commands will now use the system’s Python environment again.
We have tested that uWSGI is able to serve our application, but we want something more robust for long-term usage. We can create a uWSGI configuration file with the options we want.
Let’s place that in our project directory and call it myproject.ini
:
- nano ~/myproject/myproject.ini
Inside, we will start off with the [uwsgi]
header so that uWSGI knows to apply the settings. We’ll specify the module by referring to our wsgi.py
file, minus the extension, and that the callable within the file is called “app”:
[uwsgi]
module = wsgi:app
Next, we’ll tell uWSGI to start up in master mode and spawn five worker processes to serve actual requests:
[uwsgi]
module = wsgi:app
master = true
processes = 5
When we were testing, we exposed uWSGI on a network port. However, we’re going to be using Nginx to handle actual client connections, which will then pass requests to uWSGI. Since these components are operating on the same computer, a Unix socket is preferred because it is more secure and faster. We’ll call the socket myproject.sock
and place it in this directory.
We’ll also have to change the permissions on the socket. We’ll be giving the Nginx group ownership of the uWSGI process later on, so we need to make sure the group owner of the socket can read information from it and write to it. We will also clean up the socket when the process stops by adding the “vacuum” option:
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
The last thing we need to do is set the die-on-term
option. This can help ensure that the init system and uWSGI have the same assumptions about what each process signal means. Setting this aligns the two system components, implementing the expected behavior:
[uwsgi]
module = wsgi:app
master = true
processes = 5
socket = myproject.sock
chmod-socket = 660
vacuum = true
die-on-term = true
You may have noticed that we did not specify a protocol like we did from the command line. That is because by default, uWSGI speaks using the uwsgi
protocol, a fast binary protocol designed to communicate with other servers. Nginx can speak this protocol natively, so it’s better to use this than to force communication by HTTP.
When you are finished, save and close the file.
The next piece we need to take care of is the systemd service unit file. Creating a systemd unit file will allow Ubuntu’s init system to automatically start uWSGI and serve our Flask application whenever the server boots.
Create a unit file ending in .service within the /etc/systemd/system directory to begin:
- sudo nano /etc/systemd/system/myproject.service
Inside, we’ll start with the [Unit]
section, which is used to specify metadata and dependencies. We’ll put a description of our service here and tell the init system to only start this after the networking target has been reached:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
Next, we’ll open up the [Service]
section. We’ll specify the user and group that we want the process to run under. We will give our regular user account ownership of the process since it owns all of the relevant files. We’ll give group ownership to the www-data
group so that Nginx can communicate easily with the uWSGI processes.
We’ll then map out the working directory and set the PATH
environmental variable so that the init system knows where our the executables for the process are located (within our virtual environment). We’ll then specify the commanded to start the service. Systemd requires that we give the full path to the uWSGI executable, which is installed within our virtual environment. We will pass the name of the .ini configuration file we created in our project directory:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
Finally, we’ll add an [Install]
section. This will tell systemd what to link this service to if we enable it to start at boot. We want this service to start when the regular multi-user system is up and running:
[Unit]
Description=uWSGI instance to serve myproject
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
[Install]
WantedBy=multi-user.target
With that, our systemd service file is complete. Save and close it now.
We can now start the uWSGI service we created and enable it so that it starts at boot:
- sudo systemctl start myproject
- sudo systemctl enable myproject
Our uWSGI application server should now be up and running, waiting for requests on the socket file in the project directory. We need to configure Nginx to pass web requests to that socket using the uwsgi
protocol.
Begin by creating a new server block configuration file in Nginx’s sites-available
directory. We’ll simply call this myproject
to keep in line with the rest of the guide:
- sudo nano /etc/nginx/sites-available/myproject
Open up a server block and tell Nginx to listen on the default port 80. We also need to tell it to use this block for requests for our server’s domain name or IP address:
server {
listen 80;
server_name server_domain_or_IP;
}
The only other thing that we need to add is a location block that matches every request. Within this block, we’ll include the uwsgi_params
file that specifies some general uWSGI parameters that need to be set. We’ll then pass the requests to the socket we defined using the uwsgi_pass
directive:
server {
listen 80;
server_name server_domain_or_IP;
location / {
include uwsgi_params;
uwsgi_pass unix:/home/sammy/myproject/myproject.sock;
}
}
That’s actually all we need to serve our application. Save and close the file when you’re finished.
To enable the Nginx server block configuration we’ve just created, link the file to the sites-enabled
directory:
- sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
With the file in that directory, we can test for syntax errors by typing:
- sudo nginx -t
If this returns without indicating any issues, we can restart the Nginx process to read the our new config:
- sudo systemctl restart nginx
The last thing we need to do is adjust our firewall again. We no longer need access through port 5000, so we can remove that rule. We can then allow access to the Nginx server:
- sudo ufw delete allow 5000
- sudo ufw allow 'Nginx Full'
You should now be able to go to your server’s domain name or IP address in your web browser:
http://server_domain_or_IP
You should see your application output:
Note
After configuring Nginx, the next step should be securing traffic to the server using SSL/TLS. This is important because without it, all information, including passwords are sent over the network in plain text.
The easiest way get an SSL certificate to secure your traffic is using Let’s Encrypt. Follow this guide to set up Let’s Encrypt with Nginx on Ubuntu 16.04.
In this guide, we’ve created a simple Flask application within a Python virtual environment. We create a WSGI entry point so that any WSGI-capable application server can interface with it, and then configured the uWSGI app server to provide this function. Afterwards, we created a systemd service file to automatically launch the application server on boot. We created an Nginx server block that passes web client traffic to the application server, relaying external requests.
Flask is a very simple, but extremely flexible framework meant to provide your applications with functionality without being too restrictive about structure and design. You can use the general stack described in this guide to serve the flask applications that you design.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Former Senior Technical Writer at DigitalOcean, specializing in DevOps topics across multiple Linux distributions, including Ubuntu 18.04, 20.04, 22.04, as well as Debian 10 and 11.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Awesome! thanks for this! finally got my instance up and running…
I was actually following your other guide on deployment for ubuntu 14, when I provisioned ubuntu 16. Was racking my head trying to sort through the difference between systemd and upstart. tried converting files… asking ubuntu 16 to revert to upstart… all to no avail… until this tutorial popped up…
thanks again. have a good day!
This comment has been deleted
Warning, anyone following or reading this tutorial there is an error at “/etc/nginx/sites-available/myproject” part.
uwsgi_pass unix:/home/sammy/myproject/myproject.sock;
Should be
uwsgi_pass unix:///home/sammy/myproject/myproject.sock;
This should solve any 502 gateway error’s
Good instructions for the most part. However calling everything myproject is really confusing. Everyone who reads this will agree.
…Or you can learn Docker and leave the Nginx / uWSGI to an image like this one: https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
And just worry about your Flask app.
Also, if you latter want to use a DB like MySQL or Postgres you can add it very easily with Docker. Without having to learn each system and it’s configurations. And the same with most other stacks (Redis, ElasticSearch, Celery with RabbitMQ, etc). (It’s totally worthwhile to learn Docker).
Replying to tiangolo
Thanks for this! I never heard of Docker before and after researching it for a few hours and pulling your image, it worked like a charm.
Replying to tiangolo
I was having trouble with 502 Bad Gateway and spent a lot of time trying to get through the tutorial. I gave up and set up your container, it took me 10 minutes to get it running! Thanks tiangolo.
I’ve used Docker a little bit before, so this was a great solution.
My .conf file is similar to what you’re told to put here, yet it always tells me that the server directive is not allowed when I do sudo nginx -t.
nginx: configuration file /etc/nginx/nginx.conf test failed
Interestingly it complains about that specific .conf file, rather than the location recommended in this article. ( /etc/nginx/sites-enabled/myproject )
Also, here’s some information I heard earlier, if someone can tell me if this sounds about right…
That most people do not run their webserver applications directly on port 80 or 443, they usually run it on a higher level port that would not give the application root level access. Is this accurate? If so what would we do to change the default port, so that it does not have to be included in the URL.
Hey Justin!
This worked out perfectly for me. Only one issue I have is that one of my python modules would like to use Java. When it tries to find the path it can’t find it. I edited the module and hardcoded the path and I managed to find out it says Permission Denied now. What are the proper steps to securely allow the python module within the virtual environment to access Java? I tried a bunch of different things but nothing ended up stopping the Permission Denied issue from coming up.
Thanks a bunch!
I am getting 502 bad gateway In nginx error logs I can see that its not able to find project.sock file When I checked in my project folder there is no sock file. How will it be generated?
I tried generating manually and chmod-ing it but then I get connection refused
The app is getting served only in my browser. Its not getting served in other devices!!!
This tutorial has been very helpful. I am able to deploy my app.
But there seems to be some problem when sending email through the app. In development enviornment everything is working fine, i get the email. When testing the app using $ uwsgi command it still work but not when using unix socket. Is there something I am missing?
I have changed the content in myproject.py file from Hello There! to Hi There! and restart the server using sudo systemctl restart nginx but nothing is reflect in browser. Can someone explain me what I am doing wrong?
After following this tutorial I end up with the default welcome to Nginx page being served.
I follow this tutorial for my project and everything is working perfect, but now my API request takes too much time to respond. Is there any config setting that I missed? Because it is almost 10 times higher than the old Cherrypy server.
Hello everyone,
I new to these server setup and I followed all the steps as described in this post, But I am not able to deploy the app. A details question I asked on stackoverflow , please take a look and help me throgh that.
Thanks
Note: I also tried
uwsgi_pass unix:///home/sammy/myproject/myproject.sock;
But no success.
Very nice tutorial. I was able to follow up until creating the sockets for connecting.
I’m trying to apply it on a slightly different setup. My server is behind a gateway running Nginx. Would it be possible to use the Nginx running on the gateway instead? What would be the changes if my wsgi and nginx are on two different computers?
Thanks for any replies.
Hi Folks,
For those that have the 502 gateway error try changing chmod-socket = 660 to chmod-socket = 666
. Worked for me on Debian stretch.
cheers
Followed the directions with my DO server literally letter by letter and it still returned a 502. I’ve done this tutorial probably a dozen times. Maybe it’s time to go back to Apache
anyone else having trouble with the internal error…
change the working directory in /etc/systemd/system/project.service
WorkingDirectory=/home/sammy/myproject/myprojectenv
and in the nginx file
unix:///home/user/myproject/myprojectenv/myproject.sock;
Like many others, I am getting a 502 Bad Gateway from the nginx server. I have looked through the comments and found the change to the uwsgi_pass line, but the issue persists. Upon more digging, the issue seems to be with systemd. The myproject.service is failing to start. In my version, myProject
is hello
and I have included the status output from systemctl to hopefully help solve the problem.
● hello.service - uWSGI instance to serve the test project Loaded: loaded (/etc/systemd/system/hello.service; enabled; vendor preset: enabled) Active: failed (Result: exit-code) since Fri 2017-03-17 20:34:25 UTC; 16min ago Process: 30361 ExecStart=/bin/uwsgi --ini hello.ini (code=exited, status=203/EXEC) Main PID: 30361 (code=exited, status=203/EXEC)
Mar 17 20:34:25 servalServer systemd[1]: Started uWSGI instance to serve the test project. Mar 17 20:34:25 servalServer systemd[1]: hello.service: Main process exited, code=exited, status=203/EXEC Mar 17 20:34:25 servalServer systemd[1]: hello.service: Unit entered failed state. Mar 17 20:34:25 servalServer systemd[1]: hello.service: Failed with result ‘exit-code’.
Is it possible to run two flask environments from one computer (AWS free Tier) one flask serving python 2.7 and one flask with python 3.
Many thanks for the great tutorial
This is what I was looking for. It works for python3 and that’s great because my project is coded under python3 . Excellent guide and thank you very much :D
Why do I get 502 bad gateway error? Went through the instructions twice and still same error. …WHYYYYYY?
This tutorial should be removed by DigitalOcean staff since it does not work. 24 hours with problems and reinstallation and back to square one. 502 bad gateway and sockets is not being created.
For those still getting the 502 gateway error after doing all the steps twice and even after correcting the path to the sock. Try running this command to output any systemctrl errors:
journalctl -u <your project name>.service
Ended up telling me that it couldn’t find my .ini file, once I corrected that error it worked. Hope you guys get it working!
For those of your still experiencing the 500/502 error problem, I just spent a long time struggling with it, and I was able to fix it on my system after taking a look at the logs. My problem was that when I tried to adapt the tutorial to my specific project, the service wouldn’t start.
Follow the steps I did, and maybe it will fix your problem.
Make sure you look at your syslogs: sudo vim /var/log/syslog
In syslog I had an error: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
I had already run into this multiple times. It’s due to not having $LD_LIBRARY_PATH configured properly. If you see this message, type sudo find / -name libpcre.so.1
on the commandline. If it returns a result, your’e good. All you have to do is change the Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
entry in your myproject.service
file to Environment="PATH=/home/sammy/myproject/myprojectenv/bin" "LD_LIBRARY_PATH=/path/to/your/libfolder"
. This will ensure that the ExecStart
entry runs with the PATH and LD_LIBRARY_PATH environment variables set up correctly.
In my case, /path/to/your/libfolder was /home/admin_user/anaconda3/pkgs/pcre-8.39-1/lib/
. If you don’t have it on your system, you need to install libpcre: http://www.linuxfromscratch.org/blfs/view/svn/general/pcre.html and follow the steps above.
Let me know if that resolves anyone’s issues.
Try as I might, I can’t seem to get uwsgi to behave for a non-trivial app. I’ve written up a detailed SO question (http://stackoverflow.com/questions/43905911/flask-app-imports-fail-when-launched-under-uwsgi/43907227), but basically, while flask run
works fine, uwsgi fails to find the flask module when it’s imported.
I am following the guide. However I am not using a virtual environment. My app starts when I run python app_name from the command line. It also starts up when I python wsgi.py as well. When I get to uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
I get the following uwsgi: invalid option – ‘w’ getopt_long() error
I then run. uwsgi --socket 0.0.0.0:5000 --plugin python3 --protocol=http -w wsgi:app
uwsgi starts. WIth
uwsgi socket 0 bound to TCP address 0.0.0.0:5000 fd 3 Python version: 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] *** Python threads support is disabled. You can enable it with --enable-threads *** Python main interpreter initialized at 0x22fae90 your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 72768 bytes (71 KB) for 1 cores *** Operational MODE: single process *** unable to load app 0 (mountpoint=‘’) (callable not found or import error) *** no app loaded. going in full dynamic mode *** *** uWSGI is running in multiple interpreter mode *** spawned uWSGI worker 1 (and the only) (pid: 31814, cores: 1) — no python application found, check your startup logs for errors —
When I navigate to localhost:5000 I get internal server error. What am I doing wrong and why do I get the invalid option error.
I haven’t even gotten to nginx yet.
Thanks in advance.
Great tutorial! Almost everything is working and by this I mean I am using flask pdfkit with wkhtmltopdf to generate pdf’s and everything was installed successfully. When I ran the app by typing python myproject.py everything works fine even pdfkit. but after I installed and configured uWSGI and Nginx everything works fine except when I try to generate pdf’s by clicking on a button it gives me 502 bad gateway nginx/1.10.0 (Ubuntu) error. Do I need to make changes to myproject.service, my project.ini etc files? Can someone help with this I will appreciate it?
Thank you
Thanks for this tutorial. I finished that. But i have a problem with nginx. this step: Configuring Nginx to Proxy Requests. when i finish it i still see this page:
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com.
Thank you for using nginx.
Whats my wrong ? thanks
Is it possible to run two flask environments from one computer (AWS free Tier) one flask serving python 2.7 and one flask with python 3.
Many thanks for the great tutorial
This is what I was looking for. It works for python3 and that’s great because my project is coded under python3 . Excellent guide and thank you very much :D
Why do I get 502 bad gateway error? Went through the instructions twice and still same error. …WHYYYYYY?
This tutorial should be removed by DigitalOcean staff since it does not work. 24 hours with problems and reinstallation and back to square one. 502 bad gateway and sockets is not being created.
For those still getting the 502 gateway error after doing all the steps twice and even after correcting the path to the sock. Try running this command to output any systemctrl errors:
journalctl -u <your project name>.service
Ended up telling me that it couldn’t find my .ini file, once I corrected that error it worked. Hope you guys get it working!
For those of your still experiencing the 500/502 error problem, I just spent a long time struggling with it, and I was able to fix it on my system after taking a look at the logs. My problem was that when I tried to adapt the tutorial to my specific project, the service wouldn’t start.
Follow the steps I did, and maybe it will fix your problem.
Make sure you look at your syslogs: sudo vim /var/log/syslog
In syslog I had an error: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
I had already run into this multiple times. It’s due to not having $LD_LIBRARY_PATH configured properly. If you see this message, type sudo find / -name libpcre.so.1
on the commandline. If it returns a result, your’e good. All you have to do is change the Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
entry in your myproject.service
file to Environment="PATH=/home/sammy/myproject/myprojectenv/bin" "LD_LIBRARY_PATH=/path/to/your/libfolder"
. This will ensure that the ExecStart
entry runs with the PATH and LD_LIBRARY_PATH environment variables set up correctly.
In my case, /path/to/your/libfolder was /home/admin_user/anaconda3/pkgs/pcre-8.39-1/lib/
. If you don’t have it on your system, you need to install libpcre: http://www.linuxfromscratch.org/blfs/view/svn/general/pcre.html and follow the steps above.
Let me know if that resolves anyone’s issues.
Try as I might, I can’t seem to get uwsgi to behave for a non-trivial app. I’ve written up a detailed SO question (http://stackoverflow.com/questions/43905911/flask-app-imports-fail-when-launched-under-uwsgi/43907227), but basically, while flask run
works fine, uwsgi fails to find the flask module when it’s imported.
I am following the guide. However I am not using a virtual environment. My app starts when I run python app_name from the command line. It also starts up when I python wsgi.py as well. When I get to uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
I get the following uwsgi: invalid option – ‘w’ getopt_long() error
I then run. uwsgi --socket 0.0.0.0:5000 --plugin python3 --protocol=http -w wsgi:app
uwsgi starts. WIth
uwsgi socket 0 bound to TCP address 0.0.0.0:5000 fd 3 Python version: 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] *** Python threads support is disabled. You can enable it with --enable-threads *** Python main interpreter initialized at 0x22fae90 your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 72768 bytes (71 KB) for 1 cores *** Operational MODE: single process *** unable to load app 0 (mountpoint=‘’) (callable not found or import error) *** no app loaded. going in full dynamic mode *** *** uWSGI is running in multiple interpreter mode *** spawned uWSGI worker 1 (and the only) (pid: 31814, cores: 1) — no python application found, check your startup logs for errors —
When I navigate to localhost:5000 I get internal server error. What am I doing wrong and why do I get the invalid option error.
I haven’t even gotten to nginx yet.
Thanks in advance.
Great tutorial! Almost everything is working and by this I mean I am using flask pdfkit with wkhtmltopdf to generate pdf’s and everything was installed successfully. When I ran the app by typing python myproject.py everything works fine even pdfkit. but after I installed and configured uWSGI and Nginx everything works fine except when I try to generate pdf’s by clicking on a button it gives me 502 bad gateway nginx/1.10.0 (Ubuntu) error. Do I need to make changes to myproject.service, my project.ini etc files? Can someone help with this I will appreciate it?
Thank you
Thanks for this tutorial. I finished that. But i have a problem with nginx. this step: Configuring Nginx to Proxy Requests. when i finish it i still see this page:
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org. Commercial support is available at nginx.com.
Thank you for using nginx.
Whats my wrong ? thanks
I ran through this tutorial, then I ran through the Let’s Encrypt tutorial ( https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04 ) and now my web application isn’t being served properly since the https version is apparently different from the http version. Any quick fix?
EDIT: there WAS a quick fix! I added these lines to /etc/nginx/sites-available/myproject file, right after the line listen 80;
:
listen 443;
ssl on;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
I think I found a workaround (fix?) to the 502 Bad Gateway problem / "connect() to unix:/// … failed (13: Permission denied). I moved the socket out of my home directory into /tmp/myproject.sock. Seemed to have done the trick. Follow-up question: is it bad to have a socket in /tmp? If so, where would be a better place?
Cheers, teep
I also have got a “502 gateway error”. First of all I want to focus your attentions that all installations must be done from the user side (not root user). So, first of all create new user, login to it and then do all steps from instruction. If you made changes form root then delete droplet and do all steps from the beginning from the user side. If you build your app on python 3.6 then install packages like this
sudo apt-get install python3-pip python3.6-dev nginx
...
virtualenv -p python3.6 myprojectenv
Thanks, I also have three problems -
So many complaining comments. Could the author please remove or update this tutorial? It really doesn’t work!
This is what I am getting after following the tutorial: Internal Server Error
Yet another who has followed this tutorial to the letter with a 502 bad gateway error. Can you please take this down and amend the article ASAP.
What’s the purpose of wsgi.py
. It appear to be a proxy that doesn’t really do much. Instead of the ini file saying module = wsgi:app
I could just use module = myproject:app
. One less file. Or does it actually have a special purpose?
For those who have a 502 Gateway error. It might be because you’re trying to run two sites with the same user. You’d need to create a user for each site (e.g. userx, usery, etc). I don’t know why (anyone can explain?) but if you try to serve more than one site with nginx .sock with the same user, the second site you create doesn’t create the .sock file.
Thanks for the awesome tutorial.
By following the tutorial I got it running. However, I couldn’t seem to display any update on flask. For simplicity, I only changed return “<h1 style=‘color:blue’>Hello There!</h1>” to different string.
I tried to perform: sudo systemctl start myproject sudo systemctl enable myproject sudo ssystemctl restart nginx
However, when I go to my website, it is still showing the old version. Am I doing it the wrong way?
Followed the instructions and worked perfectly for me!
Make sure you run the following command after changing any of the code in your .py file in order for it to show up/work:
sudo systemctl restart myproject
If you’re getting a 502 Gateway error, try deleting other files in the /etc/nginx/sites-available directory except for your “myproject” file.
This tutorial was horrible. I ran through it several times and still got 502 error. *.sock file was being created (file or directory doesn’t exist). If someone can answer this it might help someone else but this was a terrible experience and hours lost for something that seemed to be an easy process. Also, you may want to highlight that you need to create another (sammy) user before starting.
The error I’m getting
8640#8640: *11 connect() to unix:///home/sammy/myproject/myproject.sock failed (2: No such file or directory) while connecting to upstream, client:
Please add root in nginx setup, for me after adding root in nginx file application started working. server { listen 80; server_name server_domain_or_IP; root /home/sammy/myproject
location / {
include uwsgi_params;
uwsgi_pass unix:/home/sammy/myproject/myproject.sock;
}
}
For others who might experience problems, rest assured this tutorial works. I experienced all the problems mentioned throughout these comments…502 Gateway error, Nginx default page showing up, files not found, and even another not mentioned here.
First time through, I received 502 Gateway error. So, I copied and pasted everything from the site exactly another time through, and got rid of the 502 Gateway error, but the page wasn’t showing up. I believe this was bc I had setup the droplet previous for a NodeJS app and was forcing the site to https instead of http. This tutorial only sets up for http, so that was likely the problem.
Created a fresh, new droplet. Confident without the https redirect it would work the first time through. So, instead of copy-pasting each command, I changed myproject
to my actual project name, changed sammy
to my username, and I went through the tutorial again. Still got 502 Gateway Error.
Attempted tutorial again, this time copy-pasting everything exactly except changing sammy
to my username. Still received a 502 Gateway error at the end.
Solution (For me):
cat /var/log/nginx/error.log
to look through your log of errors. I saw that the server was still attempting to load the app I created in step #2 above./etc/nginx/sites-available/myproject
file and the /etc/systemd/system/myproject.service
file.myproject
on my server. Again, not just the project file, but also the system files that were created.myproject
names to my own username and project name. During this attempt I noticed ONE little typo I likely made on a previous attempt, forgetting to replace myproject
with my own project name in one file on one line. So, be careful. Just one typo and things won’t work right.Moral of the story, first time through you might want to copy-paste every exactly into your console except for your username to make sure everything works right.
If you have at least 1 failed attempt, make sure you have deleted everything before trying again. Essentially, reverse the tutorial instructions, removing every folder and file you created when following the tutorial.
After doing the above, and also everything else every mentions in the comments, this tutorial worked for me.
BETTER advice for people getting the 502 bad gateway error: Learn how nginx logs and go find said logs. Every time Nginx has a server error it will log. In this case, the file you want is usually at /var/log/nginx/error.log
.
In my case, this is the log I got:
018/01/26 21:43:36 [crit] 13607#13607: *1 connect() to unix://home/sammy/myproject/project.sock failed (13: Permission denied) while connecting to upstream, client: 209.6.192.188, server: 192.241.159.83, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/home/sammy/myproject/project.sock:", host: "192.241.159.83"
This suggests that the uwsgi is somehow not being permitted to do what it wants to do with the project.sock
file. I checked the permissions and they were 755
, my user being the owner and www-data being the group. However, this is not as it should be based on the instructions: in the project.ini
file we specify that the socket file should have file permissions of 660
.
Based on this knowledge, I double-checked my .ini file and realized that I had written chmod-sock = 660
instead of chmod-sock***et***. I corrected the spelling and restarted both the service and nginx and everything is working now, and the socket file has the correct permissions.
Knowing what you’re doing is more important than just blindly following a tutorial - I hope my advice with the log files was useful and might help some of you grow as developers and troubleshooters =).
This tutorial works pretty fine for the example you specified !!
But When I’m trying to run my original flask project through the tutorial it is showing some errors.
I just reconfigured the wsgi.py file to import app instance from my server.py instead of myproject.py.
Also I am using separate virtual environment for my project’s dependencies and set the path of the virtual environment in the myproject.service file.
Finally, after restarting my project and nginx… I got the following errors:-
myproject.service - uWSGI instance to serve myproject
Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since বà§à¦§ 2018-01-31 12:09:08 +06; 10s ago
Process: 27705 ExecStart=/home/user/myproject/virtual_frame/bin/uwsgi --ini myproject.ini (code=exited, status=203/EXEC)
Main PID: 27705 (code=exited, status=203/EXEC)
জানৠ31 12:09:08 user-HVM-domU systemd[1]: Started uWSGI instance to serve myproject.
জানৠ31 12:09:08 user-HVM-domU systemd[1]: myproject.service: Main process exited, code=exited, status=203/EXEC
জানৠ31 12:09:08 user-HVM-domU systemd[1]: myproject.service: Unit entered failed state.
জানৠ31 12:09:08 user-HVM-domU systemd[1]: myproject.service: Failed with result 'exit-code'.
So, what I am sensing that uwsgi might be unable serve my project.
Then when I tried directly run my project with uwsgi without nginx I got the following error…
(virtual_frame) user@user-HVM-domU:~/myproject$ sudo uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app
IOError: unable to complete websocket handshake
So, is there any problem running Flask SocketIO with wsgi ?? Or, I am missing or misleading some further configuration beyond your Tutorial ??
What does the –ini part of the following line do?
ExecStart=/home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini
After successfully completing the tutorial, i am trying to deploy my own server app based on keras and tensorflow . it works fine till the testing of Uwsgi serving point but after that when i create the service and config files . it gives me a 504 timeout error. the code and the config files are available on this question in stack. https://stackoverflow.com/questions/49255545/flask-application-giving-504-timeout-through-uwsgi-and-nginx
For those who failed to install uwsgi with pip, please install ‘build-essential’ from ubuntu repo first
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.