This Udacity project is to configure a Linux server in a Ubuntu instance on AWS Lightsail. And then to deploy the web app that was built here.
IP address: 18.219.3.185
18.188.54.6
SSH port: 2200
URL: http://project.emilyzhang.work
apt-get update
apt-get upgrade
To automatically update, use unattended-upgrades package
cd
to /etc/ssh
, sudo nano sshd_config
Find the line PermitRootLogin
, change from prohibit-password
to no
.
Restart ssh server: sudo service ssh restart
Connect to server: ssh <username>@<lightsail_public_ip> -i <path_to_your_private_key> -p 2200
.
Check the status of the firewall: sudo ufw status
Block all incoming connections on all ports: sudo ufw default deny incoming
Allow outgoing connection on all ports: sudo ufw default allow outgoing
Allow incoming connection for SSH on port 2200: sudo ufw allow 2200/tcp
Allow incoming connections for HTTP on port 80: sudo ufw allow www
Check the rules that have been added before enabling the firewall use: sudo ufw show added
Enable the firewall: sudo ufw enable
Lightsail accepts port 22 and 80 by default. You need to set up Lightsail to accept 2200 connection. Log into Amazon Lightsail homepage, click your instance. Then find "Networking", under "Networking", find "Firewall". Under "Firewall", click "+ Add another": make sure the Port range is 2200.
Now change SSH port 22 to 2200: sudo nano /etc/ssh/sshd_config
, change Port 22
to Port 2200
.
Restart SSH server: sudo service ssh restart
.
Connect to server: ssh <username>@<lightsail_public_ip> -i <path_to_your_private_key> -p 2200
.
Diable SSH port 22: sudo ufw deny 22
.
sudo adduser grader
sudo nano /etc/sudoers.d/grader
. Then write grader ALL=(ALL) NOPASSWD:ALL
into the file.
As root user, on server, create a folder: mkdir /home/grader/.ssh
On your local machine, generate a key pair: ssh-keygen
Install public key on server, as user grader
:
touch .ssh/authorized_keys
nano .ssh/authorized_keys
Read out the content of public key file on your local machine, copy and then paste to .ssh/authorized_keys
file on your server. Then
save it.
Now log into the server as grader: ssh grader@<lightsail_public_ip> -i <path_to_your_private_key> -p 2200
.
On server, as grader, force key based authentication: sudo nano /etc/ssh/sshd_config
, change PasswordAuthentication
to no
. Then save it.
On server, as grader, then modify file permission: chmod 700 .ssh
, chmod 600 .ssh/authorized_keys
.
Helpful resource: Add new user in Linux instance
Configure local timezone to UTC: sudo timedatectl set-timezone UTC
Install Apache: sudo apt-get install apache2
Configure Apache to serve a Python mod_wsgi application: sudo apt-get install libapache2-mod-wsgi
. If you're coding in Python3, then:
sudo apt-get install libapache2-mod-wsgi-py3
Install Postgresql: sudo apt-get install postgresql postgresql-contrib
.
Create a PostgreSQL user catalog
: sudo -u postgres createuser -P catalog
. You will be prompted for a password.
Create an database catalog
whose owner is user catalog
: sudo -u postgres createdb -O catalog catalog
.
Hepful resource: PostgreSQL official documents Create database user, Create database
sudo apt-get install python-psycopg2
sudo apt-get install python-flask
sudo apt-get install python-sqlalchemy
sudo apt-get install python-pip
sudo pip install oauth2client
sudo pip install requests
sudo pip install httplib2
sudo apt-get install git
cd /var/www/
sudo mkdir fullstack-nanodegree-vm
sudo chown www-data:www-data fullstack-nanodegree-vm/
sudo -u www-data git clone https://github.com/eqlz/fsnd-project-mgt-app.git fullstack-nanodegree-vm
Make .git
file inaccessible: sudo nano .htaccess
, add a line of RedirectMatch 404 /\.git
into the file. Then save it.
Set your directory structure look like this, this is what my directory looks like on my server:
/var/www/fullstack-nanodegree-vm/
--------------------------------catalog
---------------------------------------catalog
----------------------------------------------__init__.py
----------------------------------------------models.py
----------------------------------------------static
----------------------------------------------templates
----------------------------------------------client_secrets.json
---------------------------------------catalog.wsgi
Folder structure:
- Under
fullstack-nanodegree-vm
, there is only one item, foldercatalog
. - Under first
catalog
folder, there are two items, foldercatalog
, filecatalog.wsgi
. - Under second
catalog
folder, put all the catalog project files there. - It's necessary to have two
catalog
folders, and are structured in this way.
Helpful resource: How to deloy a Flask application on an Ubuntu VSP
Location: see directory structure above, under the first catalog
file
Command: sudo nano catalog.wsgi
Content:
#!/usr/bin/python
import sys
import logging
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/var/www/fullstack-nanodegree-vm/catalog/") # pay attention to the path, yours may be different from mine.
from catalog import app as application
application.secret_key = 'YOUR_SECRET_KEY'
From the folder structure above, you'll notice there is an __init__.py
file under the second catalog
folder.
This __init__.py
file is the python file that contains all your backend logic.
You have alreay created such a file while finishing catalog project. It's just your file's name may not be __init__.py
. Mine is
views.py
, you can see my views.py
here
Now, change views.py
to __init__.py
: sudo mv views.py __init__.py
.
sudo nano __init__.py
Change engine = create_engine('sqlite:///projectmgtwithuser.db')
to
engine = create_engine('postgresql://catalog:<password you set up when creating postgresql user catalog>@localhost/catalog')
Change CLIENT_ID = json.loads(open('client_secrets.json', 'r').read())['web']['client_id']
's path to the abosulte path
CLIENT_ID = json.loads(open('/var/www/fullstack-nanodegree-vm/catalog/catalog/client_secrets.json', 'r').read())['web']['client_id']
In my models.py
file, change engine = create_engine('sqlite:///projectmgtwithuser.db')
to
engine = create_engine('postgresql://catalog:<password you set up when creating postgresql user catalog>@localhost/catalog')
In client_secrets.json
file, update
"redirect_uris":["http://project.emilyzhang.work"]
,
"javascript_origins":["http://project.emilyzhang.work"]
.
In Google developer console, update your credentials:
Authorized JavaScript origins: http://project.emilyzhang.work
,
Authorized redirect URIs: http://project.emilyzhang.work
.
Error: Permission denied to generate login hint for target domain
Amazon Lightsail's public IP doesn't work for me, see the reason here
To server catalog app via Apache web server, create a virtual host configuration file first
sudo nano /etc/apache2/sites-available/catalog.conf
catalog.conf
's content, pay attention to the path, mine may be different from yours:
<VirtualHost *:80>
ServerName 18.219.164.45
ServerAdmin admin@18.219.164.45
WSGIDaemonProcess catalog user=www-data group=www-data threads=5
WSGIProcessGroup catalog
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias / /var/www/fullstack-nanodegree-vm/catalog/catalog.wsgi
<Directory /var/www/fullstack-nanodegree-vm/catalog/catalog/>
Require all granted
</Directory>
Alias /static /var/www/fullstack-nanodegree-vm/vagrant/catalog/catalog/static
<Directory /var/www/fullstack-nanodegree-vm/catalog/catalog/static/>
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Disable the default virtual host: sudo a2dissite 000-default.conf
Enable the virtual host just created: sudo a2ensite catalog.conf
To make these changes live restart Apache2: sudo service apache2 restart
python __init__.py
sudo service apache2 restart