Self-host FUTO Notes sync

Run the FUTO Notes sync server on your own box and your devices keep each other up to date without anyone else in the middle. Sync is end-to-end encrypted: every note is encrypted on your device before upload, and the server stores sealed blobs it cannot open. See how the encryption works below.

There is no hosted service today, so self-hosting is how you get sync. It is a single-user server with one sync password.

Install

You need a Linux box with Docker and Docker Compose v2, on amd64 or arm64.

curl -fsSL https://notes.futo.tech/install-server.sh | sh

The installer asks for an install directory, a port (3005 by default), and a sync password, then starts one container and checks /health before it finishes. SQLite runs inside the container; the database and your encrypted blobs both live in a data directory under the install directory.

Connect the app

In the app, open Settings → Self-hosted sync → Server URL. On your own network, enter:

http://<your-server-ip>:3005

Use the same sync password on every device. That password does two jobs: it signs the app in to your server, and it unlocks the encryption key for your notes. If you lose it, nothing on the server can be decrypted, and there is no reset.

Reach it from outside your network

The server speaks plain HTTP, which is fine on a LAN. To reach it from anywhere, put a TLS reverse proxy in front of it.

Tailscale Funnel is the least work: it gives the machine an HTTPS name without opening a port on your router. If you already run a public server, Caddy handles the certificate for you:

notes.example.com {
	reverse_proxy localhost:3005
}

Then point the app at the HTTPS URL instead.

Upgrade and back up

From the install directory:

docker compose pull && docker compose up -d

To back up, stop the container, copy the whole data directory somewhere safe, and start it again. That directory is everything the server has.

How the encryption works

The app does all of the cryptography. The server is a dumb store for bytes it cannot read, and it does the same job whether or not it is trusted.

What the server can see is the sync coordination data: how many objects there are, the size of each encrypted blob, when each one changed, and opaque IDs. It cannot see note text, titles, filenames, folder names, tags, or links. That means a copy of the data directory or a backup of it is worthless without your password.

Three honest caveats. The sync password is also the login password, so whoever runs the server is handed it when a device signs in; in a self-hosted setup that person is you. The installer writes that password into the server’s .env file, so protect that file: it is created mode 600, it should not sit in the same backup as the data directory, and you can store a scrypt hash in FUTO_NOTES_PASSWORD_HASH instead of the password itself (the server README covers it). And the app speaks plain HTTP unless you put TLS in front of it; TLS protects the password and session token in transit, while the notes are already encrypted either way.

Without Docker

Release binaries are published for Linux, macOS, and Windows if you would rather run the server directly, with a systemd unit example. The server README covers that path.

The full README and the source are at gitlab.futo.org/futo-notes/futo-notes-server.