Application link: https://rahulbethi.com/restaurants_catalogue
This project is the extension of my existing project - My Restaurants' Catalogue. Built by Rahul Bethi.
It is a Web application hosted on Amazon Web Services (AWS) LightSail Ubuntu instance. It has a web server (Apache 2) with a database (PostgreSQL) to store and edit information about Restaurants and the food items sold in them. It also has a user system with Google and Facebook - OAuth 2.0 authentication to login and make modifications (CRUD operations) to add, edit or delete restaurants and their items.
It also has a JSON endpoint to provide restaurant details and item details.
- Python v3.5.2
- Flask v0.12.2 - micro-framework
- SQLAlchemy v1.2.6 - SQL toolkit
- OAuth2client v4.1.2 - OAuth 2.0 client library
- Psycopg2 v2.7.4 - PostgreSQL adapter
- Apache v2.4.18 web server
- PostgreSQL v9.5.12 database server
- Ubuntu 16.04 LTS linux operating system
- Amazon Web Services (AWS) - LightSail virtual machine instance on AWS Cloud
- Lower configuration than a AWS EC2 t2-micro instance (512MB RAM), cheaper pricing and free tier.
- Google, Facebook - OAuth 2.0 authentication systems
- HTML, CSS
- Other tools used while developing (not needed to build the app again):
- Get an AWS account (free tier) and create a LightSail instance with 'OS only (Ubuntu 16.04 LTS)' option.
- Create a Static IP address from [AWS LightSail console] -> [Networking] and attach it to the instance created.
- Open the instance from the [AWS LightSail console] (opens in browser) or by SSH into the instance by using username
ubuntu
, instance's IP address and SSH private key location.- AWS default SSH key can be obtained from [AWS LightSail console] -> [Account] -> [SSH Keys].
- Create a new user and add
sudo
permission.- New user:
sudo useradd
<new_user>
- Add sudo permission by adding an entry in a new file at
/etc/sudoers.d/
<new_user>
<new_user>
ALL=(ALL) NOPASSWD:ALL
- Create a new SSH key pair by running
ssh-keygen
on the local machine. - Copy the SSH public key into new user's
/home/
<new_user>
/.ssh/authorized_keys
file in the AWS instance.- Create the directory and file if they don't exist.
- Change file permissions and ownership on the
authorized_keys
file and.ssh
directory.sudo chmod 600 /home/<new_user>/.ssh/authorized_keys sudo chmod 700 /home/<new_user>/.ssh sudo chown <new_user> /home/<new_user>/.ssh/authorized_keys sudo chown <new_user> /home/<new_user>/.ssh sudo chgrp <new_user> /home/<new_user>/.ssh/authorized_keys sudo chgrp <new_user> /home/<new_user>/.ssh
- Now, this user on AWS instance can log in from this local machine using the username, IP address of the instance and the SSH private key on the local machine.
ssh
<new_user>
@
<ip_address-or-domain>
-p <ssh_port> -i
/private/key/location/with/file
- New user:
- Close and login with the new user.
- Update the system.
sudo apt-get update
--> Check for updatessudo apt-get upgrade
--> Updates system- If you still have packages to upgrade, use
sudo apt-get dist-upgrade
--> Updates dependencies too
- Modify SSH configuration file
/etc/ssh/sshd_config
- Disable Remote-root-login by changing
PermitRootLogin
tono
- Disable Login-by-password by changing
PasswordAuthentication
tono
- Change SSH port
- First Allow AWS LightSail instance's Firewall to allow/deny the desired ports [AWS LightSail console] -> [Instance] -> [Networking] -> [Firewall].
- Change
Port
to your desired port number in the configuration file.
- Restart SSH
sudo service sshd restart
- Disable Remote-root-login by changing
- Configure Uncomplicated FireWall (UFW) to allow SSH (new port), HTTP(80) and NTP(123) ports.
- Check status:
sudo ufw status
sudo ufw default deny incoming
--> Deny all incomingsudo ufw default allow outgoing
--> Allow all outgoingsudo ufw allow
<port#>
--> Allow portsudo ufw allow
<port#>
/
<tcp-or-udp>
--> Allow port on TCP or UDP- Allow changed SSH port and NTP using their port numbers as shown above.
- HTTP can also be allowed by using names
www
orhttp
sudo ufw allow www
orsudo ufw allow http
- Check status:
- Configure the Local time-zone to UTC.
- Run
sudo dpkg-reconfigure tzdata
- Then select [None of the above] -> [UTC]
- Run
- Install Apache2 web server
sudo apt-get install apache2
- Install PostgreSQL database server
sudo apt-get install postgresql
- Python 3.5.2 comes pre-installed on this instance, but not Pip. Pip is used to get python packages.
- Install Pip:
sudo apt-get install python3-pip
- Install Pip:
- Install Python packages
pip3 install flask
--> Flask (micro-framework)pip3 install sqlalchemy
--> SQL toolkitpip3 install oauth2client
--> OAuth 2.0 client librarypip3 install psycopg2
--> PostgreSQL database adaptersudo apt-get install libapache2-mod-wsgi-py3
--> Apache module (WSGI)
- Change user to postgres (default PostgreSQL user) -
sudo su postgres
- Log into PostgreSQL server by running command:
psql
- Create a new database user with only login permission.
CREATE USER <user> WITH LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOREPLICATION CONNECTION LIMIT -1 PASSWORD '<password>';
- Create new database with the new user as its owner.
CREATE DATABASE <database> WITH OWNER = <user> ENCODING = 'UTF8'tablespace CONNECTION LIMIT = -1;
- Clone this project into your desired directory. Goto the desired directory, then run:
git clone https://github.com/bethirahul/Restaurants-Web-App-AWS
- Create a new file
database_secrets.json
in the project root folder and fill it up with database details (user, password and database which were created earlier), as shown here.{ "postgresql": { "user": "<database_user>", "password": "<password>", "database": "<database_name>" } }
- To use Google OAuth 2.0 authentication, goto Google's Developers webpage and create new app (button on top).
- Goto [Credentials] -> [Credentials] and create a new OAuth client ID. Open the client ID
- Set Javascript Origins to
http://
<server_ip_address>
.xip.io
- Set Redirect URIs to
http://
<server_ip_address>
.xip.io/restaurants_catalogue/gconnect
- Get the client secrets by clicking [Download Json] button on the top. Place this file in the project root folder and rename it to
client_secrets.json
.
- Set Javascript Origins to
- Goto [Credentials] -> [OAuth consent screen] and set Email and Product Name.
- Goto [Credentials] -> [Credentials] and create a new OAuth client ID. Open the client ID
- To use Facebook OAuth 2.0 authentication, goto Facebook's Developers webpage
- Goto [My Apps] (top right corner) and [Add a New App].
- Goto [Add a Product] -> [Facebook Login] -> [Set Up]
- Goto [Facebook Login] (left) -> [Settings] and set Redirect URIs to
http://
<server_ip_address>
.xip.io/restaurants_catalogue/fbconnect
- Goto [Settings] (left) -> [Basic]
- Copy the App ID and App Secret into a new file named
fb_client_secrets.json
in the project root folder. Fill it up as shown here{ "web": { "app_id": "<your_app_id>", "app_secret": "<your_app_secret>" } }
- Copy the App ID and App Secret into a new file named
- Run database_setup.py file using python 3, to setup the database with necessary tabels (with rows and columns).
python3 database_setup.py
- Run initiating_db_with_users.py to fill the database tables with some information, this is needed for the app to work.
python3 initiating_db_with_users.py
- You can modify this file or make another file by taking this file as a templete.
- Note: Running the same file more than once without modifying, will add duplicate entries into the database.
- Create a new file at
/etc/apache2/sites-available/
<new_conf_file>
.conf
and fill it up by modifying the templete file restaurants_app.conf - Run command
sudo a2ensite
<new_conf_file>
.conf
to let the apache server use the new configuration file.- To disable a configuration file, run
sudo a2dissite
<conf_file>
.conf
- To disable a configuration file, run
- Restart web server -
sudo service apache2 reload
This project is the extension of the Restaurant's web app. Hosting the app onto the web using a virtual machine on the cloud is done here.
- A AWS LightSail virtual machine (VM) instance is setup with Ubuntu 16.04 LTS linux operating system.
- A Static IP is created for that instance.
- Domain name of the server is created using Xip.io, a free Public DNS server.
- Any domain name can be created from an IP address by appending the IP address with
.xip.io
- The DNS server just redirects back the IP address.
- I bought my own domain name and assigned my server IP address to it.
- Any domain name can be created from an IP address by appending the IP address with
- A new user with is created and sudo permissions are assigned.
- A new pair of SSH Keys are setup and are used between the host machine and the new user in the AWS VM. Login with password is disabled on the VM.
- SSH port is changed as a precaution to stop attacks on the default port.
- AWS LightSail Firewall is configured to allow this new port.
- The Uncomplicated FireWall (UFW) on the VM is also setup to block all incoming ports except, the new SSH port, HTTP and NTP ports. All outgoing ports are allowed.
- Local time-zone is set to UTC.
- System is updated and all the necessary software and their packages are installed.
- Application is cloned into a directory using Git.
- PostgreSQL database server is configured by creating a new user and creating a new database with the owner of the new database being the new database. These details are stored in the
database_secrets.json
file, so that the app can use those details to access the database. - Database is setup with necessary tables by using the username, password and database name from the
database_secrets.json
file. - Database is then populated with some Restaurant names, item names and users.
- Google and Facebook app secrets are taken and stored in their respective json files. These details are used by the app to login a user using OAuth2.0 authentication.
- Apache web server is configured by adding the app's apache configuration into the server's configuration folder. Then the server is updated with the new configuration file. Restart the server to take effect.
This makes the app run at http://
<your_domain_name>
.
Or if you don't have a domain name, just use Xip.io DNS, http://
<server_ip_address>
.xip.io
Address to my hosted app: https://rahulbethi.com/restaurants_catalogue
Screenshots of all the pages are located in Screenshots folder.
- Udacity - Full Stack nano degree course
- Udemy - AWS Developer Associate course
- Google OAuth2 docs
- Facebook OAuth2 docs
- SSH configuration
- SSH Keygen docs
- UFW configuration
- Apache configuration
- Apache mod_wsgi configuration
- PostgreSQL docs
sudo
docsapt-get
docschmod
docs
Linkdin: https://www.linkedin.com/in/rahulbethi
Email: rahulbethi@hotmail.com
Phone: +1 (361) 336-7752