In this tutorial, you will learn how to configure a Linux Server to host your Flask App. We will use Amazon Lightsail to get a Linux Server. You will take a baseline installation of a Linux distribution on a virtual machine and prepare it to host your web applications, including installing updates, securing it from a number of attack vectors, and installing/configuring web and database servers
This is part of a project that was required for the Udacity Full Stack Nano Degree Program.
Required
- Knowledge of some basic Linux Commands
- A terminal, I prefer git bash
- A flask app ready to be deployed
How to configure your Linux Server
Get a server from AWS Lightsaild
- Go to Amazon LightSail
- Create an account/sign in to your existing account
- Click Create an instance and choose
Linux/Unix
,OS only
andUbuntu 16.04LTS
4. Choose the cheapest Plan (3.5 USD/month). It is free for the first month so if you finish this tutorial within a month, you can delete the instance and won’t have to pay a dime unless you want to keep the instance.
5. Give the instance a host name. I have given mine Item-Catalog (Udacity Project’s name). Feel free to chose any name.
6. Click Create and wait a few minutes for it to start up
7. After a few seconds, the instance should be up and running.
Now, we can move on to trying to ssh into our newly created Linux machine.
SSH into the Linux Machine
- Go to your account and click on
SSH Keys
. Download the default key for your instance. The file name will be similar toLightsailDefaultKey-eu-central-1.pem
For this tutorial, I’ll download the private key for the first instance.
2. In the terminal Navigate to the downloaded file’s directory and restrict file permission by typing
chmod 600 LightsailDefaultPrivateKey-*.pem
This is your private key, do not share with anybody.
3. Rename the file to lightsail_key.rsa
for easy use.
4. SSH into your instance by typing the following (Change IP address accordingly)
ssh -i lightsail_key.rsa ubuntu@3.121.206.97
If successful, you should see the screen below
You are now logged in as ‘ubuntu’ in your instance.
Secure your Linux Instance
Update all currently installed packages
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get update && sudo apt-get dist-upgrad
Change the SSH port from 22 to 2200
- Edit the
sshd_config
file by typing:sudo nano /etc/ssh/sshd_config
- Search for the port number and change it from 22 to 2200. It will be near line 5.
- Restart SSH connection with
sudo service ssh restart
Configure the Uncomplicated Firewalll (UFW)
We should only allow incoming connections for SSH (port 2200), HTTP (port 80), and NTP (port 123)
.
First check the current ufw status, it should be inactive
sudo ufw status
Deny all incoming request
sudo ufw default deny incoming
Allow all outgoing requests
sudo ufw default allow outgoing
Allow the required incoming requests:
- to allow ssh requests
sudo ufw allow 2200/tcp
- to allow http requests
sudo ufw allow 80/tcp
- to allow ntp requests
sudo ufw allow 123/udp
- to deny requests from port 22
sudo ufw deny 22
Finally enable ufw and set it’s status to active
sudo ufw enable
Check the status
sudo ufw status
It should look something like this
Status: active
To Action From
-- ------ ----
2200/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
123/udp ALLOW Anywhere
22 DENY Anywhere
2200/tcp (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
123/udp (v6) ALLOW Anywhere (v6)
22 (v6) DENY Anywhere (v6)
12. Edit the rules accordingly in Networking in your lightsail account
You’ve secured your server and configure the firewall for proper functioning
If you are viewing this article to complete the final project in the Udacity Full Stack Nanodegree, follow the next steps else you may skip it and move on to ‘Prepare to Deploy your project’. You can follow the next steps if you want to create a new user.
Give Grader Access
- Create a new user account named
grader
sudo adduser grader
2. Give grader
the permission to sudo
sudo nano /etc/sudoers.d/grader
3. Type the following line grader ALL=(ALL:ALL) ALL
4. Create an SSH key pair for grader
using the ssh-keygen
tool. In your local machine, start up git bash and type ssh-keygen
. Set a file directory and passphrase and view the contents of the .pub file using the cat command. Copy the content.
sudo cat ~/.ssh/test.pub
- log in as grader and create a folder ssh in home directory.
mkdir .ssh
- Create a file authorized_keys
touch .ssh/authorized_keys
- Paste the content into the file and save it.
sudo nano .ssh/authorized_keys
- Restrict file permissions
chmod 700 .ssh
chmod 644 .ssh/authorized_keys
5. To disable password based login/ disable root login:
sudo nano /etc/ssh/sshd_config
Search for password based authentication and change it to no Search for PermitRootLogin and change the value to no. Restart the server.
sudo service ssh restart
You should now be able to log in with your private key and passphrase.
6. exit
and ssh -i ~/.ssh/grader -p 2200 grader@3.121.206.97\
You’ve created a new user, given them sudo access and created a SSH key pair for them
Prepare to deploy your project.
Configure the local timezone to UTC
sudo dpkg-reconfigure tzdata
Choose your timezone
Install Apache to serve a Python mod_wsgi application
- Install Apache
sudo apt-get install apache2
Check your public IP and it should display the default Apache web page. sudo apt-get install python-setuptools libapache2-mod-wsgi
Install python mod-wgsi module
Install and Configure PostgreSql
- Type
sudo apt-get install postgresql
to install postgresql - Log in as postgres
sudo su - postgres
- Enter psql shell by typing
psql
- Type the following Commands in the shell. I have named my database and user Catalog, you can name something else.
CREATE DATABASE Catalog;
CREATE USER Catalog;
ALTER ROLE catalog WITH PASSWORD 'grader';
GRANT ALL PRIVILEGES ON DATABASE catalog TO catalog;
Quit the shell \q
Exit postgres by typing exit
Install Git
- Type
sudo apt-get install git
to install git - Configure Email Id and Username:
git config --global user.name <username>
git config --global user.email <email>
- change directory to /var/www
cd /var/www
- Create a new folder.
sudo mkdir catalogApp
. This is where you’ll store your flask application and the .wsgi file. - cd into the folder
cd catalogApp
Clone and setup the project
- clone the required repo
sudo git clone https://github.com/rahulbanerjee26/Item-Catalog.git
Rename file to catalogApp or flaskApp. I am naming it catalogApp. - Go into the repo using cd and rename
app.py
to__init__.py
sudo mv app.py __init__.py
. Apache only recognizes __init__.py
3. In __init__.py
and databaseSetup.py
files, remove the sqlite connection and connect to postgresql database. engine = create_engine('postgresql://catalog:password@localhost/catalog')
Create and Configure a New Virtual Host
sudo apt-get install python-virtualenv
to install the virtual environment- cd into your repo and type
sudo virtualenv -p python3 venv3
sudo chown -R grader:grader venv3/
to change permission. venv3/bin/activate
to activate the environment- Install Flask and other dependencies as neede
sudo apt-get install python-pip
sudo pip install Flask
sudo pip install sqlalchemy oauth2client httplib2 requests
sudo apt-get install postgresql libpq-dev postgresql-client postgresql-client-common
deactivate
sudo nano /etc/apache2/sites-available/catalogApp.conf
- Add the following code in catalogApp.conf file. Change IP address, directories, DNS as required.
<VirtualHost *:80>
ServerName 3.121.206.97
ServerAlias http://ec2-3-121-206-97.eu-central-1.compute.amazonaws.com/
ServerAdmin banerjeer2611@gmail.com
WSGIScriptAlias / /var/www/catalogApp/catalogapp.wsgi
<Directory /var/www/catalogApp/catalogApp/>
Order allow,deny
Allow from all
</Directory>
Alias /static /var/www/catalogApp/catalogApp/static
<Directory /var/www/catalogApp/catalogApp/static/>
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
13. You can use this link find the DNS of your IP address to add the value for ServerAlias
14. sudo a2ensite catalogApp.conf
15. Setup the dataBase sudo python databaseSetup.py
16. Reload apache2 sudo service apache2 reload
Create .wgsi file
sudo nano /var/www/catalogApp/catalogapp.wsgi
- Paste the following and save the file:
activate_this = '/var/www/catalogApp/catalogApp/venv3/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this)) #!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,"/var/www/catalogApp")
from catalogApp import app as application
application.secret_key = 'my_secret_key'
3. Go to __init__.py
and change the path of the client_secrets.json
from relative to absolute if necessary.
4. Run sudo service apache2 restart
5. If you get an error, sudo tail /var/log/apache2/error.log
to view the error log.
If you go to your public IP, you’ll be able to view your flask application.
Congratulations 👏 👏 👏 👏
You’ve successfully deployed your application
Common Commands
If you make any changes in the .config file, you’ll need to restart the server
sudo service ssh restart
to reload apache
sudo service apache2 reload
to restart apache
sudo service apache2 restart
to read files
sudo cat fileDestination
to write into files
sudo nano fileDestination
to view error logs
sudo tail /var/log/apache2/error.log
the directory of your repo
/var/www/catalogApp/catalogApp
the directory where your virtual host config file
/etc/apache2/sites-available/catalogApp.conf
the directory of your .wsgi file.
/var/www/catalogApp/catalogapp.wsgi