In the deploy folder:
docker compose pull
docker compose up -dThe API applies new database migrations when it starts. RELOOP_VERSION in deploy/.env names the release you run, so raise it to the version you want and run the two commands. RELOOP_VERSION=latest takes the newest images every time.
Update from the app
Settings shows an Update now button to the workspace owner when a newer release exists and the updater runs. The button runs the two commands above for you.
The updater is a separate container, watchtower. It holds the Docker socket, so it can pull images and restart containers. It touches only the containers with the label com.centurylinklabs.watchtower.scope=reloop. The app itself never sees the Docker socket. The API reaches the updater inside the Docker network with the token UPDATER_TOKEN from deploy/.env.
The trade-off in plain words: whoever reaches the updater with the token can restart Reloop at any time. That is why the updater is off by default and why the token must stay secret. Keep deploy/.env at permissions 600 and never publish port 8080 of the updater.
To turn it on, add updater to COMPOSE_PROFILES in deploy/.env:
COMPOSE_PROFILES=updaterWith the bundled Caddy the line is COMPOSE_PROFILES=caddy,updater. An install made before this feature has no UPDATER_TOKEN in deploy/.env. Add one with openssl rand -hex 32. Then run docker compose up -d in the deploy folder.
The button does nothing useful when RELOOP_VERSION names a fixed version, which is what a new install gets: the updater pulls that version, finds nothing new and stops. Either raise the version in deploy/.env and run docker compose up -d, or set RELOOP_VERSION=latest and accept that the server then follows every build.
An operator who does not want this leaves the profile off and uses the two commands. The button then stays hidden.
An install that an operator keeps up to date, such as a server that runs from source, sets RELOOP_MANAGED=true. The Version card then shows the version and the state only, without the command and without the button.
Update automatically on a source install
A server that runs from source under systemd, without Docker images, can update itself. deploy/self-update/ holds a shell script, a systemd service and a timer. Every 15 minutes the script compares the newest vX.Y.Z tag on GitHub with the installed version. When a newer one exists it dumps the database, builds the release in a new folder, switches /opt/reloop/app to it and checks that the app and the API answer. When they do not, it switches back. The README in that folder has the install steps, the rollback steps and the warning that a health check is not a review.
Which container sees which secret
deploy/docker-compose.yml gives each service only the variables it reads. The agent never sees CRON_SECRET, UPDATER_TOKEN or the Google, Microsoft and Slack client secrets; the app never sees CRON_SECRET, UPDATER_TOKEN or the model keys. All three read the database, so all three hold DATABASE_URL.
A variable you add to deploy/.env only reaches a container that lists it. If you set one the list does not name, add it to that service's environment: block and run docker compose up -d. A missing variable removes a capability and never stops the container.