Andy

Table of contents

Installation

Before jumping into the installation process, we have to give credit to Miguel Grinberg and his book The Flask Mega-Tutorial which is the source for the installation instructions (starting in Chapter 17.). Feel free check the main source which also includes the deploy instructions of Flask apps for the raspberry pi and docker containers.

To deploy the sTudoo application please make sure to follow the steps below.

1. Get a Server

To run sTudoo in production, a server is needed. So make sure that you have a functional server up and running. The provided command should work on the most linux based servers. Please make sure that the package manager used in the following commands is apt. If the distribution you’re using is using a different package manager (i.e. Fedora -> dnf) ensure that you adapt the commands for your case.

Possible solutions for installing a server are provided by Linode, Digital Ocean or Amazon Lightsail.

Please follow the Documentation of the provider to install the virtual server and make sure you have the IP and the root password of your server.

2. SSH into the server

Open your terminal of choice and ssh into the server.

$ ssh root@<ip-of-your-server>

Type in your password after the prompt.

3. Create an account for deployment work

Create a new user.

$ adduser --gecos "" your_user_name

Give the user sudo permissions.

$ usermod -aG sudo your_user_name

Login as the user you’ve created

$ su your_user_name

3.1. Creating a public key

To log in without typing a password we will use a public key authentication. To do so, we will use a second terminal on your own machine. Leave the first (server) terminal session open though.

ls into the ~/.shh directory.

$ ls ~/.ssh

id_rsa id_rsa.pub

If id_rsa & id_rsa.pub are listed like above, you already have a key.

If the directory itself or the files are missing run the following command to create a SSH keypair.

$ ssh-keygen

Accept the following prompts by pressing enter. After the command has run the mentioned files should have been created. The id_rsa.pub file is the public key (which is provided to third parties to get identified). The id_rsa is the private key and shouldn’t be shared with anyone.

3.2. Configuring the public key as an authorized host

In the next step we’re going to configuire the public key as an authorized host in the server.

Print the public key on your machines terminal (not the server).

$ cat ~/.ssh/id_rsa.pub

ssh-rsa Alaksjdkfjjoi2..............3870asjd20ß23r8zz8ß1´="=

The output of the command should be a long cryptic string of characters as shown under the command above.

Copy the string to your clipboard, switch to the terminal of the remote server and import the key with the following command.

$ echo <copy-your-key-here> >> ~/.ssh/authorized_keys

$ chmod 600 ~/.ssh/authorized_keys

The passwordless loging should now be working every time your log in with ssh.

4. Installing Base Dependencies

To create a production-ready deployment make sure that the server and it’s packages are up to date.

$ sudo apt-get -y update

Install Python and the python related packages.

$ sudo apt-get -y install python3 python3-venv python3-dev

In the follwing stepp we will install the MySQL server, supervisor (a tool that monitors Flask’s server process), the Ngnix server (accepts requests and forwards them to the app) and Git to download the app from Github. During the MySQL installation a root password has to be set.

$ sudo apt-get -y install mysql-server supervisor ngnix git

5. Install the sTudoo app

Navigate into the home directory.

$ cd /home/

Download the app with git clone.

$ git clone https://github.com/andrej-moor/studoo

Change into the the directory.

$ cd studoo

Create the virtual invironment.

$ python3 -m venv venv

Activate the virtual environment.

$ source venv/bin/activate

Install the package dependencies from requirements.txt via pip.

(venv) $ pip install -r requirements.txt

Install Gunicorn which is a production webserve for pyhton apps.

(venv) $ pip install gunicorn

Generate your own secret key string and copy it to the clipboard.

python -c "import uuid; print(uuid.uuid4().hex)"

12dfb585fb2a4b1da206f06cf09f0956

Create an .env file for environment viables. And open it with the texteditor nano.

(venv) $ touch .env
(venv) $ nano .env

First, enter the generated key string into the file. Afterwords enter the database url. Choose a password and enter it isnstead on <db-password>. Save the password, we will use it later in the MySQL settings.

SECRET_KEY=12dfb585fb2a4b1da206f06cf09f0956

DATABASE_URL=mysql+pymysql://studoo:<db-password>@localhost:3306/studoo

Save the file with str+o and close it with str+q.

Set the FLASK_APP environment variable to the entry point of the app, adding it to the .profile file of the user account. It will be set atomatically everytime one logs in.

$ echo "export FLASK_APP=studoo.py" >> ~/.profile

6. Set up MySQL

To manage multiple request at a time in production a MySQL database will be implemented.

Login in into MySQL as a root user.

$ sudo mysql -u root 

Create a database called classes and a user with the same name with full acces. Enter the password from the .env file you’ve chosen insteat of <db-password>.

mysql> create database classes caracter set utf8 collate utf8_bin;
mysql> create user 'studoo'@'localhoast' identified by '<db-password>';
mysql> grant all provileges on classes.* to 'studoo'@'localhost';
mysql> flush privileges;
mysql> quit;

Run the database migrations that creates all the tables.

(venv) $ flask db upgrade

7. Set up Gunicorn & Supervisor

Create a config file for the installed Supervisor package which will be reponsible for managing the Unicorn application webserver’s processes.

$ touch /etc/supervisor/conf.d/studoo.conf

Add the following settings to it, by opening it with the nano editor.

$ nano /etc/supervisor/conf.d/studoo.conf

[program:studoo]
command=/home/studoo/studoo/venv/bin/gunicorn -b localhost:8000 -w 4 studoo:app
directoray=/home/studoo/studoo
user=studoo
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true

Reload the suvervisor service.

$ sudo supervisorctl reload

8. Set Up Ngnix

To handle external web traffic let us set up the public facing Ngnix server.

First we will create a self-signed SSL certificate. After creating a directory in the root directory of the app.

Enter all the asked information, because they will be included in the SSL certificate.

$ mkdir certs
$ openssl req -new -newkey rsa:4096 -day 365 - nodes -x509 \
  - keyout certs/key.pem -out certs/cert.pem

Make sure that you nee a “real” certificat by a trusted autority, otherwise users will receive warnings from the browser, that the certificate can’t be trusted. Include the appropriate files (key.pem & cert.pm) in the directories mentioned in the Ngnix config file when have your domain set up and the ssl key available.

Next, delete the preinstalled test site created as a default by Ngnix.

$ sudo rm /etc/ngnix/sites-enabled/default

Create a new config file,

$ touch /etc/ngnix/sites-enabled/studoo

open it with nano and add the followed content to it.

$ nano /etc/ngnix/sites-enabled/studoo
server {
  # listen on port 80 (http)
  listen 80;
  server_name_;
  location / {
    # redirect any rerequest to the same URL but on https
    return 301 https://$host$request_uri:
  }
}

server {
  # listen on port 443 (https)
  listen 433 ssl;
  server_name_;

  #location of the self-signed SSL certificate 
  ssl_certificate /home/studoo/studoo/certs/cert.pem;
  ssl_certificate_key /home/studoo/studoo/certs/key.pem;

  # write acces and error logs to /var/log
  acces_log /var/log/studoo_access.log;
  error_log /var/log/microblog:error.log;

  location / {
    #forward application request to the gunicorn server
    proxy_pass http://localhost:800;
    proxy:redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
  }

  location /static {
    # handle static files directly, without forwarding them to the application
    alias /home/studoo/studoo/app/static;
    expired 30d;
  }
}

Now, we have to reload the config and activate it.

$ sudo service ngnix reload

Congrats, your sTudoo instance is now deployed and usable.