uVersion
English
Download →

Wiki

Server configuration & migration

Edit config.toml, move the data directory, use a PostgreSQL database elsewhere, back up and restore.

Everything is set in a single file, /etc/uversion/config.toml. The installer generates it; you are then free to edit it.

The configuration file

Edit, then restart: the server reads its configuration at startup only.

sudo nano /etc/uversion/config.toml
sudo systemctl restart uversion-server

Here are the fields you will end up touching. This is a partial excerpt: the file contains others, and some mandatory fields do not appear below. Never overwrite your file with this block, edit the relevant lines.

# EXTRAIT PARTIEL : le fichier contient d'autres sections.
# N'ecrasez jamais votre fichier avec ce bloc, editez les lignes concernees.

[server]
bind_address = "0.0.0.0"
port = 8080

[database]
# Ou toute base PostgreSQL accessible : autre disque, autre machine, service manage.
url = "postgres://uversion:MOTDEPASSE@127.0.0.1:5432/uversion"

[security]
# Le secret qui signe les sessions. Obligatoire et SANS valeur par defaut :
# absent ou plus court que 32 caracteres, le serveur refuse de demarrer.
# L'installateur en genere un. Le remplacer deconnecte tout le monde une fois.
jwt_secret = "..."

[storage]
# Le contenu des fichiers (les chunks, morceaux de fichiers). C'est ce qui grossit.
path = "/var/lib/uversion/data/chunks"

[tls]
disabled = false
https_port = 8443

[licence]
key = "..."
File permissions It holds the licence key, the secret that signs the sessions and the database password. It is in 0640 root:uversion: keep it that way.

Where the data lives

Three separate locations, and this is the point that surprises the most. The third, the configuration, is also the one that gets forgotten in backups:

WhatWhere
File content (the chunks, pieces of files: this is what takes up the space)/var/lib/uversion/data/chunks
TLS certificate, server fingerprint/var/lib/uversion/data/tls
Server identity, licence anchor/var/lib/uversion/server-id, last-validated-at
Metadata (files, revisions, users, locks, permissions, tasks)PostgreSQL: /var/lib/postgresql/16/main
Configuration: licence key, session-signing secret, database password/etc/uversion/config.toml, /etc/uversion/licence-key
The database does not follow the data directory Changing the data directory moves the chunks and the certificates, not the database. And the database references chunks by fingerprint: if you move one without the other, the server will look for chunks it cannot find. Move both, or neither.

Moving the data directory

This is the common case: the content grows, the system partition is small. The database itself stays small (it grows with the number of revisions, not with the size of the files).

1. Stop the service

sudo systemctl stop uversion-server

2. Copy the directory

It is the -a that preserves permissions and owners. Copying, rather than moving, leaves you a way back until the final check.

sudo mkdir -p /srv/uversion
sudo rsync -a /var/lib/uversion/ /srv/uversion/
sudo chown -R uversion:uversion /srv/uversion
sudo chmod 0750 /srv/uversion

3. Point the configuration at the new path

This step is mandatory and comes before the next one: see the "Order matters" box below.

sudo sed -i 's#/var/lib/uversion#/srv/uversion#g' /etc/uversion/config.toml

4. Declare the new path to the installer

Answer the new path to the "Data directory" question. The installer rewrites the systemd unit from this answer, then restarts the service.

sudo dpkg-reconfigure uversion-server
#   Data directory : /srv/uversion

5. Check that the unit really points there

systemctl cat uversion-server | grep -E 'WorkingDirectory|ReadWritePaths'
systemctl status uversion-server
Go through dpkg-reconfigure, do not write the systemd unit yourself The installer writes /etc/systemd/system/uversion-server.service.d/10-data-dir.conf itself, and it rewrites it on every configuration from the answer you gave it. A file placed by hand survives until the next update, including the one triggered by the Update now button: the unit then points back to the old directory while the configuration writes into the new one. The hardened service (ProtectSystem=strict) starts normally, and breaks on the first file upload, weeks later.
Order matters: edit config.toml first dpkg-reconfigure on its own is not enough. The installer only fixes [storage].path if the directory it finds there no longer exists: a custom path that is still present is treated as a deliberate choice and left as is. Since you copied rather than moved, the old directory still exists, so step 2 above is mandatory. Once everything is checked and the server is running on the new path, you can delete the old directory.
Never under /home or /root The service runs as a hardened system user (ProtectHome=true, and a home directory is not traversable by a system account). A path under /home or /root prevents startup (226/NAMESPACE or 200/CHDIR). Choose a system path: /srv, /opt, or a mounted disk.

Putting the database elsewhere

The installer creates a local database, but nothing forces you to keep it. Point url at any reachable PostgreSQL database: another disk mounted as a separate cluster, another machine, or a managed service.

[database]
url = "postgres://UTILISATEUR:MOTDEPASSE@HOTE:5432/BASE"

Then restart. The server applies its migrations at startup: it updates its database structure on its own. An empty database is initialised, an older database is upgraded, you have nothing to run by hand.

It is simply required that the role you give can create tables in the target database.

Database on the data disk

The previous section assumes a database you administer elsewhere. If your goal is different: that a single surviving disk is enough to bring the server back when the machine dies, then the installer can place the database inside the data directory, in the form of a dedicated PostgreSQL cluster: a separate PostgreSQL instance, with its own directory and its own port, independent of the system one.

The question is asked at installation. To enable it on a Debian server already in place:

sudo dpkg-reconfigure uversion-server
#   Data directory                     : /srv/uversion
#   Put the database on the data directory too?  Yes

On Windows

Same promise, different mechanics. Windows has no named clusters: the installer moves the PostgreSQL instance itself onto the data directory, re-pointing the service. This choice is made at installation time, by adding -DbOnDataDir to the script's parameters. It is not offered by a question: the script only asks for the activation code, so if you do not pass this parameter, the database will stay at its default location. See Installing on Windows for the exact form of the command, keeping in mind that the one-liner cannot receive any parameter.

# PowerShell en administrateur, installation en ligne de commande
& ([scriptblock]::Create((iwr https://uversion.io/downloads/server/install.ps1 -UseBasicParsing).Content)) `
    -LicenceKey "UV-XXXX-XXXX-XXXX" -DataDir "D:\uVersion" -DbOnDataDir

# verifier ensuite ou pointe le service PostgreSQL
(Get-CimInstance Win32_Service -Filter "Name='postgresql-x64-16'").PathName

The move is refused, with the reason shown, if the instance hosts databases other than uVersion's, or if its directory is not self-contained: presence of a tablespace, a pg_wal relocated through a junction, or an absolute path written into postgresql.conf. Nothing is ever deleted: the installer copies, verifies, starts the service on the new copy, and only then renames the old directory.

Two differences from Linux Windows cannot make a service wait for a disk: there is no equivalent of RequiresMountsFor. A late external disk is therefore caught by the service's recovery actions, not by a dependency. And PostgreSQL checks no permission on its directory under Windows: it is the installer that restricts them, there is no safety net on the server side.

The disk then contains everything:

/srv/uversion/
├── data/chunks       contenu des fichiers
├── data/tls          certificat, empreinte
├── pgdata/16         LA BASE (cluster PostgreSQL dedie)
└── recovery/         procedure + fichiers necessaires a la reprise
    ├── RESTORE.md
    ├── pgconf/       postgresql.conf, pg_hba.conf, pg_ident.conf
    ├── etc/          copie de config.toml et du mot de passe
    └── cluster.env

The cluster receives its own port, assigned automatically (5433 if it is free), and config.toml is updated to target it. The system cluster is untouched: it can keep hosting other databases.

Two trade-offs, worth knowing before you say yes A PostgreSQL data directory only opens with the major version that created it: a recovery in three years may require explicitly installing PostgreSQL 16. And the disk now carries the licence key, the secret that signs the sessions and the database password, in a directory accessible to root alone: treat this disk as a credential.
Database already populated: the installer refuses to move it If your server is already running with data, enabling the option moves nothing: a relocation interrupted in the middle of a package update would be worse than no relocation at all. The installer leaves you as you are and prints the manual procedure (stop, pg_dump, create the cluster, restore, update url).

Bringing the server back on a new machine

The disk does not contain the software: plan for PostgreSQL and the uVersion package, of which a copy kept next to the disk avoids a nasty surprise on the day it is needed.

# sur la machine neuve
sudo apt install postgresql-16
# montez le disque, par exemple sur /srv/uversion
sudo apt install ./uversion-server_*.deb
#   dossier de donnees : le point de montage du disque
#   base sur le dossier de donnees : oui

The installer finds the database on the disk, puts the PostgreSQL configuration files back in place (which pg_createcluster had moved out of the directory, onto the system disk), registers the cluster, fixes the owners, then realigns the port and the chunk path in config.toml. If the disk comes back on a different mount point than before, simply give the new path.

The full procedure, including the variant without reinstalling, is written on the disk itself: recovery/RESTORE.md.

Backup and restore

A complete backup is three elements: the export of the database (the dump), the data directory, and the configuration directory.

Back up the database

The metadata: files, revisions, users, locks.

sudo -u postgres pg_dump uversion > uversion-$(date +%F).sql

Back up the data directory

The content of the files, that is, what takes up the space.

sudo tar -C /var/lib/uversion -czf uversion-data-$(date +%F).tar.gz .

Back up the configuration

Licence key, session-signing secret, database password. It does not live in the data directory.

sudo tar -C /etc -czf uversion-etc-$(date +%F).tar.gz uversion
Do not forget /etc/uversion It is the third element, and the easiest to forget: it does not live in the data directory. /etc/uversion/config.toml carries the licence key, the secret that signs the sessions and the database password; /etc/uversion/licence-key carries the licence itself. Without them, a restore on a new machine starts again with a new secret, so the whole team is disconnected at once, and a licence must be requested again: the activation code received at sign-up is single-use and already consumed, only the licence key it produced can be reused.

To restore onto a new machine: install the package, then put the three elements back in place, in this order.

1. Restore the database

sudo -u postgres createdb -O uversion uversion      # seulement si elle n'existe pas
sudo -u postgres psql uversion < sauvegarde.sql

2. Restore the data

Put the chunks back, with the right permissions:

sudo rsync -a /mnt/backup/uversion/ /var/lib/uversion/
sudo chown -R uversion:uversion /var/lib/uversion
sudo chmod 0750 /var/lib/uversion

3. Carry over two configuration lines

Not the whole file: the one the installer just wrote carries the database password that it redefined itself.

# N'ECRASEZ PAS le fichier neuf : ouvrez l'ancien a cote et recopiez-en
# deux lignes, et deux seulement.
#   [security] jwt_secret  -> sinon toute l'equipe est deconnectee
#   [licence]  key         -> sinon il faut redemander une licence
# Gardez le [database] url que l'installateur vient d'ecrire : il porte le
# mot de passe qu'il a lui-meme redefini.
sudo nano /etc/uversion/config.toml

4. Restart

sudo systemctl restart uversion-server
Installing on top of an existing database The installer destroys nothing: if it already finds the uversion database, it reuses it as is and merely resets the role password. So you can restore your dump first and install afterwards.

Moving the PostgreSQL cluster

Rarely necessary: the database is small. If you insist on it, it is a standard PostgreSQL operation, not something the uVersion installer handles. Be aware that this cluster (the system's PostgreSQL instance, with its directory and its port) may host databases other than uVersion's.

sudo systemctl stop uversion-server
sudo pg_ctlcluster 16 main stop

sudo mkdir -p /srv/pgdata
sudo rsync -a /var/lib/postgresql/16/main/ /srv/pgdata/16/main/
sudo chown -R postgres:postgres /srv/pgdata

sudo sed -i "s#^data_directory =.*#data_directory = '/srv/pgdata/16/main'#" \
  /etc/postgresql/16/main/postgresql.conf

sudo pg_ctlcluster 16 main start
sudo systemctl start uversion-server

Then check with pg_lsclusters that the cluster is online on the new path.