Install with Coolify
Myrtille runs as one service of your Coolify: one container, its data on a volume of its own. You need Coolify 4.2.0 or later (4.4.0 or later to see preview deployments).
What Myrtille never does here
Section titled “What Myrtille never does here”- It never changes anything in Coolify on its own. The town starts read-only: no district accepts an action until an admin of that district turns its actions on.
- It never shows a Coolify token once it has checked it, not even to the owner. Tokens are stored encrypted in the town hall, never in a file you edit.
- It never runs as root: the container runs as a user without rights, with a read-only file system except for its volume, no capability and
no-new-privileges.
Install
Section titled “Install”- In Coolify, open a project and choose New resource > Docker Compose Empty.
- Paste the template below and save.
- Coolify gives the service a domain (
SERVICE_URL_MYRTILLE, port 7420 behind its proxy) and generates its instance secret once (SERVICE_HEX_64_MYRTILLE). Deploy. - Open the logs of the service: they print the setup token.
- Open the domain. The first screen creates the owner account with that token; the setup then connects Coolify, discovers the town, gives the webhook address to paste in Coolify, and shows the command of the local agent. It takes less than ten minutes. First steps walks through each screen.
The template, deploy/coolify/myrtille.compose.yaml in the repository:
# documentation: https://docs.myrtille.eu# slogan: Run your company like a town: what runs, and what waits for a decision, in a living pixel-art town.# category: monitoring# tags: myrtille,coolify,town,dashboard,claude,agents,devops,monitoring# logo: svgs/myrtille.svg# port: 7420
# The template of Myrtille for Coolify (S5-T04, ADR-0020: pinned on the `latest` image). Coolify gives it a domain and# a secret of its own; the setup token is printed in the logs of the service at its first start.services: myrtille: image: ghcr.io/myrtillehq/engine:latest environment: - SERVICE_URL_MYRTILLE_7420 - MYRTILLE_MODE=selfhost - MYRTILLE_PUBLIC_URL=${SERVICE_URL_MYRTILLE} # 32 random bytes in hex, generated once by Coolify: the credentials of the volume are useless without it. - MYRTILLE_SECRET=${SERVICE_HEX_64_MYRTILLE} # The proxy of Coolify (Traefik) is the one hop in front of the town hall. - MYRTILLE_TRUSTED_PROXIES=1 volumes: - myrtille-data:/data read_only: true tmpfs: - /tmp security_opt: - no-new-privileges:true cap_drop: - ALLvolumes: myrtille-data:What the template sets:
MYRTILLE_PUBLIC_URLis the domain Coolify gives the service: the town allows that origin only, with secure cookies.MYRTILLE_SECRETis generated by Coolify and kept in the environment of the service, never in the volume. A copy of the volume alone cannot read the credentials it holds.MYRTILLE_TRUSTED_PROXIES=1: the proxy of Coolify is the one hop in front of the town hall, so the rate limits see the real address of each visitor.- The health check of the image calls
/health.
Update
Section titled “Update”Make a backup first (below). Then redeploy the service: Coolify pulls the image again, and the town hall applies the migrations of its database when it starts. A town hall never opens a database migrated by a newer version: to go back, restore the backup made before the update.
Back up
Section titled “Back up”An owner downloads a hot copy of the database while the service runs, with the command line of Myrtille (npx fetches it):
npx @myrtillehq/cli backup --town-hall https://<domain> --out myrtille-backup.dbIt asks for the e-mail and password of an owner (or reads MYRTILLE_EMAIL and MYRTILLE_PASSWORD), writes the file readable by you only, never over an existing file, and prints its size and SHA-256.
The backup holds the accounts, the audit log and the state of the town plan. It also holds the credentials, encrypted with the instance secret, which the backup does not contain. Keep the instance secret apart: it is the value of SERVICE_HEX_64_MYRTILLE in the environment variables of the service, where Coolify shows it.
Restore
Section titled “Restore”The service stopped, the image restores a backup itself, from a directory of the server that holds the backup file:
docker run --rm --user node -v <volume of the service>:/data -v <dir>:/backup:ro ghcr.io/myrtillehq/engine:latest restore /backup/myrtille-backup.dbUse the same tag as the service (latest, or next before 1.0). Then start the service again.
- The volume of the service is named
<id of the service>_myrtille-data: the id is the last part of the address of the service in Coolify, anddocker volume ls --filter name=myrtille-dataon the server lists it. - A restore while the service runs is refused.
- The restore keeps the database it replaces in the volume and never deletes it. To go back, restore that file the same way:
restore /data/town.db.before-restore-<time>. - At its next start, the town hall records the restore in its audit log.
On a new server or a new service
Section titled “On a new server or a new service”A backup cannot read its credentials without the instance secret of the town it came from. Create the service from the template, set SERVICE_HEX_64_MYRTILLE to the old value in its environment variables before its first deploy, then stop it, restore and start it.
- First steps: the setup, the mail and the actions.
- Coolify: the tokens, the webhook and polling.
- Install with Docker Compose: the same image without Coolify, with every detail of backups.