Docker
tvault docker wraps the Docker CLI so a project's secrets reach a build, a compose stack, or a container without putting values on the docker command line or writing a plaintext .env.
You still need Docker on PATH. TinyVault does not talk to the daemon itself.
tvault docker build --only NPM_TOKEN -- -t app .
tvault docker compose --only DATABASE_URL -- up
tvault docker run --only DATABASE_URL -- --rm alpine env
tvault docker init # Dockerfile + compose snippets--only, --prefix, --strict, --identity, --group, and --env work the same as on tvault run. Put TinyVault flags before --; everything after is passed to Docker.
BuildKit secret mounts
tvault docker build sets DOCKER_BUILDKIT=1 and adds one --secret id=KEY,env=KEY per selected key. Values live in the docker process environment, not on argv. The Dockerfile reads them from a build tmpfs:
FROM node:22
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=secret,id=NPM_TOKEN \
NPM_TOKEN="$(cat /run/secrets/NPM_TOKEN)" npm ci
COPY . .tvault docker build --only NPM_TOKEN -- -t app .If you only read the secret in that RUN, it is not stored in an image layer. Prefer --only / --prefix so the build client only sees the keys the Dockerfile mounts.
Print a starter snippet with tvault docker init.
Compose interpolation
tvault docker compose injects selected keys into the compose process environment. Compose expands ${KEY} in the compose file from that environment. Values do not appear as -e flags on argv.
services:
app:
build: .
environment:
DATABASE_URL: ${DATABASE_URL}tvault docker compose --only DATABASE_URL -- upFor a compose build secret, declare it from the same environment:
secrets:
npm_token:
environment: NPM_TOKEN
services:
app:
build:
secrets:
- npm_tokendocker run
tvault docker run adds -e KEY (the name only) for each selected key. Docker reads the value from the client environment, so it does not appear on argv. The container still has the value in its environment — the same residual risk as tvault run.
tvault docker run --only DATABASE_URL -- --rm alpine envWhat this does not do
- It does not put a vault inside the image. In-cluster or CI fetch still uses a recipient identity (
TVAULT_IDENTITY_KEY) and committed ciphertext, not the developer laptop's passphrase. - It does not replace
tvault run -- docker compose up, which already injects the full project env.tvault docker compose --only …is the least-privilege form. - BuildKit
--secretrequires a modern Docker engine (BuildKit is the default). The wrapper setsDOCKER_BUILDKIT=1on the child.
WARNING
Compose interpolation and docker run still place plaintext in a process or container environment. Treat that process as trusted. For a file you can commit, use committable secrets instead of baking values into an image.