Skip to content

Install

If you want to use Docker, please follow the instructions in docs/docker.md

Preparation

Requires

  • Python3. Tested on 3.8.1 3.9.2 3.10.1 3.11.2 3.12.0
  • A PostgreSQL server

Install required system packages

apt-get install git python3-venv python3-dev gcc libpq-dev mime-support libcairo2

Create a user that will run LiberaForms

You might want to run LiberaForms with the user www-data. If not you can create a user like this.

adduser --disabled-password liberaforms

Install code

You can install LiberaForms in the directory of your choice.

Here we will use /opt but that could be /var/www or /home, etc..

Clone LiberaForms

cd /opt
git clone https://gitlab.com/liberaforms/liberaforms.git liberaforms
cd liberaforms
chown liberaforms uploads

Make sure the user who runs LiberaForms is the owner of the directories and files

Create a Python venv

cd /opt/liberaforms
python3 -m venv ./venv

Install python packages

source ./venv/bin/activate
pip install --upgrade pip
pip install -r ./requirements.txt

Configure

Create and edit .env

cp dotenv.example .env

You can create a SECRET_KEY like this

#openssl rand -base64 32
python -c 'import secrets; print(secrets.token_hex())'

Add the database config.

DB_HOST=localhost
DB_NAME=liberaforms
DB_USER=liberaforms
DB_PASSWORD=a_secret_db_password

Logs directory

Create the directory as defined by LOG_DIR in your .env file and ensure the user has permission on that directory.

Database

Create a user and database with the .env values

sudo su
su postgres -c "liberaforms/commands/postgres.sh create-db"
exit

Create tables

flask database create-tables
flask db stamp head

See more db options here https://flask-migrate.readthedocs.io/en/latest/#api-reference

Drop database

If you need to delete the database (warning: the database user is also deleted)

sudo su
su postgres -c "liberaforms/commands/postgres.sh drop-db"
exit

Data encryption

LiberaForms encrypts passwords by default. However, these other values are also encrypted:

  • Form attachments when they are submitted
  • Fediverse authentication

You need to create a key for these features to be enabled.

Create the key

flask cryptokey create

olYyUwGT--example-key--c9AkH_HoMEWg9Q=

Important. Save this key somewhere safe and do not lose it!

Copy the generated key and save it in a file with a name you will recognize. Something like my.domain.com.cryptokey.

Now add the key to your .env file

CRYPTO_KEY=olYyUwGT--example-key--c9AkH_HoMEWg9Q=

SMTP config

You can configure SMTP via the CLI (see docs/CLI.md)

Optionally, SMTP can be configued via the web UI

Session data

SESSION_TYPE = "filesystem"
#SESSION_TYPE = "memcached"

Unless you are running a memcached server, use filesystem and ensure the user running LiberaForms has write permissions. For example

chown liberaforms ./flask_session

Configure Gunicorn

Gunicorn serves LiberaForms.

This command suggests the configuration file path and it's content.

flask config hint gunicorn

Copy the content. Create the file ./gunicorn.py and paste the suggested config. Change the user name if needed

Install Supervisor

Supervisor manages the Log server, and Gunicorn. It will start the processes when the server boots.

sudo apt-get install supervisor

Configure Supervisor

Two configuration files are required.

This command suggests configuration file paths and content for both files.

flask config hint supervisor

Create the liberaforms-logs.conf and paste the suggested config. Change the user name if needed

Create the liberaforms.conf and paste the suggestion. Change the user name if needed

Restart supervisor and check if liberaforms-logs and liberaforms are running.

sudo systemctl restart supervisor
sudo supervisorctl status liberaforms-logs
sudo supervisorctl status liberaforms

Other supervisor commands

sudo supervisorctl start [liberaforms | liberaforms-logs]
sudo supervisorctl stop [liberaforms | liberaforms-logs]

Web server

You need to configure a web server to serve LiberaForms.

Configure nginx proxy. See docs/nginx.example

(TODO: update apache2.example)

Max body size

Your nginx vhost should accept uploads greater than the limit MAX_ATTACHMENT_SIZE defined in your .env file.

See client_max_body_size in docs/nginx.example

Cronjobs

Forms may expire by a date expiry condition. Run a cronjob at least once a day (shortly after midnight) to expire those forms.

/path/to/venv/bin/flask site expire-forms

Note that your server's timezone may differ from the timezone defined in the .env file.

Backups

Database

Create a directory for the backup and set permissions

mkdir /var/backups/liberaforms
chown postgres /var/backups/liberaforms/

Run this and check if a copy is dumped correctly.

su postgres -c "/usr/bin/pg_dump <db_name> > /var/backups/liberaforms/backup.sql"

Add a line to postgres user's crontab

crontab -u postgres -e
to run it every night..
30 3 * * * /usr/bin/pg_dump -U <db_name> > /var/backups/liberaforms/backup.sql"

Note: This overwrites the last copy. You might want to change that.

Don't forget to check that the cronjob is dumping the database correctly.

Recover database from a backup

sudo su
su postgres
cat <sql_dump_file> | psql -U postgres <db_name>

Uploaded files

If you enabled ENABLE_UPLOADS in the .env file, you should make copies of that directory too.

CRYPTO_KEY

Do not lose it!

Installation finished!

Stop the flask server if you still have it running in a terminal.

Start LiberaForms

supervisorctl start liberaforms
supervisorctl start liberaforms-logs

Bootstrap the first admin user

ROOT_USER defined in the .env is used to create the first user.

  1. From the Login page, choose 'Forgot your password?'
  2. Enter the ROOT_USER email
  3. Fill out the new user form
  4. Enjoy!

Debugging

Something gone wrong?

You can check supervisor's log at /var/log/supervisor/...

You can also run LiberaForms in debug mode.

sudo supervisorctl stop liberaforms
FLASK_CONFIG=development FLASK_DEBUG=True flask run

You can also test gunicorn

gunicorn --worker-tmp-dir /dev/shm --bind 127.0.0.1:5000 --workers 3 'liberaforms:create_app()' -e ENV_FILE=.env -e FLASK_CONFIG=development