Choosing a database

A server keeps its world in a database: every map, item, script, account and character. Unless you say otherwise that database is SQLite, which is a single file in the server's data folder and needs nothing installed. The server can also keep the world in PostgreSQL, MySQL or MariaDB, on a database server you run or rent.

This guide helps you choose, sets up each one, and moves a world from one to another.

Which one#

What it isChoose it when
SQLiteOne .db file in the data folder. Nothing to install or look after.Nearly always. It is what the server uses unless told otherwise.
PostgreSQL 13 or laterA database server.You already run one, or you want its own tools around your world.
MySQL 8.0 or later, or MariaDB 10.6 or laterA database server.Your host hands you a MySQL database, as many game hosting panels do, or you already run one.

The game is the same on all of them. Players cannot tell which you chose, and nothing in Odyssey Server Admin works differently. A world is small, a few megabytes, so SQLite is not the slow choice: pick another only because it suits how you run things.

If you are not sure, stay on SQLite. You can move later.

SQLite#

There is nothing to set up. A new server writes this in data/server.yaml:

database:
  provider: sqlite
  file: server.db

file is the world's file. A name on its own is looked for in the data folder. To run a different world, stop the server, put its .db file in data, and change file to its name.

PostgreSQL#

1. Create an empty database and a user who owns it. On the database server, as its administrator:

CREATE USER odyssey WITH PASSWORD 'choose-a-password';
CREATE DATABASE odyssey OWNER odyssey;

The names are yours to choose. Leave the database empty: the server creates its own tables.

2. Stop the server, if it is running. If it has never run, start it once and stop it, so that data/server.yaml exists.

3. Point the server at it. In data/server.yaml, replace the database section:

database:
  provider: postgres
  host: localhost
  port: 5432
  name: odyssey
  user: odyssey
  passwordFile: db-password.txt

4. Give it the password. Put the password, on a line of its own, in a file called db-password.txt in the data folder. There are other places to keep it.

5. Bring your world, or start a new one: see Putting a world in below.

MySQL and MariaDB#

1. Create an empty database and a user who may do anything in it. On the database server, as its administrator:

CREATE DATABASE odyssey;
CREATE USER 'odyssey'@'%' IDENTIFIED BY 'choose-a-password';
GRANT ALL PRIVILEGES ON odyssey.* TO 'odyssey'@'%';

If your host gave you a database, a user and a password, this step is already done: use theirs.

2. Stop the server, if it is running. If it has never run, start it once and stop it, so that data/server.yaml exists.

3. Point the server at it. In data/server.yaml, replace the database section:

database:
  provider: mysql
  host: localhost
  port: 3306
  name: odyssey
  user: odyssey
  passwordFile: db-password.txt

The provider is mysql for MariaDB too. The server finds out which of the two it is talking to by itself.

4. Give it the password. Put the password, on a line of its own, in a file called db-password.txt in the data folder. There are other places to keep it.

5. Bring your world, or start a new one: see below.

Putting a world in#

A new, empty world#

Start the server. It finds the database empty, creates its tables, and you have a new world. The first start takes a little longer than the ones after it.

A world you already have#

A world you have is a .db file: one converted from the original Odyssey, a backup, or the file a SQLite server was running on. With the server stopped, import it:

./odyssey-server import-world path/to/world.db
Importing world.db...
Done. The server opens it the next time it starts.

Then start the server as usual.

The file you imported is read, not changed, and the server does not use it again. Keep it somewhere safe as a backup.

A world's pictures, sounds and music are not in the database. If your world came with an assets folder, put it in the server's data folder, exactly as you would with SQLite.

Replacing the world that is there#

import-world will not overwrite a world. If the database already holds one, it stops and says so. To replace it on purpose:

./odyssey-server import-world path/to/world.db --replace

The world being replaced is backed up first, and the command tells you the backup's name. It is in data/backups/.

Moving a world you are already running#

From SQLite to PostgreSQL, MySQL or MariaDB:

  1. Stop the server.

  2. Set up the new database, steps 1 to 4 above.

  3. Import the file the server was running on. It is in the data folder, named by file in the old database section:

    ./odyssey-server import-world data/server.db
    
  4. Start the server.

Everything comes across: maps, scripts, accounts, characters, bans, settings. Because certs and the rest of server.yaml have not changed, players' games recognise the server and its listing on the registry carries on.

To move the other way, or between two database servers, the world travels as a backup:

  1. In Odyssey Server Admin, open Database maintenance, press Back up now, and Download the backup. It is a .db file whichever database the world is in.
  2. Stop the server.
  3. To go to SQLite, put that file in the data folder and set the database section to provider: sqlite with file: naming it. To go to another database server, set that one up and import-world the file.
  4. Start the server.

Where the password goes#

The server looks in three places, and uses the first it finds:

PlaceHow
The environment variable ODYSSEY_DB_PASSWORDSet it for the account that runs the server.
A password filepasswordFile: names it. The password is its first line. A name on its own is looked for in the data folder.
server.yaml itselfpassword: ... in the database section.

Writing it in server.yaml is the simplest, and what a hosting panel expects. Anyone who can read that file can then read the password, so think about that before you send server.yaml to someone who is helping you. With a password file or the variable, server.yaml holds nothing secret about the database.

If you run the server under systemd, as in Running the server on its own, the variable goes in the unit:

[Service]
Environment=ODYSSEY_DB_PASSWORD=choose-a-password

Every setting#

All of these are in the database section of server.yaml. A change takes effect the next time the server starts.

SettingWhat it does
providersqlite, postgres or mysql. Use mysql for MariaDB.
fileSQLite only: the world's file.
hostThe database server's name or address. localhost when it is on the same machine.
portIts port. Leave it out for the usual one: 5432 for PostgreSQL, 3306 for MySQL and MariaDB.
nameThe database's name on that server.
userWho to sign in as.
passwordFileA file holding the password.
passwordThe password itself.

Backups are the same everywhere#

Whichever database you choose, backing up and restoring work as that guide describes. A backup made on the Database page is a .db file in data/backups/, even when the world is in PostgreSQL or MySQL. You can download it, restore it, import it into a different database, or run it directly as a SQLite world.

The server still backs the world up by itself before every restore, every reset and every update.

You can use your database's own tools as well, such as pg_dump or mysqldump. Treat those as extra: the backups on the Database page are the ones the server knows how to restore.

One server, one database#

A database holds one world, and one server runs it. A second server pointed at a database that is already in use refuses to start. Give each server a database of its own. They can share a database server.

import-world needs the server stopped for the same reason.

Keep the database close#

The connection between the server and its database is encrypted when the database server offers that, but the server does not check the database's certificate. Run the database on the same machine as the server, or on a private network between the two. Do not reach it across the open internet.

If the server will not start#

The server says what is wrong on the screen and in its log, under SERVER NOT STARTED.

It saysWhat to do
Could not reach the world's databaseThe server could not open the database. The line below it, starting Cause:, says why. The usual causes are below.
Cause: ... is not a database this server can useprovider is misspelt. It is sqlite, postgres or mysql.
Cause: A postgres database needs ... in the database settingshost, name or user is missing. The message names the ones it needs.
Cause: Could not find fileThe password file is not where passwordFile says.
Any other Cause:It is the database server's own answer: a wrong host or port, a wrong password, or a database that does not exist.
Another server is already running on this world's databaseAnother server has this database open. Stop it, or give this one a database of its own.
The database already holds a worldFrom import-world. Add --replace if you mean to replace it.