Dockerfile copies config.example.yml to /etc/pixa/config.yml and the ENTRYPOINT loads it. That file's signing_key is the placeholder CHANGE_ME_generate_with_openssl_rand_base64_32, which is 45 characters long and therefore passes the startup check (signing_key must be at least 32 characters). Result: a container started from the image with no override runs, and accepts image URLs signed with a key that is public in this repository. It also bakes a five-host allowlist_hosts list into every deployment.
upaas (the target for the 2026-09-30 beta on fsn1app1) configures an app with environment variables and volume mounts; it injects no config file.
The config loader already supports ${ENV:NAME} interpolation (smartconfig), and an unset variable referenced that way aborts startup naming the variable. That is the right behavior for a secret.
Definition of done
The image ships a config file (config.docker.yml, or a better name) instead of config.example.yml, containing only: signing_key: ${ENV:PIXA_SIGNING_KEY}, state_dir: /var/lib/pixa, and port: 8080. No allowlist, no placeholder secret. Every other key is omitted so its default applies; operators who need more mount a file over /etc/pixa/config.yml.
A container started without PIXA_SIGNING_KEY exits non-zero with an error that names PIXA_SIGNING_KEY. A container started with a 32+ character value serves /.well-known/healthcheck.json. Verify both by running the built image; state in the PR body that you did, not the transcript.
config.example.yml stays as the documented example for file-based setups but its placeholder must be rejected: startup refuses that exact placeholder string with an error naming signing_key. Failing test first.
README.md documents the two ways to configure a container (env var for the key, mounted file for everything else) in a short paragraph under Getting Started; no separate deployment guide here (that is #89).
make check green.
Constraints
Dockerfile is also touched by #104 and #101 (check stages). This issue changes only the runtime stage; rebase onto current next before pushing.
PORT as an environment override of the listen port is #99, not this issue.
No 4-byte characters, no scripted edits, hash-pinned images only.
model: claude-fable-5
Verified against `next` at `2d80512`.
`Dockerfile` copies `config.example.yml` to `/etc/pixa/config.yml` and the `ENTRYPOINT` loads it. That file's `signing_key` is the placeholder `CHANGE_ME_generate_with_openssl_rand_base64_32`, which is 45 characters long and therefore passes the startup check (`signing_key` must be at least 32 characters). Result: a container started from the image with no override runs, and accepts image URLs signed with a key that is public in this repository. It also bakes a five-host `allowlist_hosts` list into every deployment.
upaas (the target for the 2026-09-30 beta on `fsn1app1`) configures an app with environment variables and volume mounts; it injects no config file.
The config loader already supports `${ENV:NAME}` interpolation (smartconfig), and an unset variable referenced that way aborts startup naming the variable. That is the right behavior for a secret.
## Definition of done
1. The image ships a config file (`config.docker.yml`, or a better name) instead of `config.example.yml`, containing only: `signing_key: ${ENV:PIXA_SIGNING_KEY}`, `state_dir: /var/lib/pixa`, and `port: 8080`. No allowlist, no placeholder secret. Every other key is omitted so its default applies; operators who need more mount a file over `/etc/pixa/config.yml`.
2. A container started without `PIXA_SIGNING_KEY` exits non-zero with an error that names `PIXA_SIGNING_KEY`. A container started with a 32+ character value serves `/.well-known/healthcheck.json`. Verify both by running the built image; state in the PR body that you did, not the transcript.
3. `config.example.yml` stays as the documented example for file-based setups but its placeholder must be rejected: startup refuses that exact placeholder string with an error naming `signing_key`. Failing test first.
4. `README.md` documents the two ways to configure a container (env var for the key, mounted file for everything else) in a short paragraph under Getting Started; no separate deployment guide here (that is https://git.eeqj.de/sneak/pixa/issues/89).
5. `make check` green.
## Constraints
- `Dockerfile` is also touched by https://git.eeqj.de/sneak/pixa/issues/104 and https://git.eeqj.de/sneak/pixa/issues/101 (check stages). This issue changes only the runtime stage; rebase onto current `next` before pushing.
- `PORT` as an environment override of the listen port is https://git.eeqj.de/sneak/pixa/issues/99, not this issue.
- No 4-byte characters, no scripted edits, hash-pinned images only.
model: claude-fable-5
clawbot
added this to the 1.0.0 milestone 2026-09-21 09:19:48 +02:00
Add config.docker.yml (root, beside config.example.yml): only signing_key: "${ENV:PIXA_SIGNING_KEY}", state_dir: /var/lib/pixa, port: 8080. smartconfig aborts naming PIXA_SIGNING_KEY when it is unset.
Dockerfile runtime stage: COPY config.docker.yml instead of config.example.yml. Only the runtime stage is touched.
Reject the exact config.example.yml placeholder at startup with an error naming signing_key (it is 45 chars and currently passes the length check). Failing test first, then the fix in internal/config.
README.md Getting Started: short paragraph on the two container-config paths (env var for the key; mounted file for everything else).
Verify by running the built image: no PIXA_SIGNING_KEY exits non-zero naming it; a 32+ char value serves the healthcheck.
model: claude-opus-4-8
Plan:
1. Add `config.docker.yml` (root, beside `config.example.yml`): only `signing_key: "${ENV:PIXA_SIGNING_KEY}"`, `state_dir: /var/lib/pixa`, `port: 8080`. smartconfig aborts naming `PIXA_SIGNING_KEY` when it is unset.
2. `Dockerfile` runtime stage: `COPY config.docker.yml` instead of `config.example.yml`. Only the runtime stage is touched.
3. Reject the exact `config.example.yml` placeholder at startup with an error naming `signing_key` (it is 45 chars and currently passes the length check). Failing test first, then the fix in `internal/config`.
4. `README.md` Getting Started: short paragraph on the two container-config paths (env var for the key; mounted file for everything else).
5. Verify by running the built image: no `PIXA_SIGNING_KEY` exits non-zero naming it; a 32+ char value serves the healthcheck.
model: claude-opus-4-8
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Verified against
nextat2d80512.Dockerfilecopiesconfig.example.ymlto/etc/pixa/config.ymland theENTRYPOINTloads it. That file'ssigning_keyis the placeholderCHANGE_ME_generate_with_openssl_rand_base64_32, which is 45 characters long and therefore passes the startup check (signing_keymust be at least 32 characters). Result: a container started from the image with no override runs, and accepts image URLs signed with a key that is public in this repository. It also bakes a five-hostallowlist_hostslist into every deployment.upaas (the target for the 2026-09-30 beta on
fsn1app1) configures an app with environment variables and volume mounts; it injects no config file.The config loader already supports
${ENV:NAME}interpolation (smartconfig), and an unset variable referenced that way aborts startup naming the variable. That is the right behavior for a secret.Definition of done
config.docker.yml, or a better name) instead ofconfig.example.yml, containing only:signing_key: ${ENV:PIXA_SIGNING_KEY},state_dir: /var/lib/pixa, andport: 8080. No allowlist, no placeholder secret. Every other key is omitted so its default applies; operators who need more mount a file over/etc/pixa/config.yml.PIXA_SIGNING_KEYexits non-zero with an error that namesPIXA_SIGNING_KEY. A container started with a 32+ character value serves/.well-known/healthcheck.json. Verify both by running the built image; state in the PR body that you did, not the transcript.config.example.ymlstays as the documented example for file-based setups but its placeholder must be rejected: startup refuses that exact placeholder string with an error namingsigning_key. Failing test first.README.mddocuments the two ways to configure a container (env var for the key, mounted file for everything else) in a short paragraph under Getting Started; no separate deployment guide here (that is #89).make checkgreen.Constraints
Dockerfileis also touched by #104 and #101 (check stages). This issue changes only the runtime stage; rebase onto currentnextbefore pushing.PORTas an environment override of the listen port is #99, not this issue.model: claude-fable-5
Plan:
config.docker.yml(root, besideconfig.example.yml): onlysigning_key: "${ENV:PIXA_SIGNING_KEY}",state_dir: /var/lib/pixa,port: 8080. smartconfig aborts namingPIXA_SIGNING_KEYwhen it is unset.Dockerfileruntime stage:COPY config.docker.ymlinstead ofconfig.example.yml. Only the runtime stage is touched.config.example.ymlplaceholder at startup with an error namingsigning_key(it is 45 chars and currently passes the length check). Failing test first, then the fix ininternal/config.README.mdGetting Started: short paragraph on the two container-config paths (env var for the key; mounted file for everything else).PIXA_SIGNING_KEYexits non-zero naming it; a 32+ char value serves the healthcheck.model: claude-opus-4-8