Use in production environment
=============================

This is the guide for the manual installation of a "production" instance.

**IMPORTANT**: At the moment, there is **no** authentication mechanism in
Flatisfy. That is, if you want your instance to be private, you should put
some access control on your own with the webserver. This is explained below in
the case of `Nginx`.

## Get the app installed

```bash
# Clone the repository
git clone https://Phyks@git.phyks.me/Phyks/flatisfy.git && cd flatisfy

# Create a virtualenv
virtualenv .env && source .env/bin/activate

# Install required Python modules
pip install -r requirements.txt

# Clone and install weboob
git clone https://git.weboob.org/weboob/devel weboob && cd weboob && python setup.py install && cd ..

# Install required JS libraries and build the webapp
npm install && npm run build:prod

# Create a minimal config file
mkdir config && python -m flatisfy init-config > config/config.json

# Create a data directory to store db and data files
mkdir data

# Edit the config file according to your needs
$EDITOR config/config.json

# Build the required data files
python -m flatisfy build-data --config config/config.json -v

# Run initial import
python -m flatisfy import --config config/config.json -v
```

_Note_: In the config, you should set `data_directory` to the absolute path of
the `data` directory created below. This directory should be writable by the
user running Flatisfy. You should also set `modules_path` to the absolute path
to the `modules` folder under the previous `weboob` clone. Finally, the last
`import` command can be `cron`-tasked to automatically fetch available
housings posts periodically.


## Use an alternative Bottle backend (production)

This is the simplest option, offers good performances but is less scalable.
You should take care of which user is running `flatisfy`, as there can be some
related security concerns.

Just choose another [available
webserver](https://bottlepy.org/docs/dev/deployment.html) to use in Bottle
(typically `cherrypi`) and set the `webserver` config option accordingly to
use it.

### Nginx vhost

Here is a typical minimal `Nginx` vhost you can use (which provides
HTTP authentication support and SSL):

```
upstream _flatisfy {
    server 127.0.0.1:PORT;
}

server {
    listen 443;
    server_name SERVER_NAME;
    root ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT/flatisfy/web/static;

    access_log  /var/log/nginx/flatisfy-access.log;
    error_log   /var/log/nginx/flatisfy-error.log warn;

    ssl                  on;
    ssl_certificate      PATH_TO_SSL_CERT;
    ssl_certificate_key  PATH_TO_SSL_KEY;

    location / {
        auth_basic "Restricted";
        auth_basic_user_file ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT/.htpasswd;

        # Try to serve directly the URI first (static content), fallback on
        # passing it to the Python backend
        try_files $uri @uwsgi;
    }

    location @uwsgi {
        proxy_pass http://_flatisfy;
    }
}


server {
    listen      80;
    server_name SERVER_NAME;

    root /dev/null;

    return 301 https://$server_name$request_uri;
}
```

where  `PORT` (default for Flatisfy is 8080), `SERVER_NAME`,
`ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT`, `PATH_TO_SSL_CERT` and `PATH_TO_SSL_KEY`
should be replaced by values according to your own setup. You should also set
the `.htpasswd` file with users and credentials.

_Note_: This vhost is really minimalistic and you should adapt it to your
setup, enforce SSL ciphers for increased security and do such good practices
things.


## Use WSGI

This is the best option in terms of performance and is recommended. It should
offer both the best security and performances.

### Configure uWSGI

Assuming you are running Debian stable, you should install `uwsgi`:

```
apt-get install uwsgi uwsgi-plugin-python
```

Then, you can create a `/etc/uwsgi/apps-available/flatisfy.ini` with the
following content:

```ini
[uwsgi]
socket = /run/uwsgi/app/flatisfy/socket
chdir = ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT
master = true
plugins = python
venv = ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT/.env
file = wsgi.py
uid = www-data
gid = www-data
```

where `ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT` is the absolute path to the root of
the Flatisfy git clone made at the beginning of this document.

Now, you can enable the app:

```bash
ln -s /etc/uwsgi/apps-available/flatisfy.ini /etc/uwsgi/apps-enabled/flatisfy.ini
```

and restart `uWSGI`:

```bash
systemctl restart uwsgi
```

_Note_: You should review the `wsgi.py` file at the root of the repository to
check it is matching you setup (and especially is loading the configuration
from the right place, which is `config/config.json` by default).


### Nginx vhost

Here is a typical minimal `Nginx` vhost you can use (which provides
HTTP authentication support and SSL):

```
upstream _flatisfy {
    server unix:/run/uwsgi/app/flatisfy/socket;
}

server {
    listen 443;
    server_name SERVER_NAME;
    root ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT/flatisfy/web/static;

    access_log  /var/log/nginx/flatisfy-access.log;
    error_log   /var/log/nginx/flatisfy-error.log warn;

    ssl                  on;
    ssl_certificate      PATH_TO_SSL_CERT;
    ssl_certificate_key  PATH_TO_SSL_KEY;

    location / {
        auth_basic "Restricted";
        auth_basic_user_file ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT/.htpasswd;

        # Try to serve directly the URI first (static content), fallback on
        # passing it to the Python backend
        try_files $uri @uwsgi;
    }

    location @uwsgi {
        include uwsgi_params;
        uwsgi_pass _flatisfy;
    }
}


server {
    listen      80;
    server_name SERVER_NAME;

    root /dev/null;

    return 301 https://$server_name$request_uri;
}
```

where `SERVER_NAME`, `ABSOLUTE_PATH_TO_FLATISFY_GIT_ROOT`, `PATH_TO_SSL_CERT`
and `PATH_TO_SSL_KEY` should be replaced by values according to your own
setup. You should also set the `.htpasswd` file with users and credentials.

_Note_: This vhost is really minimalistic and you should adapt it to your
setup, enforce SSL ciphers for increased security and do such good practices
things.
