This project outlines the installation of a Linux server and prepare it to host a web applications, install and configure a database server, and deployment.
- IP Address:
- SSH Port: 2200
- URL:
- Amazon Lightsail
- Configuring Linux Web Servers
- How To Deploy a Flask Application on an Ubuntu VPS
- Flask
- SQLAlchemy - PostgreSQL
- Google Oauth 2 Authentication
- Go to Ligthsail
- Click Create an AWS Account (yellow button, upper right-hand corner)
- Choose an instance image: Ubuntu
- Choose your instance plan
- Give your instance a hostname
- Wait for it to start up
- It's running on IPls
t
with the namelinux-catalog
. - Obtain DNS name using the xip.io service (for OAuth set up). I will use
<URL>
. (set up DNS Zone in Lightsail) - Connect using SSH button and update all currently installed packages.
- Type
sudo apt-get update
- Type
sudo apt-get upgrade
- Type
- Type
sudo adduser grader
- Confirm new user using Finger
- Type
sudo apt-get install finger
- Type
finger grader
- Type
- Give
grader
sudo.- Type
sudo nano /etc/sudoers.d/grader
- Enter
grader ALL=(ALL) NOPASSWD:ALL
and save file.
- Type
- On local machine, generate key pairs:
- Type
ssh-keygen
- Type
- Enter file in which to save the key.
- Enter passphrase.
- Private and Public key will be saved on local machine in separte files (NOTE: public file has the same name as the private key, but with .pub on the end)
- Log into server and change to
grader
- Type
su - grader
and enter password at prompt to switch tograder
- Type
- In the home directory, add
.ssh
directory- Type
mkdir .ssh
- Type
- Create file to store public key
- Type
nano .ssh/authorized_keys
- Copy public key from local machine and paste into the file and save.
- Type
- Change permission for .ssh directory and ssh key file:
- Type
chmod 700 ~/.ssh
- Type
chmod 644 ~/.ssh/authorized_keys
- Type
- Disable password based login
- Type
sudo nano /etc/ssh/sshd_config
- Find 'Port 22' and change 22 to 2200
- Find 'PasswordAuthentication yes' in the file and change 'yes' to �no�
- Save and close file.
- Type
- Type
sudo ufw default deny incoming
- TYpe
sudo ufw default allow outgoing
- Allow ssh by typing
sudo ufw allow ssh
- Allow access on port 2200 by typing
sudo ufw allow 2200/tcp
- Allow HTTP by typing
sudo ufw allow http
- Allow access on port 123 by typing
sudo ufw allow 123/udp
- Enable firewall by typing
sudo ufw enable
- Restart ssh service
- Type
sudo service ssh restart
- Type
- In Lightsail (on you server), go to the Networkingtab to update Firewall settings:
- Add Custom TCP 2200
- Add Custom UDP 123
- Save updates.
- From local machine, verify you can SSH into server using port 2200:
- Type
ssh grader@<IP Address> -p 2200 -i ~/.ssh/linuxProject
- Enter passphrase for key
- Successfully logged in as
grader
via SSH
- Type
- In Lightsail (on you server), go to the Networking tab to edit Firewall settings:
- Remove SSH TCP 22
- Configure the local timezone to UTC.
- Type
sudo dpkg-reconfigure tzdata
- Scroll to the bottom of the Continents list and select None of the above
- In the second list, select UTC source: https://askubuntu.com/questions/138423/how-do-i-change-my-timezone-to-utc-gmt
- Type
- Install apache
- Type
sudo apt-get install apache2
- Type
- Install and Enable mod_wsgi
- Type
sudo apt-get install libapache2-mod-wsgi
- Type
sudo a2enmod wsgi
- Type
- Install git
- Type
sudo apt-get install git
- Type
- Create app
- Type
cd /var/www
- Type
sudo mkdir CatalogApp
- Type
cd CatalogApp
- Clone repository from Catalog Project (completed earlier in course)
- Type
sudo git clone https://github.com/MKing301/catalog.git CatalogApp
- Type
- Rename
catalog_app.py
to__init__.py
- Type
cd CatalogApp
- Type
sudo mv catalog_app.py __init__.py
- Type
- Type
- Make sure that your .git directory is not publicly accessible via a browser (see here)
- Install PIP
- Type
sudo apt-get install python-pip
- Type
- Install virtualenv
- Type
sudo pip install virtualenv
- Type
- Name virtual environment
- Type
sudo virtualenv venv
- Type
- Activate vitual environment
- Type
source venv/bin/activate
NOTE: (venv) will appear at begining of line
- Type
- Install Flask here
- Type
sudo pip install Flask
- Type
- Type
deactivate
to exit virtual environment
- Install all of the following:
- Type
sudo apt-get install python-psycopg2
- Type
sudo pip install psycopg2-binary
- Type
sudo pip install SQLAlchemy
- Type
sudo pip install Flask-SQLAlchemy
- Type
sudo pip install requests
- Type
sudo pip install httplib2
- Type
sudo pip install flask_httpauth
- Type
sudo pip install oauth2client
- Type
- Type
sudo nano /etc/apache2/sites-available/CatalogApp.conf
- Edit file to contain the following:
<VirtualHost *:80> ServerName <your server name> ServerAdmin admin@<your server name>.com WSGIScriptAlias / /var/www/CatalogApp/catalogapp.wsgi <Directory /var/www/CatalogApp/CatalogApp/> Order allow,deny Allow from all </Directory> Alias /templates /var/www/CatalogApp/CatalogApp/templates <Directory /var/www/CatalogApp/CatalogApp/templates/> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
- Save and close file.
- Create wsgi file.
- Type
cd /var/www/CatalogApp
- Type
sudo nano catalogapp.wsgi
- Add the following lines in the file:
NOTE: Obtain secret key (check here)
#!/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 = 'super secret key'
- Type
- Disable default:
- Type
sudo a2dissite 000-default.conf
- Type
- Add ip and host
- Type
sudo nano /etc/hosts
- Add
<IP Address> <your server name>
- Type
- Enable virtual host:
- Type
sudo a2ensite CatalogApp
- Type
- Restart apache
- Type
sudo service apache2 restart
- Type
- Type
sudo apt-get install postgresql
to install - Type
sudo -u postgres psql postgres
to access postgreSQL - Type
\password postgres
to set the password - Type
CREATE DATABASE catalog;
to create the database - Type
\c catalog
to connect to the database - Create user catalog by typing
Create a user with: postgres=# CREATE USER <username> WITH PASSWORD '<password>';
- Grant user catalog permission to database catalog:
- Type
GRANT ALL PRIVILEGES ON DATABASE <database name> TO <username>;
- Type
- Type
\q
thenENTER
to exit postgreSQL - Reload postgresql by type
sudo /etc/init.d/postgresql reload
- Enter virtual environment to load table and initial data for the database:
- Type
cd /var/www/CatalogApp/CatalogApp
- Type
source venv/bin/activate
- Type
sudo python database_setup.py
- Type
sudo python initial_data.py
- Type
- Remove Vagrantfile and categories_books_users.db files
- Update the following variables:
- From
CLIENT_ID = json.loads(open('client_secrets.json', 'r').read())['web']['client_id']
- To
CLIENT_ID = json.loads(open('/var/www/CatalogApp/CatalogApp/client_secrets.json', 'r').read())['web']['client_id']
- From
app_id = json.loads(open('fb_client_secrets.json', 'r').read())['web']['app_id']
- To
app_id = json.loads(open('/var/www/CatalogApp/CatalogApp/fb_client_secrets.json', 'r').read())['web']['app_id']
- From
app_secret = json.loads(open('fb_client_secrets.json', 'r').read())['web']['app_secret']
- To
app_secret = json.loads(open('/var/www/CatalogApp/CatalogApp/fb_client_secrets.json', 'r').read())['web']['app_secret']
- From
oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='')
- To
oauth_flow = flow_from_clientsecrets('/var/www/CatalogApp/CatalogApp/client_secrets.json', scope='')
- From
- Change 2 print statements:
- From
print ('No User ID found.')
- To
nouseridfile = open("/var/www/CatalogApp/CatalogApp/nouseridfile.txt", "a") nouseridfile.write('No User ID found') nouseridfile.close()
NOTE: Had to give file permissions (see here) - From
print 'Access Token is None'
- To
notokenfile = open("/var/www/CatalogApp/CatalogApp/notokenfile.txt", "a") notokenfile.write('Access Token is None') notokenfile.close()
NOTE: Had to give file permissions (see here)
- From
- Add the following parameters to the book and category tables foreign keys:
onupdate='CASCADE', ondelete='CASCADE'
- Changed connection to database from sql to postgres in database_setup.py, initial_data.py and init.py:
- From
sqlite:///categories_books_users.db
- To
postgres://catalog:<password here>@localhost/catalog
- From
- Download and update Google API JSON file (client_secrets.json)
- Removed Facebook Oauth Authentication NOTE: Facebook now enforce HTTPS (see here)