Skip to content

contrib/sni-router: render mtg-config.toml from a tracked .example#525

Merged
9seconds merged 2 commits into
masterfrom
contrib/sni-router-config-example
May 20, 2026
Merged

contrib/sni-router: render mtg-config.toml from a tracked .example#525
9seconds merged 2 commits into
masterfrom
contrib/sni-router-config-example

Conversation

@dolonet
Copy link
Copy Markdown
Collaborator

@dolonet dolonet commented May 19, 2026

Summary

Track mtg-config.toml.example with secret = "${MTG_SECRET}"; the rendered mtg-config.toml (and .env) are now gitignored. The secret never lands in a tracked file, which is the gap discussed in #506.

Quick start step 3 switches from:

mtg-config.toml → paste the secret

to either:

export MTG_SECRET=...    # paste the hex secret from step 2
envsubst < mtg-config.toml.example > mtg-config.toml

or, for users without envsubst:

cp mtg-config.toml.example mtg-config.toml && $EDITOR mtg-config.toml   # edit ${MTG_SECRET}

Single placeholder file works for either workflow.

Why this shape

#506 asked for env-var support inside the TOML loader; @9seconds settled that with "TOML stays static, templating belongs in deploy-layer CLI tools" (composability). That principle leaves the contrib example as the right place to show the standard templating step, not mtg itself. This PR does exactly that — keeps mtg static, keeps the compose minimal (no init container, no entrypoint rewrites, no apk add at startup), and uses the tool @9seconds named (envsubst) as the documented path while still working with a plain cp + edit for users on platforms without it.

After #502 made DOMAIN env-driven for HAProxy + Caddy, the secret was the last manual touch of a tracked file in the example. This closes that gap.

Test plan

  • envsubst < mtg-config.toml.example > mtg-config.toml produces a valid TOML file with secret = "<resolved>"
  • No code changes; mtg parses the rendered file exactly as before (only the placeholder line differs from current behaviour)
  • .gitignore covers both mtg-config.toml and .env
  • README quick start, file table, and docker-compose.yml header comment all updated in sync
  • export MTG_SECRET=... ; envsubst < ... form is shell-safe on literal copy-paste (the earlier MTG_SECRET=<placeholder> form parsed <placeholder> as a redirection — fixed in 3d0899d)

Track `mtg-config.toml.example` with `secret = "${MTG_SECRET}"`; the
rendered `mtg-config.toml` and local `.env` are gitignored, so the
secret never lands in a tracked file.

Quick start switches from "paste the secret into mtg-config.toml" to
either `envsubst < mtg-config.toml.example > mtg-config.toml` or
`cp` + hand-edit `${MTG_SECRET}` for users without envsubst.

After #502 made DOMAIN env-driven, the secret was the last hand-edit
of a tracked file in the example. Follow-up to #506.
…ples

`MTG_SECRET=<placeholder> envsubst < ...` was shell-broken on literal
copy-paste — bash parses `<placeholder>` as redirection from a
non-existent file. Two-line `export MTG_SECRET=...` + plain envsubst
form removes the ambiguity. Applies to README, docker-compose.yml,
and the .example header.
@bam80
Copy link
Copy Markdown
Contributor

bam80 commented May 19, 2026

Nah, the system should synchronize secret/domains in all the 3 places itself, no manual steps should be involved.
Otherwise, it's very hard to debug.
I just spent a few hours chasing for this.

no init container, no entrypoint rewrites, no apk add at startup

And this is the problem. Upstream compose (or rather contrib, as there is no upstream) should provide all the needed for the above, and compensate lack of mtg's abilities if needed. Nothing bad if it's not minimal, this is for a reason.

Having that, the patch seems useful, but definitely not enough.

@dolonet
Copy link
Copy Markdown
Collaborator Author

dolonet commented May 20, 2026

The shape you're describing — runtime template rendering inside the container, apk add at startup, an init step — is the path @9seconds declined in #506 ("TOML stays static, templating belongs in CLI tools; composability gives simpler design"). #525 follows exactly that line: tracked .example + envsubst (the tool he named), rendered once on the host, secret stays out of git.

On the "3 places" — after #502 + this PR, the only substitution surface is two env vars (DOMAIN, MTG_SECRET) both in .env; HAProxy/Caddy read $DOMAIN at runtime, the TOML is rendered once. If you hit a sync bug in your own inline-Dockerfile variant, happy to look at that separately, but I don't want to roll the rejected runtime-template approach back into contrib without @9seconds.

Leaving the merge call to @9seconds.

@9seconds
Copy link
Copy Markdown
Owner

@bam80 but this is just a suggested configuration, and it is not specific to mtg, this is just a general Unix stuff. I think that for this scope this is already quite good and reasonable PR. If we want to have some generic mechanism, sure, we can just put envsubst in a docker container.

@9seconds 9seconds merged commit a3ff5ca into master May 20, 2026
15 checks passed
@9seconds 9seconds deleted the contrib/sni-router-config-example branch May 20, 2026 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants