Skip to content

CI and 26 services: pin actions, validate Compose, require your own secrets - #368

Merged
crypt0rr merged 18 commits into
mainfrom
t3code/template-baseline-ci-review
Oct 9, 2026
Merged

crypt0rr merged 18 commits into
mainfrom
t3code/template-baseline-ci-review

Conversation

@jackspiering

@jackspiering jackspiering commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Review of the repo against templates/service-template/ and CONTRIBUTING.md (the template placeholder in the request was blank, so AGENTS.md decided the baseline), plus fixes for the findings that were approved.

Review findings

  • Structure: all 122 services follow the template (123 since Umami from Umami: new service #349 was merged in, which already uses the guard). The deviations I found (published ports, docker.sock, privileged, extra containers, no Serve) are all documented in the service READMEs, so I left them alone.
  • CI: the actions were tag-pinned, there was no permissions:, concurrency or timeout, .github/** was never linted, and CI did not run docker compose config.
  • Code: 15 services shipped well-known passwords or placeholders that start the stack as they are, for example Paperless admin/changeme, a Seafile fallback admin password asecret, and the REPLACE_WITH_... values that still work as secrets.
  • Technitium publishes its web console over plain HTTP on all host interfaces. That is documented, so I only added a README warning.
  • A read-only docker.sock mount does not limit Docker API access. Several comments and READMEs suggested it does.

Commits

  1. CI: pin actions to SHAs, permissions: contents: read, concurrency, timeout, lint .github/** (planned commits 1 and 2, merged).
  2. CI: new compose-validation.yml runs docker compose config --quiet on every service. Stacks that require their own secrets get a dummy value per missing variable.
  3. Paperless, Flatnotes, Technitium, EspoCRM, NextExplorer: require your own secrets.
  4. Coder, Mattermost, Sure, XWiki, AFFiNE, Immich, Tandoor: require your own database passwords.
  5. GitSave, ArtistTrackarr, Seafile: require your own secrets.
  6. Technitium README: warn about the plain HTTP console on port 5380.
  7. Docker socket: :ro does not limit API access (comments and READMEs).
  8. Tandoor: require SECRET_KEY in the application environment.
  9. CI: use the latest rumdl action (v0.2.78).
  10. CI: cancel superseded runs only on pull requests, and fail the validation when it runs out of retries.
  11. Upgrading notes: name the old sample database password or key, so a user who kept it can set it again. The database still uses it.
  12. CI: pin the rumdl version (version: "0.2.78"), so that the linter no longer follows the latest release.
  13. Sure, Tandoor, GitSave: require SECRET_KEY_BASE in Sure (both containers), and give one way to generate each secret. Tandoor had two commands in .env, and GitSave pointed to a website that generates secrets.
  14. Booklore, FreshRSS, Kaneo, KitchenOwl, Miniflux: the secrets were already empty in .env, but Compose started the stack without them. They now have the ${VAR:?Set VAR in .env} guard. No sample value was removed, so these stacks have no Upgrading note.
  15. AdGuard Home Sync, Formbricks, Frigate, Ghost, Gotify, Nanote: the well-known passwords that were literal values in compose.yaml (admin, example, postgres, password, <yourkey>) are now empty variables in .env with the guard, and each README has an Upgrading note that names the old value. Formbricks builds DATABASE_URL from POSTGRES_PASSWORD. Frigate FRIGATE_RTSP_PASSWORD is optional and has no guard, because Frigate only uses it when config.yml refers to it.
  16. AFFiNE, Coder, Mattermost, Miniflux: the database password is part of a connection URL, so .env and the README now ask for letters and digits only.
  17. AFFiNE: remove POSTGRES_HOST_AUTH_METHOD: trust, so that the new database password is enforced on a new database (an existing database keeps the setting it was created with). Paperless, EspoCRM, Technitium, Seafile: the Upgrading note says that the admin password variable only applies at the first start and how to change an existing account.

The secrets commits follow #367: empty in .env, ${VAR:?Set VAR in .env} in compose.yaml, and an Upgrading note in each README.

Related Issues

  • None.

Verification

  • docker compose config --quiet passes on all 123 services with dummy values (the CI script, run with bash -eo pipefail). The changed stacks fail without them, by design.
  • rumdl check --config .markdownlint.yml . and git diff --check are clean.
  • Flatnotes ran live with a filled-in secret: both containers healthy and Tailscale Serve active (checked inside the namespace, because test nodes are not reachable from this host).
  • ArtistTrackarr refuses to start with empty secrets (SETUP_TOKEN must be at least 32 characters).
  • Kaneo refuses to start without AUTH_SECRET upstream (apps/api/src/utils/auth-secret.ts), so the guard only moves the error to Compose.
  • Each new guard stops docker compose config with its message when the value is empty.
  • Formbricks: docker compose config shows the password from .env in both POSTGRES_PASSWORD and DATABASE_URL.
  • Test containers and images were removed afterwards.

Not done

  • Dependabot: declined.
  • Technitium port binding: unchanged, README warning only.
  • Open WebUI WEBUI_SECRET_KEY and Pocket ID ENCRYPTION_KEY have no guard. Open WebUI generates and stores its own key when the value is empty (backend/start.sh), and Pocket ID also accepts ENCRYPTION_KEY_FILE.
  • TAILNET_NAME (Arcane, FreshRSS, Homepage, Miniflux) and TS_TAILNET (Tracktor) are empty and have no guard. They are not secrets.
  • Unused .env keys and image tags in .env: not evaluated.
  • The other 25 changed stacks were not started. They are covered by compose config only.
  • Upgrade notes name the old value: users who git pull and keep their old .env are unaffected. Users who recreate .env from the template must set the values, and for databases must reuse the old password.

Checklist

  • I have performed a self-review of my code and followed the templates structure.
  • I have added verification that the stack works as expected.
  • I have updated necessary documentation (e.g. frontpage README.md ).
  • I have selected the correct label(s) for this PR.

Additional Context

  • The rumdl action is pinned to a commit and the rumdl binary to 0.2.78 through the version input. Update both together.
  • I checked that the action does not use the GitHub API or token (contents: read is enough). The local check ran rumdl 0.2.77; the first CI run shows the installed version.
  • If compose-validation becomes a required check, its paths: filter leaves PRs that do not touch services waiting. I did not change any repo settings.
  • Values that are only read at the first start (Technitium, EspoCRM, Seafile INIT_*, Paperless admin, FreshRSS ADMIN_PASSWORD and ADMIN_API_PASSWORD, Miniflux ADMIN_PASSWORD, Gotify GOTIFY_DEFAULTUSER_PASS) must stay in .env, as in Arcane, ConvertX, Formbricks, Hemmelig, Karakeep: require your own secrets #367.

The pinned SHAs are actions/checkout v7.0.1 3d3c42e5aac5ba805825da76410c181273ba90b1 and rvben/rumdl v0.2.78 9c4cc2a2ebe176de68e1788106e25af8a9bd3899 (dereferenced from the annotated tag), the latest release.

…thub folder

Pin checkout and rumdl to commit SHAs, set contents: read, add a
concurrency group and a timeout, and stop ignoring .github/** so that
workflow and template changes are linted.
Stacks that require your own secrets get a dummy value for each missing
variable, so the rest of the file is still checked.
… own secrets

These stacks shipped well-known sample passwords and keys in .env, such
as admin/changeme. A stack started with them unless the user replaced
each one by hand.

Leave the secrets empty in .env and make Compose stop with an error when
one is missing, as in #367. Document the values and the upgrade steps in
each README.
… own database passwords

These stacks shipped a well-known database password in .env or as a
fallback in compose.yaml. Leave the password empty in .env and make
Compose stop with an error when it is missing, as in #367. Tandoor also
requires its SECRET_KEY. Document the upgrade steps in each README: an
existing database keeps the password it was created with.
These stacks shipped placeholders that start the stack as they are, such
as REPLACE_WITH_RANDOM_ALPHANUMERIC_PASSWORD, and Seafile fell back to a
known administrator password. Leave the secrets empty in .env and make
Compose or the application stop with an error when one is missing, as
in #367. Document the upgrade steps in each README.
The stack publishes the web console on all interfaces of the Docker host.
Say so in the README and name the line to remove when the console is only
used through Tailscale.
A read-only bind mount of docker.sock only protects the socket file. The
service can still control Docker, which is root access to the host. Fix
the comments and READMEs that suggested otherwise.
SECRET_KEY reached the container only through env_file, so an empty value
started the stack. Require it in the application environment, as the
README and the previous commit already state.
…and encryption key

A user who kept the sample value and pulls this change ends up with an
empty value. The database or the stored data still uses the old one, so
say which value to set again.
@jackspiering jackspiering changed the title CI and 15 services: pin actions, validate Compose, require your own secrets CI and 20 services: pin actions, validate Compose, require your own secrets Oct 8, 2026
…he sample passwords to .env and require your own
@jackspiering jackspiering changed the title CI and 20 services: pin actions, validate Compose, require your own secrets CI and 26 services: pin actions, validate Compose, require your own secrets Oct 9, 2026
@jackspiering jackspiering added CI/CD Continuous Integration / Continuous Deployment (CI/CD) enhancement New feature, change or request documentation Improvements or additions to documentation labels Oct 9, 2026
@jackspiering
jackspiering marked this pull request as ready for review October 9, 2026 11:23
@jackspiering
jackspiering requested a review from crypt0rr October 9, 2026 11:23
…CRM, Technitium, Seafile: say how to change an existing admin password
@crypt0rr
crypt0rr merged commit a5fca3c into main Oct 9, 2026
2 checks passed
@crypt0rr
crypt0rr deleted the t3code/template-baseline-ci-review branch October 9, 2026 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD Continuous Integration / Continuous Deployment (CI/CD) documentation Improvements or additions to documentation enhancement New feature, change or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants