This repository has been archived on 2022-06-28. You can view files and clone it, but cannot push or open issues or pull requests.
Yotter/SELF-HOSTING.md

145 lines
6.1 KiB
Markdown
Raw Normal View History

2020-09-05 12:16:40 +05:30
<a href="https://github.com/pluja/Yotter"><img alt="Installation Working" src="https://img.shields.io/badge/Status-Working 2020.09.05-green.svg"></img></a>
<a href="https://github.com/pluja/Yotter"><img alt="Tested on Ubuntu" src="https://img.shields.io/badge/Tested On-Ubuntu Server 20.04LTS-blue.svg"></img></a>
2020-09-04 15:46:16 +05:30
2020-09-04 22:13:32 +05:30
> Using the `root` user is not recommended for this installation.
#### Step 1: Base setup
1. Connect to your server via SSH or direct access.
* (Recommended) Set up password-less login with ssh-keys.
2. Install base dependencies:
* `sudo apt-get -y update`
* `sudo apt-get -y install python3 python3-venv python3-dev`
2020-09-05 02:39:52 +05:30
* `sudo apt-get -y install mysql-server supervisor nginx git`
> When installing MySQL-server it will prompt for a root password. Set up a password of your like, this will be the MySQL databases master password and will be required later, so don't forget it!
2020-09-04 22:13:32 +05:30
> If after the MySQL-server installation you have not been prompted a password for the `root` user, run `sudo mysql_secure_installation`
3. Clone this repository and acccess folder:
* `git clone https://github.com/pluja/Yotter`
* `cd Yotter`
4. Create a Python virtual environment and populate it with dependencies:
* `python3 -m venv venv`
* `source venv/bin/activate`
2020-09-04 22:13:32 +05:30
* `pip install wheel`
* `pip install cryptography`
* `pip install -r requirements.txt`
2020-09-05 12:40:32 +05:30
> You can edit the `yotter-config.json` file
2020-09-04 17:24:44 +05:30
5. Install gunicorn (production web server for Python apps) and pymysql:
`pip install gunicorn pymysql`
2020-09-05 02:39:52 +05:30
6. Set up the database tables:
* `flask db init`
* `flask db migrate`
* `flask db upgrade`
7. Set up `.env`
1. (PRE) Generate a random string and copy it to clipboard:
`python3 -c "import uuid; print(uuid.uuid4().hex)"`
2. Create a `.env` file on the root folder of the project (`/home/ubuntu/Yotter/.env`):
```
SECRET_KEY=<RandomStringHere!>
DATABASE_URL=mysql+pymysql://yotter:<db-password>@localhost:3306/yotter
```
#### Step 2: Setting up the MySQL Database:
* Open the MySQL prompt line (Use the previously set MySQL root password!)
`mysql -u root -p`
2020-09-04 22:13:32 +05:30
> If you have problems with the root password try running `sudo mysql` and then run this query: `ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YOUR_PASSWORD';`. This changes the password for the user `root` by `YOUR_PASSWORD`
Now you should be on the MySQL prompt line (`mysql>`). So let's create the databases:
> Change `<db-password>` for a password of your like. It will be the password for the dabase user `yotter`. Don't choose the same password as the root user of MySQL for security.
2020-09-05 12:12:05 +05:30
> The password `<db-password` for the **yotter** user needs to match the password that you included in the `DATABASE_URL` variable in the `.env` file. If you didn't change it, you can change it now.
```
mysql> create database yotter character set utf8 collate utf8_bin;
mysql> create user 'yotter'@'localhost' identified by '<db-password>';
mysql> grant all privileges on yotter.* to 'yotter'@'localhost';
mysql> flush privileges;
mysql> quit;
```
If your set up was correct, you should now be able to run:
2020-09-05 02:39:52 +05:30
* `flask db upgrade`
#### Step 3: Setting up Gunicorn and Supervisor
When you run the server with flask run, you are using a web server that comes with Flask. This server is very useful during development, but it isn't a good choice to use for a production server because it wasn't built with performance and robustness in mind. Instead of the Flask development server, for this deployment I decided to use gunicorn, which is also a pure Python web server, but unlike Flask's, it is a robust production server that is used by a lot of people, while at the same time it is very easy to use. [ref](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvii-deployment-on-linux)
* Start yotter under Gunicorn:
`gunicorn -b localhost:8000 -w 4 yotter:app`
The supervisor utility uses configuration files that tell it what programs to monitor and how to restart them when necessary. Configuration files must be stored in /etc/supervisor/conf.d. Here is a configuration file for Yotter, which I'm going to call yotter.conf [ref](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvii-deployment-on-linux).
* Create a yotter.conf file on `/etc/supervisor/conf.d/`:
> You can run `nano /etc/supervisor/conf.d/yotter.conf` and paste the text below:
> Make sure to fit any path and user to your system.
```
[program:yotter]
2020-09-05 12:12:05 +05:30
command=/home/ubuntu/Yotter/venv/bin/gunicorn -b localhost:8000 -w 4 yotter:app
directory=/home/ubuntu/Yotter
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
```
After you write this configuration file, you have to reload the supervisor service for it to be imported:
`sudo supervisorctl reload`
#### Step 4: Set up Nginx
The Yotter application server powered by gunicorn is now running privately port 8000. Now we need to expose the application to the outside world by enabling public facing web server on ports 80 and 443, the two ports too need to be opened on the firewall to handle the web traffic of the application. I want this to be a secure deployment, so I'm going to configure port 80 to forward all traffic to port 443, which is going to be encrypted. [ref](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvii-deployment-on-linux).
* `sudo rm /etc/nginx/sites-enabled/default`
2020-09-04 15:46:16 +05:30
Create a new Nginx site, you can run `sudo nano /etc/nginx/sites-enabled/yotter`
2020-09-04 20:12:37 +05:30
And write this on it:
```
server {
server_name <yourdomain>;
location / {
proxy_pass http://localhost:8000;
}
2020-09-04 22:13:32 +05:30
location /static {
# handle static files directly, without forwarding to the application
2020-09-05 12:12:05 +05:30
alias /home/ubuntu/Yotter/app/static;
2020-09-04 22:13:32 +05:30
expires 30d;
}
2020-09-04 20:12:37 +05:30
}
```
2020-09-04 22:13:32 +05:30
* Run `sudo service nginx reload`
2020-09-05 12:40:32 +05:30
[Follow this instructions to install certbot and generate an ssl certificate so your server can use HTTPS](https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx)
## Updating the server
Updating the server should always be pretty easy:
```
(venv) $ git pull
(venv) $ sudo supervisorctl stop yotter
(venv) $ flask db upgrade
(venv) $ pip install -r requirements.txt
(venv) $ sudo supervisorctl start yotter
```