python - How to deploy Flask+Gunicorn+Nginx+supervisor on a cloud server?
<p>I've read a lot of instructions since yesterday about this issue but all of them have similar steps. However I followed step by step but still can't get everything Ok.</p>

<p>Actually I can make Flask+Gunicorn+supervisor working but Nginx is not working well.</p>

<p>I connect my remote cloud server with SSH and I'm not deploying the site on my computer.</p>

<p>Nginx is installed correctly because when I visit the site via the domain name (aka. <code>example.com</code>) it shows the Nginx welcome page. </p>

<p>I use <code>supervisor</code> to start Gunicorn and the configuration is</p>

<pre><code>[program:myapp]
command=/home/fh/test/venv/bin/gunicorn -w4 -b 0.0.0.0:8000 myapp:app
directory=/home/fh/test
startsecs=0
stopwaitsecs=0
autostart=false
autorestart=false
stdout_logfile=/home/fh/test/log/gunicorn.log
stderr_logfile=/home/fh/test/log/gunicorn.err
</code></pre>

<p>here I bind the server to port <strong>8000</strong> and <strong>I don't actually know what does 0.0.0.0 stand for but I think it doesn't mean the localhost because I can visit the site via <em><a href="http://example.com:8000" rel="nofollow">http://example.com:8000</a></em> and it works well.</strong></p>

<p>Then I tried to use Nginx as a proxy server.</p>

<p>I deleted <code>/etc/nginx/sites-available/default' and '/etc/nginx/sites-enabled/default/</code> and created <code>/etc/nginx/sites-available/test.com</code> and <code>/etc/nginx/sites-enabled/test.com</code> and symlink them.</p>

<p><code>test.com</code></p>

<pre><code>server {
        server_name www.penguin-penpen.com;
        rewrite ^ http://example/ permanent;
}

# Handle requests to example.com on port 80
server {
        listen 80;
        server_name example.com;

        # Handle all locations
        location / {
                # Pass the request to Gunicorn
                proxy_pass http://127.0.0.1:8000;

                # Set some HTTP headers so that our app knows where the request really came from
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}
</code></pre>

<p>To my understanding, what Nginx do is when I visit <code>http://example.com</code> it passes my request to <code>http://example.com:8000</code>.</p>

<p>I'm not quite sure that I should use <code>proxy_pass http://127.0.0.1:8000</code> here because I don't know whether should Nginx pass the request to localhost <strong>But I 've tried to change it to <code>0.0.0.0:8000</code> but it still doesn't work.</strong></p>

<p>Can anyone help?</p>

<p><code>0.0.0.0</code> means the server will accept connections from all IP address. See <a href="https://en.wikipedia.org/wiki/0.0.0.0" rel="nofollow">https://en.wikipedia.org/wiki/0.0.0.0</a> for more detail.</p>

<p>If the gunicorn server listens on <code>127.0.0.1</code>, only you (or someone else on the same machine with gunicorn server) can access it through local loop <a href="https://en.wikipedia.org/wiki/Local_loop" rel="nofollow">https://en.wikipedia.org/wiki/Local_loop</a>.</p>

<p>But since you use Nginx to accept connection from the internet, you can just <code>proxy_pass http://127.0.0.1:8000;</code> and change the command to <code>command=/home/fh/test/venv/bin/gunicorn -w4 -b 127.0.0.1:8000 myapp:app</code>. In this scenario, gunicorn itself only need to accept connections from Nginx which runs on the same machine with gunicorn.</p>

<p>The whole process looks like this</p>

<pre><code>Connections from the Internet -&gt; Nginx (reverse proxy, listen on 0.0.0.0:80) -&gt; Gunicorn (which runs your Python code, listen on 127.0.0.1:8000)
</code></pre>

python nginx web flask server