Upgrades
Pin a release, move to a new one with a short maintenance window and roll back if it fails.
This procedure is for the Compose installer and cloud VMs. Railway, Render, Coolify, Dokploy, Easypanel and CapRover each have an Upgrades section in their platform guide. Run the commands from the install directory: ./grovs for the installer, /opt/grovs as root on a cloud VM. For a local trial, replace --profile standalone with -f docker-compose.yml -f docker-compose.local.yml.
Pin the version
GROVS_VERSION in .env selects the tag for both ghcr.io/grovs-io/backend and ghcr.io/grovs-io/dashboard. Setup and the installer write a numbered release there, such as 2.3.1.
| Value | Behavior |
|---|---|
| A numbered release | Recommended for production. Nothing changes until you edit it. |
latest | Takes the newest stable images on the next pull. See Images and releases. |
| Unset | Compose falls back to latest |
Check what the stack will run:
docker compose --profile standalone config --imagesBefore you upgrade
- Read the release notes of every release between your version and the target.
- Write down the current
GROVS_VERSION. You need it to roll back. - Take a fresh backup with the backup script and keep it until the new version has run cleanly.
Upgrade
Print the latest completed release without touching your installation:
GROVS_RELEASE_URL="$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/grovs-io/self-host/releases/latest)"
printf 'GROVS_VERSION=%s\n' "${GROVS_RELEASE_URL##*/}"Set the GROVS_VERSION line in .env to that value.
Clear any shell override so Compose reads the saved value, then run:
unset GROVS_VERSION
docker compose --profile standalone config --images
docker compose --profile standalone pull
docker compose --profile standalone stop dashboard web worker-1 worker-2
docker compose --profile standalone run --rm migrate
docker compose --profile standalone up -d
docker compose --profile standalone ps -aThe application is down between stop and up.
Check https://<API_HOST>/up, log in, open a link and confirm new analytics arrive. See Monitoring.
pull also refreshes the supporting images within their tags: postgres:16-alpine, redis:7-alpine, clickhouse/clickhouse-server:25.3 and caddy:2-alpine. The upgrade changes images only; your Compose file, Caddyfile and .env stay as they are.
Migrations
migrate runs db:prepare for PostgreSQL, the seed, and the ClickHouse setup. It also runs on every up that recreates it, and it is safe to repeat. The application services start only after it exits with code 0.
If it fails, the application stays stopped. Read the error before you do anything else:
docker compose --profile standalone logs migrateFix the cause and run migrate again, or roll back.
Roll back
Set the previous version again. If migrate ran on the new version, restore the backup you took before the upgrade too: the database schema has already moved forward.
docker compose --profile standalone stop dashboard web worker-1 worker-2Set GROVS_VERSION in .env back to the version you wrote down, then pull it:
unset GROVS_VERSION
docker compose --profile standalone pullSkip this step only if migrate never ran on the new version. Otherwise follow Restore from Start the data stores through Restore uploads with the pre-upgrade backup. Data written after that backup is lost.
docker compose --profile standalone up -d
docker compose --profile standalone ps -aRules
- Setup and the installer keep an existing
.env. Edit its version explicitly, and use this procedure rather than the installer for upgrades. - Never regenerate secrets or encryption keys during an upgrade.
- Keep the backend and dashboard on the same version.
- A restart alone does not fetch a new image.