/Featurester

A Flask web application for making and recording requests.

Primary LanguagePython

A feature request manager

Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system.

Prerequisites

Tech Stack Requirements

  • OS: Ubuntu 18.04
  • Server Side Scripting: Python 3.6.6
  • Development Server: Flask
  • Production Server: Gunicorn ( Internal), NginX (External)
  • ORM: Flask-SQLAlchemy
  • JavaScript: JQuery
  • CSS Framework: BootStrap 4

Python Packages

The python dependencies are tracked in the requirements.txt file. I will list the major dependencies.

  • Flask
  • Flask-Moment
  • Flask-Bootstrap
  • Flask-SQLAlchemy

Database Management System

  • Local: Postgres 9.6.6
  • Deployment: MySQL 5.4
  • Testing: Sqlite3

Setup

  1. 1nstall python 3.6.6 and python-virtualenv
    $ sudo apt-get python3 python3-venv python3-dev
  1. Pull the project from github. Navigate to a suitable directory and run the following commands.
    $ git clone https://github.com/Miravicson/Featurester.git
  1. Create a virtualenvironment called venv. Navigate inside the folder Featurester that you have pulled from github and create a virtual environment by running the commands below.
    $ python -m venv venv
  1. Activate the virtualenv
    $ source venv/bin/activate
  1. Install the dependencies. inside the Featurester folder is a file requirements.txt that specifies all the python packages neede for the project to run. Install the dependencies by running the following command
    (venv) $ python install -r requirements.txt
  1. Setup the Database. Create a postgres database with the name requester flask associated with the username flask and choose a password <db-password>

  2. Create a .env file. The .env file should follow the template in the file Featurester/local/.localenv

  3. Upgrade the database. Run the command below

    (venv) $ flask db upgrade
  1. Export the FLASK_APP=featurester.py to the environment variable
    $ export FLASK_APP=featurester.py
  1. Run the application. Activate the virtual environment and run the command below.
    (venv) $ flask run

Running the tests

To run test, activate the virtual environment and run the following command

    $ python manage.py test --coverage

A report of the test coverage will be displayed on the terminal. Also an interactive HTML report which can be opened in the browser is created in the folder Featurester/tmp/coverage open the index.html file in the folder with the browser to view the html report.

Break down into end to end tests

Explain what these tests test and why

Give an example

And coding style tests

Explain what these tests test and why

Give an example

Deployment

The application was deployed on Digital Ocean Linux VPS. Gunicorn was used as an internal server and NginX was used for the external server. setting up and configuration of the server was done largely through SSH after which

Creating an Ubuntu Server and connecting to the ubuntu server

  1. Create an Ubuntu Servr with Digital Ocean and add your local machine's SSH keys to the Ubuntu VPS through the digital ocean dashboard. Note the IP address of the server created.

  2. Open up a local terminal on your linux PC and type the following command to gain access to your remote Ubuntu VPS via Secure Shell SSH

    $ ssh root@<server-ip-address>

Activating Passwordless Login to the Ubuntu Server

  1. Create a user account named ubuntu or whichever name you prefer and give sudo privileges to the account.
    $ add user --gecos "" ubuntu  # creating ubuntu account
    $ usermod -aG sudo ubuntu      # add account to sudo group
  1. On your local machine, open a second terminal and confirm that your ssh keys has been generated by running the command:
    $ ls ~/.ssh
    $  id_rsa id_rsa.pub       # Output showing you have generated an ssh key
  1. If you don't get an outpu like the above, you will need to generate an ssh key. Run the command below and follow the prompt to generate your ssh key
    $ ssh-keygen
  1. The ssh keys will be generated in the folder ~/.ssh and they wil be stored in the files id_rsa.pub (The public key) and id_rsa (The private key)

  2. On the local terminal (your machine terminal), print the public key to the terminal in order to copy it by running the command:

    $ cat ~/.ssh/id_rsa.pub
  1. Copy the output displayed to the clipboard

  2. Switch over to the server terminal (ssh terminal) and run the following commands to add your ssh key to the authorised_keys of the server.

    $ echo <paste-your-key-here> >> ~/.ssh/authorised_keys
    $ chmod 600 ~/.ssh/authorised_keys
  1. Logout from the root session.

  2. You can log in straight to the ubuntu account by typing the following commands on a local terminal

    $ ssh ubuntu@<server-ip-address>

Securing your server [ Optional ]

Two main steps will be taken to secure the server

  • Disable root login over ssh
  • Disable password login

To achieve this follow the steps below

  1. Login to your ubuntu server
  2. Edit the file at the location /etc/ssh/sshd_config
    $ sudo nano /etc/ssh/sshd_config

  1. On the editor, locate the lines that contain PermitRootLogin and PasswordAuthentication and modify them to appear this way
    PermitRootLogin no
    PasswordAuthentication no
  1. Restart the ssh service by running
    $ sudo service ssh restart

Setting up Firewall [Optional]

Firewalls help protect the server and restricts the connection modes to the server. I used Uncomplicated Firewall (ufw) for this. Install ufw on the server and setup the allowed connection ports -- ssh (port 22), http (port 80), https (port 443).

    $ sudo apt-get install -y ufw
    $ sudo ufw allow ssh
    $ sudo ufw allow http
    $ sudo ufw allow 443/tcp
    $ sudo ufw --force enable
    $ sudo ufw status

Installing Base Dependencies

Here is a list of base dependencies for the server:

  • Python 3.6.6
  • Python-venv
  • Git
  • MySQL
  • Postfix
  • NginX
  • Supervisor

Install python and python dependencies by running the following command on the server terminal.

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

Install the other dependencies by running the following command

    $ sudo apt-get -y install mysql-server postfix supervisor nginx git

Installing the Application

clone the code from the Github repository and navigate to the directory

    $ git clone https://github.com/Miravicson/Featurester.git
    $ cd Featurester

create a virtual environment and populate it with all the package dependencies,

    $ python -m venv venv
    $ source venv/bin/activate
    (venv) $ pip install -r requirements.txt

A template of the .env file needed is included here in the deployment/.serverenv file, copy the contents deployment/.serverenv template from the deployment folder and paste into a .env file in the Featurester folder. Modfiy the template accordingly.

To create a strong secrete key value, run the following command

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

Set up the FLASK_APP environment variable to the entry point of the application to enable the flask command work.

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

Setting up a MySQL Database

Login to MySQL

    $ sudo mysql -u root

Reset the password to whatever password you want

    mysql> UPDATE mysql.user SET authentication_string=PASSWORD('<your-password>') WHERE user='root';

Creating a Database

    mysql> create database requester character set utf8 collate utf8_bin;

    mysql> create user 'featurester'@'localhost' identified by '<enter-a-database-password>';
    mysql> grant all privileges on requester.* to 'featurester'@'localhost';

    mysql> flush privileges;

    mysql> quit;

modify the .env file and set the DATABASE_URL environment variable

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

Upgrade the database by running the command

    (venv) flask db upgrade

Setting up Gunicorn and Supervisor

Create a configuration file for the supervisor

    $ sudo touch /etc/supervisor/conf.d/featurester.conf

Modify the contents of the featurester.conf to be exactly the same as the file in Featurester/deployments/supervisor/featurester.conf.

Reload the supervisor server by running

   $ sudo supervisorctl reload

Setting up NginX

I created a self-signed SSL certificate on the server

Navigate in to the Featurester folder and create a folder named certs

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

We need to write a default configuration file in order to have the website served by NginX. You first need to delete the default configuration file that comes with NginX

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

create a configuration for nginx and call it featurester

    $ sudo touch /etc/nginx/sites-enabled/featurester

Edit the file /etc/nginx/site-enabled/featurester to contain the same contents as the file Featurester/deployments/nginx/featurester

Start the nginx service by running

    $ sudo service nginx reload

Deploying application updates

When you have made changes and pushed to github, you may update the server by signing in to the server and running the following commands

(venv) $ git pull                              # download the new version
(venv) $ sudo supervisorctl stop featurester     # stop the current server
(venv) $ flask db upgrade                      # upgrade the database
(venv) $ sudo supervisorctl start featurester    # start a new server

Authors

  • Victor Ughonu