Skip to main content
This guide starts a local instance at http://localhost:5173. You need Docker with Compose V2 and a terminal. No repository clone is required.

1. Create a directory

Save the following as compose.yml:
This example pins Kaneo to a release so a pull does not unexpectedly upgrade it. See the release notes when choosing another version. To follow a release line instead, set KANEO_IMAGE_TAG to a major tag such as 2 or a major and minor tag such as 2.34. These tags move to the newest matching release and only exist for lines released since they were introduced, so check the available tags first. Pulling a newer image does not restart Kaneo; follow the upgrade guide to apply it.

2. Add configuration

Run this twice to generate two different secrets:
Create .env beside compose.yml. Replace both placeholders with the generated values:
Keep this file private. On Linux or macOS, run chmod 600 .env. The bundled image derives its database connection from POSTGRES_* and its API URL from KANEO_CLIENT_URL. You do not need to set DATABASE_URL or KANEO_API_URL for this setup.

3. Start and check the services

Allow time for the first database initialization and migrations. Both services should become healthy. If they do not, check:
Open localhost:5173, create the initial account, and follow Your first project.

4. Make it available to your team

The port is bound to the host’s loopback address. To serve Kaneo on a domain, follow the Nginx and HTTPS guide, then set:
Apply environment changes by recreating the container:
A plain restart keeps the old environment. If you use a proxy in another container, connect it to Kaneo’s Docker network and proxy to kaneo:5173 instead of the host’s loopback address.

Keep secrets in files

Instead of putting POSTGRES_PASSWORD and AUTH_SECRET in .env, you can mount them as Docker secret files. This requires a Kaneo release that includes _FILE support, so raise KANEO_IMAGE_TAG past 2.28.3 first. Move the values you already use from .env into their own files:
Keep the current values. PostgreSQL sets its password only when it first initializes the postgres_data volume, so a new value in the file would no longer match the database. A new AUTH_SECRET would also sign everyone out. Generate fresh values with openssl rand -hex 32 only for a new installation that has not started yet. Compose mounts these files with their host ownership, and the containers read them as non-root users (UID 1001 for Kaneo, postgres for PostgreSQL). The files therefore need to be readable by other users, while the 700 directory keeps other accounts on the host from reaching them. Remove POSTGRES_PASSWORD and AUTH_SECRET from .env. In compose.yml, replace the POSTGRES_PASSWORD line of the postgres service and add the secrets to both services:
Keep the other keys of each service as they are. For custom OAuth, mount the client secret the same way and set CUSTOM_OAUTH_CLIENT_SECRET_FILE. A direct value in .env takes precedence over its _FILE variable, so leave the direct variable unset. See the environment variable reference for how files are read and what happens when one is missing.

Optional features

  • Silo stores images and attachments.
  • SMTP delivers sign-in codes, invitations, and notifications.
  • Sign-in providers connect your identity provider.
PostgreSQL stays inside the Compose network. Do not publish its port for this deployment. Before storing work you care about, set up backups. Use the upgrade guide when changing versions.