Plain installation (without Docker)

This guide will help you to install byro from PyPI on a Linux distribution, with your own database server, gunicorn, systemd and reverse proxy. It is the right choice for classic or individual deployments. If you would rather have containers do most of this for you, see Installation with byroctl (recommended) (recommended) or Installation with Docker Compose.

Step 0: Prerequisites

Please set up the following systems beforehand, we’ll not explain them here (but see these links for external installation guides):

  • Python 3.12+ and pip for Python 3. You can use python -V and pip3 -V to check.

  • An SMTP server to send out mails

  • An HTTP reverse proxy, e.g. nginx or Apache to allow HTTPS connections

  • A database server: MySQL 5.7+ or MariaDB 10.2+ or PostgreSQL 9.6+. You can use SQLite, but we strongly recommend not to run SQLite in production. Given the choice, we’d recommend to use PostgreSQL.

We also recommend that you use a firewall, although this is not a byro-specific recommendation. If you’re new to Linux and firewalls, we recommend that you start with ufw.

Note

Please do not run byro without HTTPS encryption. You’ll handle sensitive data and thanks to Let’s Encrypt, SSL certificates are free these days. We also do not provide support for HTTP-exclusive installations except for evaluation purposes.

Step 1: Unix user

As we do not want to run byro as root, we first create a new unprivileged user:

# adduser byro --disabled-password --home /var/byro

In this guide, all code lines prepended with a # symbol are commands that you need to execute on your server as root user (e.g. using sudo); you should run all lines prepended with a $ symbol as the unprivileged user.

Step 2: Database setup

Having the database server installed, we still need a database and a database user. We recommend using PostgreSQL. byro also works (and runs tests against) MariaDB and SQLite. If you do not use PostgreSQL, please refer to the appropriate documentation on how to set up a database. For PostgreSQL, run these commands:

postgres $ createuser byro -P
postgres $ createdb -O byro byro

When using MySQL, make sure you set the character set of the database to utf8mb4, e.g. like this:

mysql > CREATE DATABASE byro DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci

Step 3: Package dependencies

To build and run byro, you will need the following Debian packages beyond the dependencies mentioned above:

# apt-get install git build-essential libssl-dev gettext

If you want to use PGP signing and encryption for outgoing email, you also need GnuPG before installing byro:

# apt-get install gnupg gpg-agent

Replace all further “pip” commands with “pip3” if your system does not have Python 3 as default Python version.

Step 4: Configuration

We now create a configuration directory and configuration file for byro:

# mkdir /etc/byro
# touch /etc/byro/byro.cfg
# chown -R byro:byro /etc/byro/
# chmod 0600 /etc/byro/byro.cfg

Fill the configuration file /etc/byro/byro.cfg with the following content (adjusted to your environment):

[filesystem]
data = /var/byro/data
media = /var/byro/data/media
logs = /var/byro/data/logs

[locale]
language_code = de

[site]
debug = False
url = https://byro.mydomain.com

[database]
name = byro
user = byro
password = byro
host = localhost
port = 5432
engine = postgresql

[mail]
from = admin@localhost
host = localhost
port = 25
user = admin
password = something
tls = False
ssl = True

[pgp]
# PGP support is configured in the byro office settings. These runtime settings
# select the crypto backend and the GnuPG home directory used by byro.
backend = byro.mails.gnupg_backend.GnuPGBackend
home = /var/byro/data/gnupg

[oidc]
# Leave issuer url empty to disable OIDC login
issuer_url = https://auth.example.com/application/o/byro/
client_id = byro
client_secret = change-me
# Restrict login to members of this group (leave empty to allow any authenticated user).
admin_group = byro-admins
# Set to true to automatically create a local account for new OIDC users.
auto_create_account = false
# Claim used as the Django username (default: preferred_username).
username_field = preferred_username

Step 5: Installation

Now we will install byro itself. Please execute the following steps as the byro user. We will update all relevant Python packages in the user’s Python environment, so that your global Python installation will not know of them:

$ pip install --user -U pip setuptools wheel gunicorn psycopg2-binary

Next, we will install byro – you can either install the latest PyPI release, or install a specific branch or commit:

$ pip install --user -U byro  # OR, alternatively
$ pip install --user -U "git+https://github.com/byro/byro.git@main#egg=byro&subdirectory=src"

We also need to create a data directory:

$ mkdir -p /var/byro/data/media

We create the database structure and compile static files and translation data (rebuild runs compilemessages, collectstatic and compress for you):

$ python -m byro migrate
$ python -m byro rebuild

Now, create an administrator user by running:

$ python -m byro createsuperuser

If you just want to play around with byro, you can load test data:

$ python -m byro make_testdata

Step 5a: Plugins (optional)

Plugins are Python packages installed into the same environment as byro (see Plugins for what is available). Pin a version or a tag, then migrate, rebuild and restart:

$ pip install --user 'byro-finance-import-bank-files @ git+https://github.com/byro/byro-finance-import-bank-files.git@v1.2.0'
$ python -m byro migrate
$ python -m byro rebuild
# systemctl restart byro-web    (once the service from step 6 exists)

rebuild compiles the translations of every installed plugin as well as byro’s own and collects the plugins’ static files.

Step 6: Starting byro as a service

We recommend starting byro using systemd to make sure it starts up after a reboot. Create a file named /etc/systemd/system/byro-web.service with the following content (replacing the local paths with ones appropriate for your system, especially the local Python version’s):

[Unit]
Description=byro web service
After=network.target

[Service]
User=byro
Group=byro
WorkingDirectory=/var/byro/.local/lib/python3.12/site-packages/byro
ExecStart=/var/byro/.local/bin/gunicorn byro.wsgi \
                      --name byro --workers 4 \
                      --max-requests 1200  --max-requests-jitter 50 \
                      --log-level=info --bind=127.0.0.1:8345
Restart=on-failure

[Install]
WantedBy=multi-user.target

byro also has periodic tasks (refreshing PGP keys, sending expiry reminders, cleaning up unfinished MFA enrolments). They only run if something calls python -m byro runperiodic regularly. Create /etc/systemd/system/byro-periodic.service:

[Unit]
Description=byro periodic tasks
After=network.target

[Service]
Type=oneshot
User=byro
Group=byro
WorkingDirectory=/var/byro
ExecStart=/var/byro/.local/bin/python -m byro runperiodic

and /etc/systemd/system/byro-periodic.timer:

[Unit]
Description=Run byro periodic tasks every 10 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=10min

[Install]
WantedBy=timers.target

If /var/byro/.local/bin/python does not exist, use the python3 that has byro installed (which python3 as the byro user).

You can now run the following commands to enable and start the services:

# systemctl daemon-reload
# systemctl enable --now byro-web
# systemctl enable --now byro-periodic.timer

Step 7: SSL

The following snippet is an example on how to configure a nginx proxy for byro:

server {
    listen 80 default_server;
    listen [::]:80 ipv6only=on default_server;
    server_name byro.mydomain.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl default_server;
    listen [::]:443 ssl ipv6only=on default_server;
    server_name byro.mydomain.com;

    ssl_certificate /path/to/cert.chain.pem;
    ssl_certificate_key /path/to/key.pem;

    add_header Referrer-Policy same-origin;
    add_header X-Content-Type-Options nosniff;

    location / {
        proxy_pass http://127.0.0.1:8345/;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $http_host;
    }
}

Because the proxy terminates TLS, byro must be told to trust the X-Forwarded-Proto header it sends. Set trust_proxy = True in the [site] section of /etc/byro/byro.cfg (see Configuration); otherwise byro builds absolute URLs such as the OpenID Connect redirect with http and considers requests insecure.

Do not serve /media/ with the web server: byro delivers documents itself after checking that the user is logged in. A location /media/ alias, as older versions of this guide suggested, would expose every uploaded document to anyone who knows its URL.

We recommend reading about setting strong encryption settings for your web server.

You’ve made it! You should now be able to reach byro at https://byro.yourdomain.com/ and log in as the administrator you configured above. byro will take you through the remaining configuration steps.

Step 8: Check the installation

You can make sure the web interface is up and look for any issues with:

# journalctl -u byro-web

In the start-up output, byro also lists its logging directory, which is also a good place to look for the reason for issues.

Next Steps: Updates

Warning

While we try hard not to issue breaking updates, please perform a backup before every upgrade.

To upgrade byro, please first read through the release notes to check for relevant update notes. Also, make sure you have a current backup of the database, of /var/byro/data (it contains the secret key file .secret, whose loss invalidates all sessions and MFA devices) and of your configuration.

Next, please execute the following commands in the same environment (probably your virtualenv) to first update the byro source, then update the database if necessary, then rebuild changed static files, and then restart the byro service. Please note that you will run into an entertaining amount of errors if you forget to restart the services.

If you want to upgrade byro to a specific release, you can substitute byro with byro==1.2.3 in the first line:

$ pip3 install -U byro gunicorn
$ python -m byro migrate
$ python -m byro rebuild
# systemctl restart byro-web

Check the release notes of your plugins as well and upgrade them in the same way (pip install -U 'byro-finance-import-bank-files @ git+...@<new tag>') before migrate.