Server owners

Install and operate the main database

SQLite is the default. BlokeBot supports the current PostgreSQL 18 minor release for one active instance per main database.

Provider configuration

  • Do not put the PostgreSQL connection string in an environment value.
  • Do not put the PostgreSQL connection string in an image.
  • Use Sqlite for the default local database file.
  • Use PostgreSql with BlokeBot__PostgreSqlConnectionStringFile for PostgreSQL 18.x.
  • Install the current PostgreSQL 18 minor release.
  • Keep BlokeBot__StateDirectory on persistent storage for both providers.
  • Configure one active BlokeBot instance for each main database.

Docker Compose secrets

The Compose file uses postgres:18-alpine and starts BlokeBot. It stores each service state in a named volume.

  1. Open the BlokeBot repository root.
  2. Create the protected secret directory and files with the commands below.
  3. Write only the database password to postgresql.password.
  4. Write the complete BlokeBot connection string to postgresql.connection.
  5. Use Host=postgres;Port=5432;Database=blokebot;Username=blokebot;Password=<same-password>;SSL Mode=Disable.
umask 077
mkdir -p packaging/docker/secrets
${EDITOR:-vi} packaging/docker/secrets/postgresql.password
${EDITOR:-vi} packaging/docker/secrets/postgresql.connection
chmod 0600 packaging/docker/secrets/postgresql.password
sudo chown 1654:1654 packaging/docker/secrets/postgresql.connection
sudo chmod 0400 packaging/docker/secrets/postgresql.connection

Docker Compose startup

  1. Use a new PostgreSQL 18 volume.
  2. Start both services with the Compose file.
  3. Wait for the readiness request to succeed.
docker compose -f packaging/docker/compose.postgresql.yml up --build --detach
curl --fail --retry 30 --retry-all-errors --retry-delay 1 http://127.0.0.1:8080/health/ready

NixOS protected credential

  1. Create /etc/blokebot with mode 0700.
  2. Create /etc/blokebot/postgresql.connection with owner root and mode 0400.
  3. Write the local socket connection string below to the file.
  4. Keep the source file outside the Nix store.
Host=/run/postgresql;Database=blokebot;Username=blokebot

NixOS PostgreSQL configuration

  1. Update the NixOS package input to the current PostgreSQL 18 minor release.
  2. Add the PostgreSQL 18 service and BlokeBot settings.
  3. Make the local BlokeBot service depend on PostgreSQL.
  4. Apply the NixOS configuration.
services.postgresql = {
  enable = true;
  package = pkgs.postgresql_18;
  ensureDatabases = [ "blokebot" ];
  ensureUsers = [
    {
      name = "blokebot";
      ensureDBOwnership = true;
    }
  ];
};

services.blokebot = {
  enable = true;
  databaseProvider = "PostgreSql";
  postgresqlConnectionStringFile = "/etc/blokebot/postgresql.connection";
};

systemd.services.blokebot = {
  after = [ "postgresql.target" ];
  requires = [ "postgresql.target" ];
};

NixOS startup and health

  1. Apply the new system configuration.
  2. Check that the BlokeBot service stays active.
  3. Check the database readiness endpoint.
sudo nixos-rebuild switch
systemctl status blokebot
curl --fail http://127.0.0.1:8080/health/ready

Native PostgreSQL installation

  1. Install the current PostgreSQL 18 minor release from the operating-system package source.
  2. Start the PostgreSQL service.
  3. Create the BlokeBot login role with a password prompt.
  4. Create the BlokeBot database with that role as owner.
  • Do not give the role superuser privileges.
  • Do not give the role replication privileges.
  • Do not give the role role-management privileges.
  • Do not give the role database-creation privileges.
sudo -u postgres createuser --login --pwprompt blokebot
sudo -u postgres createdb --owner=blokebot blokebot

Native BlokeBot configuration

  1. Create /etc/blokebot/postgresql.connection for the BlokeBot service account.
  2. Set the connection-file mode to 0400.
  3. Add the database host.
  4. Add the database and user name.
  5. Add the password.
  6. Add the TLS settings.
  7. Set the non-secret values below in the service manager.
  8. Start one BlokeBot process with the command below.
export BlokeBot__DatabaseProvider=PostgreSql
export BlokeBot__StateDirectory=/var/lib/blokebot
export BlokeBot__PostgreSqlConnectionStringFile=/etc/blokebot/postgresql.connection

blokebot serve --host 127.0.0.1 --port 8080 --data-dir /var/lib/blokebot

Native startup health

  1. After BlokeBot starts, open another terminal.
  2. Before public traffic starts, check both health endpoints.
curl --fail http://127.0.0.1:8080/health/live
curl --fail http://127.0.0.1:8080/health/ready

Startup and health behavior

BlokeBot checks the database and applies migrations before it starts the HTTP listener. A connection refusal means that BlokeBot is not ready.

  • BlokeBot retries provider unavailability five times. Each retry waits three seconds.
  • /health/live confirms that the process listens. It does not access the database.
  • /health/ready checks database access and the migration history within two seconds.
  • A terminal startup failure stops BlokeBot with a redacted category and a nonzero exit status.

SQLite cutover preconditions

  1. Stop the SQLite BlokeBot instance.
  2. Back up the SQLite file and the matching state directory.
  3. Keep the active provider configuration on Sqlite.
  4. Start PostgreSQL 18.
  5. Create the application login.
  6. Do not create the application database.
  7. Create a protected administrator connection file for an existing maintenance database.
  8. Create a protected application connection file for the new database and the application login.
  • For a non-superuser administrator login, CREATEDB is required.
  • For that non-superuser login, EXECUTE on pg_control_system() is required.
  • For that non-superuser login, membership of the application login is required.

SQLite cutover command

  1. Run the offline transfer with both protected connection files.
  2. Rerun the same command to resume an interrupted transfer.
  3. Reuse the operation ID if you set --operation-id.
  4. Change the provider to PostgreSql only after successful verification.
  5. Start one BlokeBot instance.
  6. Check /health/ready.
  • The cutover command migrates SQLite first.
  • The command then creates the database.
  • The command applies the PostgreSQL schema.
  • The command copies the data.
  • The command checks the row count of each domain table.
  • The command rejects a database that exists without a matching receipt.
  • The command does not drop a database or change the active provider configuration.
blokebot database cutover-postgresql \
  --postgresql-administrator-connection-string-file /etc/blokebot/postgresql-admin.connection \
  --postgresql-application-connection-string-file /etc/blokebot/postgresql.connection \
  --data-dir /var/lib/blokebot

Cutover recovery boundary

  • Before the first PostgreSQL application write, retry the cutover or continue with untouched SQLite.
  • After the first PostgreSQL application write, repair or restore PostgreSQL.
  • Do not return to SQLite after the first PostgreSQL application write.
  • BlokeBot does not provide a reverse transfer or database downgrade.

PostgreSQL responsibilities

  • BlokeBot does not provide high availability.
  • BlokeBot does not provide scale-out.
  • BlokeBot does not provide multi-tenancy.
  • Configure certificate-verified TLS.
  • Restrict network access.
  • Back up PostgreSQL and the matching BlokeBot state directory.
  • Test a restore before a cutover or PostgreSQL upgrade.
  • Keep one active BlokeBot instance during migrations and normal operation.