Skip to content


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



  • Python3.7 or greater.
  • A PostgreSQL server

Install required system packages

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

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 liberaforms
cd liberaforms
chown liberaforms logs 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


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.



Create a user and database with the .env values

flask database create

If you encounter permission problems, try this

sudo su
su postgres -c "liberaforms/commands/ create-db"

Create tables

For new installations only!

flask database create-tables

If you are upgrading LiberaForms from a previous version, this will upgrade your existing database

flask db upgrade

See more db options here

Drop database

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

flask database drop

Or alternatively

sudo su
su postgres -c "liberaforms/commands/ drop-db"

Data encryption

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

  • Form attachments when they are submitted
  • Fediverse authentification

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

Create the key

flask cryptokey create


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

Now add the key to your .env file


SMTP config

You can configure SMTP via the CLI (see docs/

Optionally, SMTP can be configued via the web UI

Session data

SESSION_TYPE = "filesystem"
#SESSION_TYPE = "memcached"

If you use filesystem you must ensure the user running LiberaForms has write permissions on the directory. For example

chown liberaforms ./flask_session

Configure Gunicorn

Gunicorn serves LiberaForms.

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

flask config hint gunicorn

Copy the content. Create the file ./ 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]


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.



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, LiberaForm will save uploaded files in the ./uploads directory, you should make copies of this directory.


Do not lose it!

Web server

You need to configure a web server to serve LiberaForms.

Configure nginx proxy. See docs/nginx.example

(TODO: update apache2.example with the new paths)

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

So now everything is working and you need to create the first user.

ROOT_USER defined in the .env can be used to create the first Admin user.

  1. From the Login page, choose 'Forgot your password?' link
  2. Enter the ROOT_USER email
  3. Fill out the new user form
  4. Go to the configuration page and get the SMTP config working first


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

And test gunicorn

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