# LibrePortal — Upgrade Notes Version-specific notes for **existing installs**. `libreportal update apply` replaces the install tree only — it never rewrites an app's deployed `//docker-compose.yml`. So a fix to an app template reaches a running app on its next `libreportal app install ` (also the path taken by restore, peer pull, and migrate), not on update. Anything below that needs a manual step says so. ## 0.2.0 — Mastodon shipped with unsubstituted database credentials **Affects:** anyone who installed Mastodon on 0.1.0. No other app is affected. ### What went wrong Compose templates carry tag annotations of the form `#LIBREPORTAL||`, where `` is the *current literal* the tag manager searches for on that line. Mastodon's annotations used `unconfigured` while the line bodies said `PASSWORD_TAG_1_DATA` and friends, so the two never matched and nothing was ever substituted: ```yaml - DB_PASS=PASSWORD_TAG_1_DATA #LIBREPORTAL|PASSWORD_TAG_1|unconfigured ``` The literal placeholder strings shipped as the real values. Because `unconfigured` does not look like a placeholder, neither the tag state check nor the pre-start stale-tag gate in `dockerComposeUp` flagged it, and restarts did not heal it. An affected instance is running with these publicly known constants: | Setting | Value in an affected install | | --- | --- | | `DB_USER` / `POSTGRES_USER` | `RANDOM_TAG_1_DATA` | | `DB_PASS` / `POSTGRES_PASSWORD` | `PASSWORD_TAG_1_DATA` | | `DB_NAME` / `POSTGRES_DB` | `RANDOM_TAG_2_DATA` | | `SECRET_KEY_BASE` | `HEX_TAG_1_DATA` | | `OTP_SECRET` | `HEX_TAG_2_DATA` | | `VAPID_PRIVATE_KEY` / `VAPID_PUBLIC_KEY` | `VAPID_TAG_1_DATA` / `VAPID_TAG_2_DATA` | `mastodon-postgres` publishes no host port, so the database is reachable only from other containers on the LibrePortal network — but `SECRET_KEY_BASE` is what Rails uses to sign and encrypt session cookies, and the web service *is* internet-facing through Traefik. Treat a public instance as needing rotation, not just cleanup. ### Why you cannot just re-install `libreportal app install mastodon` copies the corrected template over the deployed compose and generates real credentials. The Postgres volume (`/mastodon/postgres`) was initialised with the old literals and keeps them — `POSTGRES_*` is only read by `initdb` on an empty data directory. The new credentials will not match, and the app will fail to reach its database. Pick one of the two paths below. ### Path A — discard the instance (no data worth keeping) ```bash libreportal app uninstall mastodon libreportal app install mastodon ``` Everything is regenerated correctly. Federation identity is lost; the instance is new to the network. ### Path B — keep the data, rotate the credentials Take a cold copy first — with the app stopped, the app folder contains the whole database: ```bash libreportal app stop mastodon sudo cp -a /mastodon /mastodon.bak-0.1.0 ``` Re-template to get real credentials into the compose file: ```bash libreportal app install mastodon ``` Read the values it generated: ```bash grep -E 'POSTGRES_(DB|USER|PASSWORD)=' /mastodon/docker-compose.yml ``` Bring up only the database and connect as the old superuser (the container's unix socket trusts local connections, so no password is needed): ```bash docker start mastodon-postgres docker exec -it mastodon-postgres psql -U RANDOM_TAG_1_DATA -d postgres ``` Rename the database and create the new role, substituting the three values you just read: ```sql ALTER DATABASE "RANDOM_TAG_2_DATA" RENAME TO ""; CREATE ROLE "" LOGIN SUPERUSER PASSWORD ''; \c "" REASSIGN OWNED BY "RANDOM_TAG_1_DATA" TO ""; \c postgres "" DROP ROLE "RANDOM_TAG_1_DATA"; ``` The rename needs no active sessions on that database, which is why Mastodon is stopped. The role is created and the objects reassigned rather than renamed — PostgreSQL refuses to rename the session role you are connected as. Start the app: ```bash libreportal app start mastodon ``` **Expect user-visible fallout.** `SECRET_KEY_BASE` changed, so every session is invalidated and everyone logs in again. `OTP_SECRET` changed, which affects stored two-factor enrolments — be ready to clear 2FA for users who are locked out: ```bash docker exec -it mastodon-service bin/tootctl accounts modify --disable-2fa ``` The VAPID keypair changed too; browsers re-subscribe to push on next login. Once the instance is healthy, remove the backup copy. ### Known limitation, both paths Re-templating an app regenerates every `PASSWORD_TAG_*` / `RANDOM_TAG_*` / `HEX_TAG_*` / `VAPID_TAG_*` value — the generators mint a fresh secret on each run and the tag manager writes it in. For any app whose database lives in a persistent volume, that means a re-template can desynchronise the compose file from the initialised database exactly as described above. This is not specific to Mastodon or to this fix; app credentials that must survive re-templating are the ones held in `.config` as `RANDOMIZEDPASSWORD` / `RANDOMIZEDUSERNAME`, which are generated once and persisted.