ozwiz
By:
ozwiz

Django Deployment - Unable to access django app using my ip ?

March 1, 2017 398 views
Django Nginx Ubuntu 16.04

I have followed https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-django-with-postgres-nginx-and-gunicorn tutorial to deploy django app. At the end of it, when i tried accessing I got "502 Bad Gateway".

Here are nginx error logs from error.logs file.

2017/03/01 06:40:13 [error] 26234#26234: *16 connect() failed (111: Connection refused) while connecting to upstream, client: 85.203.18.254, server: 174.138.68.184, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8001/", host: "174.138.68.184"


2017/03/01 06:41:00 [error] 26301#26301: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 85.203.18.254, server: 174.138.68.184, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8001/", host: "174.138.68.184"
3 Answers

It's because Gunicorn is not running, so when Nginx cannot connect to the upstream server it gives the error 502.
Did you remember to start Gunicorn? It's in the lower half of step 9.

Yes gunicorn is running.

(myenv) root@ubuntu-512mb-nyc3-01:/opt# sudo ps wwaux | grep -i unicorn
root     27360  0.1  4.5  61988 22848 pts/2    S+   08:03   0:00 /opt/myenv/bin/python3 /opt/myenv/bin/gunicorn --bind 174.138.68.184:8001 django_project.wsgi
root     27363  0.0  7.2 158764 36412 pts/2    S+   08:03   0:00 /opt/myenv/bin/python3 /opt/myenv/bin/gunicorn --bind 174.138.68.184:8001 django_project.wsgi
root     27493  0.0  0.2  12944  1084 pts/3    S+   08:08   0:00 grep --color=auto -i unicorn
(myenv) root@ubuntu-512mb-nyc3-01:/opt#

Infact i can access django app at http://174.138.68.184:8001/ even when i turn off nginx. That means i guess gunicorn is working as expected.

I also tried to view error logs of gunicorn by specifying --log-file as below:

gunicorn --bind 174.138.68.184:8001 --log-file g.log django_project.wsgi

Here is the content of the log file.

(myenv) root@ubuntu-512mb-nyc3-01:/opt/django_project# cat g.log
[2017-03-01 08:14:33 +0000] [27546] [INFO] Starting gunicorn 19.6.0
[2017-03-01 08:14:33 +0000] [27546] [INFO] Listening at: http://174.138.68.184:8001 (27546)
[2017-03-01 08:14:33 +0000] [27546] [INFO] Using worker: sync
[2017-03-01 08:14:33 +0000] [27549] [INFO] Booting worker with pid: 27549
(myenv) root@ubuntu-512mb-nyc3-01:/opt/django_project#
  • Correct it's running, but then you didn't bind Gunicorn to the localhost bind = '127.0.0.1:8001' as described in the config file (middle section of part 9), which means Nginx cannot proxy data to Gunicorn, since Nginx is configured to connect via the localhost.

    • you mean gunicorn_config.py file ?

      • Yes. Otherwise you need to run the command with localhost as bind:
        gunicorn --bind 127.0.0.1:8001 ......

        • Oh. So I was binding my server ip not the 127.0.0.1:8001.

          Anyway thanks, i got it working now.

          • Awesome!
            You want to bind Gunicorn internally, and have Nginx do the connections between the visitor and Gunicorn, because it's much better at handling the load, but also serving static files.

        • I know this is not the proper place to ask this questions. Why don't we just use nginx to server django apps ? What's the role of gunicorn ? Actually I have a background in developing web apps in php and we don't have such things there. I hope you can understand my situation !

          Thanks

          • Of course you can ask that. It's your thread and we solved the problem.
            Actually there's no difference between PHP and Python (Django). With Nginx you would be running php-fpm through a port or a socket, just like you're doing with Gunicorn.
            Gunicorn is the process manager, that makes sure the Python script is executed and returned to Nginx.

          • @ozwiz

            In a way, PHP actually does. PHP has a built-in web server which can be ran by using the command below. It functions much like the web servers that are built in to other languages such as NodeJS and even Python, though you don't want to run it on its own as it's not meant to be used in such a fashion.

            php -S 0.0.0.0:80 -t /path/to/directory
            

            So instead of using the above, we use NGINX + fastcgi_pass to pass on each request to PHP-FPM. In this case, NGINX is our web server and is handling our requests while PHP-FPM is the process manager that spawns according to the requests being processed.

            Likewise, we use Gunicorn to manage processes with Python. NGINX is still the web server and handles the HTTP/HTTPS aspect of our stack and then hands it off to Gunicorn to do what it does best. Since NGINX doesn't have built-in support for Gunicorn (like it does fastcgi), we use proxy_pass to proxy each of the incoming requests over.

            It's essentially the same concept, just a different language.

@hansen @jtittle Thanks for clarifying the issue.

Have another answer? Share your knowledge.