Menu

Self-hostingVersion 0.9.0

Running OpenTodo on Fly.io

OpenTodo runs on Fly.io as one machine with one volume, served over https at https://<app>.fly.dev. The repository has a ready fly.toml; you need a Fly account and flyctl, signed in with fly auth login.

On this page

Install#

  1. Get the configuration into an empty folder:

    mkdir opentodo && cd opentodo
    curl -fsSLO https://raw.githubusercontent.com/pixari/opentodo/main/deploy/fly/fly.toml
  2. Create the app from it. Pick a name (it becomes <app>.fly.dev) and a region near you (fly platform regions lists them):

    fly launch --copy-config --no-deploy --name <app> --region <region>

    This creates the app and writes its name and region into fly.toml. It does not deploy yet.

  3. Set the base URL in fly.toml, under [env], to the app's address:

    OPENTODO_BASE_URL = "https://<app>.fly.dev"
  4. Set a setup token, a secret only you know (at least 16 characters):

    fly secrets set OPENTODO_SETUP_TOKEN=$(openssl rand -hex 16)
    fly secrets list   # shows that it is set, not its value

    Keep the value: you need it once, to create the owner account.

  5. Deploy:

    fly deploy

    The first deploy creates the volume opentodo_data (1 GB) and one machine.

First visit#

Open https://<app>.fly.dev. The first visitor creates the owner account, and the setup screen asks for the setup token. After that, sign-up is closed and the owner invites people.

Fly serves the app over https only, so installing the app on a phone, working offline, push notifications, passkeys and end-to-end encryption all work once the base URL is set.

Settings#

Setting In fly.toml What it does
OPENTODO_BASE_URL empty until step 3 The https address people open. Set it to https://<app>.fly.dev, or to your own domain (below).
OPENTODO_SETUP_TOKEN not in the file A secret (fly secrets set). Asked for when the owner account is created.
OPENTODO_ALLOW_SIGNUP false true lets anyone who can reach the server create an account.
OPENTODO_TRUSTED_PROXIES empty Fly's proxy needs nothing here. Set it to cloudflare only if you put Cloudflare's proxy in front of your own domain.

Other OPENTODO_* variables from the configuration table go under [env], or fly secrets set for passwords (for example OPENTODO_EMAIL_IMAP_PASSWORD). Run fly deploy after editing fly.toml; fly secrets set restarts the machine by itself.

One machine, always on#

Keep exactly one machine. The database is SQLite in the volume, and Fly does not copy volumes between machines, so a second machine would have its own empty data. Do not run fly scale count 2 or fly machine clone.

The file keeps the machine running (auto_stop_machines = "off", min_machines_running = 1). Reminders, scheduled backups and email to task run on the server, so a machine that Fly stopped when idle would miss them. You can set auto_stop_machines = "stop" to pay only while it is used, if you do not need those.

Your own domain#

Point your domain at the app (fly ips list shows its addresses; a CNAME to <app>.fly.dev also works), then:

fly certs add todo.example.com

When fly certs show todo.example.com reports the certificate as issued, set OPENTODO_BASE_URL = "https://todo.example.com" in fly.toml and run fly deploy. More on proxies and https in Running with Docker.

Updates and backups#

fly.toml uses the stable image, which every release moves. Fly does not update a running app by itself: run fly deploy in the folder with fly.toml, and it fetches the release stable points at then. Migrations run on start. There are no down-migrations, so back up first. To stay on one release line, set image = "ghcr.io/pixari/opentodo:0.6" under [build] (or pin one version, 0.6.1).

Fly takes daily snapshots of the volume and keeps them for a few days (fly volumes snapshots list <volume id>; fly volumes list shows the id). For backups you control, turn on scheduled backups in OpenTodo's Settings → Server and send them to S3 or WebDAV; the local backups/ folder is in the same volume, so it does not protect against losing the volume. See Backups.

Troubleshooting#

  • fly deploy asks which app to use, or deploys a new one: run it in the folder where fly launch wrote the app name into fly.toml.
  • The setup screen says the token is wrong: set a new one with fly secrets set OPENTODO_SETUP_TOKEN=... and try again after the machine restarts.
  • The machine stops right after starting and fly logs says "permission denied" on /data: Fly gives the volume to the image's user (65532) when it mounts it, so this should not happen. If it does, open an issue with the log.

Edit this page on GitHub