Hello World with Nginx + uWSGI + Flask on GCE Ubuntu 18.04


Goal

  • Do a Hello World with a minimal web server.

Steps

  1. Set up a VM in the cloud.
  2. Install necessary tools.
  3. Create an app.
  4. Establish connection with WSGI protocol.
  5. Set up an web server.
  6. Tada!

1. Set up a VM in the cloud

Create a GCE f1-micro instance.

  • Required:
    • Somewhere in the U.S. for using free tier.
    • Allow HTTP traffic.
  • This time in GUI.
  • Using Ubuntu 18.04.

2. Install necessary tools

$ curl https://sdk.cloud.google.com | bash
$ exec -l $SHELL
$ gcloud init
  • SSH into the VM.
    • We don't have to remember this command, as it's shown in the web console.
    • Go to the instances list page, click triangular icon right next to the SSH button, and then click view gcloud command.
$ gcloud compute --project "YOUR_PROJECT_ID" ssh --zone "us-east1-b" "YOUR_INSTANCE_NAME"
  • Update the package manager and installed packages.
$ sudo apt update
$ sudo apt upgrade

3. Create an app

  • Install python3.
    • This enables the pip3 command.
$ sudo apt install python3 python3-dev python3-pip
  • Install virtualenv (may not be needed).
$ sudo apt install python3-vitualenv
  • Install Flask and uWSGI with pip3 (this time not apt).
$ sudo pip3 install flask
  • Create a Flask template file in the current directory.
~/hello.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"

if __name__ == "__main__":
    app.run()
  • Tell Flask about the app.
$ export FLASK_APP=hello.py

4. Establish connection with WSGI protocol.

  • Install uWSGI.
$ sudo pip3 install uwsgi
  • Create an uWSGI ini file.
~/uwsgi.ini
[uwsgi]

socket = /tmp/uwsgi.sock
chmod-socket = 666

chdir = %d
wsgi-file = /home/YOUR_USER_NAME/hello.py
module = hello:app
callable = app

master = 1
processes = 1

logto = /var/log/uwsgi/uwsgi.log
  • Create a service definition for systemd.
    • Restart = always allowed?
    • ExecStart should be noted absolute.
/etc/systemd/system/uwsgi.service
[Unit]
Description = uwsgi

[Service]
Restart = no
ExecStart = /usr/YOUR_USER_NAME/.local/bin/uwsgi --ini=/home/YOUR_USER_NAME/uwsgi.ini
ExecReload = /bin/kill -s HUP ${MAINPID}
KillSignal = QUIT

[Install]
WantedBy = multi-user.target
  • Enable (auto-restart) and start uwsgi manually.
$ sudo systemctl enable uwsgi
$ sudo systemctl start uwsgi

5. Set up an web server.

  • Install Nginx.
$ sudo apt install nginx
  • Note that configuration files are located under /etc/nginx.
    • nginx.conf file is for global configuration and conf.d directory is for local one.
    • Any .conf file put here is included into nginx.conf.
      • Look inside nginx.conf and see an include directive.
$ ls /etc/nginx | grep conf
conf.d
fastcgi.conf
nginx.conf
  • Remove the default conf file.
$ sudo rm /etc/nginx/sites-enabled/default
  • Create an Nginx conf file.
    • uwsgi_pass directive specifies an unix socket.
    • For details, look at this article.
/etc/nginx/conf.d/hello.conf
server {
  listen 80 default_server;
  server_name _;

  location / {
    include uwsgi_params;
    uwsgi_pass unix:///tmp/uwsgi.sock;
  }
}
  • Enable and start Nginx.
$ sudo systemctl enable nginx
$ sudo systemctl start nginx

6. Tada!

  • Open the fixed IP address in browser.

  • That's it!

If something's wrong...

  • First, do an research by taking a look at:
    • on Nginx:
      • service status at $ systemctl status nginx
      • service declaration at /etc/systemd/system/uwsgi.service
      • conf files at /etc/nginx/nginx.conf or /etc/nginx/conf.d/hello.conf
    • on uWSGI:
      • log at /var/log/uwsgi/uwsgi.log (if specified in logto directive in ~/uwsgi.ini)
      • service status at $ systemctl status uwsgi
      • conf file at ~/uwsgi.ini
    • in general:
      • /var/log/syslog
      • $ history

References