diff --git a/README.md b/README.md index 13776f9..4024776 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ socket is root on the host anyway. | `UPDATER_API_KEY` | no | — | Bearer token for `POST /update`. Without it the webhook answers `503` and the master logs `webhook_disabled`. | | `UPDATE_TIMEOUT` | no | `5m` | How long one `POST /update` waits for its auto jobs (Go duration). | | `POLL_INTERVAL` | no | `6h` | Time between registry polling cycles (Go duration, must be positive). The first cycle runs one minute after start. | -| `DOCKER_CONFIG` | no | `~/.docker` | Directory with a `config.json` holding registry credentials for polling. Only inline `auths` entries work; see [Registry polling](#registry-polling). | +| `DOCKER_CONFIG` | no | `~/.docker` | Directory with a `config.json` holding registry credentials for polling, readable by the master's user. Only inline `auths` entries work; see [Registry polling](#registry-polling). | The master's other settings (`DATABASE_URL`, `PUBLIC_URL`, `AGENT_URL`, `OIDC_*`, `ALLOWED_GROUP`, `AGENT_IMAGE`, `PORT`, `AGENT_PORT`, `LOG_LEVEL`) are shown in @@ -147,9 +147,10 @@ multi-arch image the digest is the index digest, the same one `docker inspect` s "poll failed" badge on the overview and in the "Polling" row of the service page; other tags continue. A later success clears it. - **Credentials.** The master reads `$DOCKER_CONFIG/config.json` (a file written by - `docker login`), mounted read-only into the container and readable by the master's user (`65534` in the - example stack); without it registries are accessed - anonymously. Only inline `auths` entries are supported. A `credsStore` or `credHelpers` + `docker login`), mounted read-only into the container; without it registries are accessed + anonymously. The directory and file must be readable by the master's user (`65534` in the + example stack) without being world-readable: `chown -R 65534:65534` the directory and keep + `0700`/`0600`. Only inline `auths` entries are supported. A `credsStore` or `credHelpers` entry makes every lookup fail with `error getting credentials ... executable file not found in $PATH`, because the container has no credential helper binaries. The master logs `registry_credentials` at startup with the directory, `config_json_found` and @@ -203,7 +204,7 @@ the agent's token (shown once) and the master's key fingerprint; the same layout | `AGENT_TOKEN` | yes | — | Token shown once when the agent was added. | | `SELF_ID` | no | hostname | Container ID or name of the agent itself; used to read its mounts. | | `UPDATE_TIMEOUT` | no | `5m` | Per-job timeout (Go duration). | -| `DOCKER_CONFIG` | no | — | Directory with a `config.json` holding registry credentials, readable by the master's user (see the `config_json_readable` and `registry_credentials_unreadable` log fields). Only inline `auths` entries work; `credsStore`/`credHelpers` are not available in the container. | +| `DOCKER_CONFIG` | no | — | Directory with a `config.json` holding registry credentials. Only inline `auths` entries work; `credsStore`/`credHelpers` are not available in the container. | | `LOG_LEVEL` | no | `info` | `debug` / `info` / `warn` / `error`. | `docker compose` runs inside the agent with only `PATH`, `HOME` and the `DOCKER_*` diff --git a/deploy/master.stack.yml b/deploy/master.stack.yml index 8d67ac8..a651ab5 100644 --- a/deploy/master.stack.yml +++ b/deploy/master.stack.yml @@ -13,10 +13,11 @@ # 5. Optional, for registry polling of private images: put a config.json written by # `docker login` (inline "auths" only; no credsStore) in /path/to/docker-config and # uncomment DOCKER_CONFIG and the volumes entry below. The master runs as 65534:65534, so -# config.json must be readable by that user: `chmod 0644` it, or set `user:` below to the -# file owner's uid:gid. The directory must exist on every -# manager node (the master is placed on a manager), or Swarm rejects the task. Without -# it registries are accessed anonymously. +# the directory and config.json must be readable by that user while staying private: +# `chown -R 65534:65534 /path/to/docker-config` (keep 0700/0600), or set `user:` below +# to the owner's uid:gid. Do not make config.json world-readable; it holds registry +# passwords. The directory must exist on every manager node (the master is placed on a +# manager), or Swarm rejects the task. Without it registries are accessed anonymously. services: master: image: gitea.shcizo.se/shcizo/package-updater:latest