Skip to content

Docker

A few ways to pass varsafe secrets into Docker containers.

varsafe Inside the Container

Install the CLI in your image and let the container fetch its own secrets at startup. You only need to pass a single API token:

dockerfile
FROM node:22-slim

# Install varsafe CLI
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
    rm -rf /var/lib/apt/lists/* && \
    curl -fsSL https://varsafe.dev/install.sh | bash
ENV PATH="/root/.varsafe/bin:$PATH"

COPY . .

CMD ["varsafe", "run", "-p", "my-api", "-e", "production", "--", "node", "server.js"]
bash
docker run -e VARSAFE_API_TOKEN=vs_at_... my-image

In compose:

yaml
services:
  app:
    build: .
    environment:
      - VARSAFE_API_TOKEN=${VARSAFE_API_TOKEN}

Rotate secrets in varsafe and containers pick them up on next restart — no redeployment needed.

INFO

The container needs network access to the varsafe API at startup.

Export to env_file

Export secrets to a file and let Docker load it.

With docker run, use --format docker (unquoted KEY=value) since docker run --env-file treats quotes as literal characters:

bash
varsafe export -f docker -o .env.production
docker run --env-file .env.production my-image

With compose, the default env format works because compose strips quotes:

bash
varsafe export -o .env.production
yaml
services:
  app:
    image: my-image
    env_file:
      - .env.production

TIP

Add exported files to .gitignore to keep them out of version control.

Inject from Host Environment

Use varsafe run to inject secrets into the shell, then let compose (or docker run) read them:

bash
varsafe run -- docker compose up
yaml
services:
  app:
    image: my-image
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - API_KEY=${API_KEY}

Compose resolves ${VAR} from the current shell environment, where varsafe run has already injected them.

Use --include to filter which secrets get injected:

bash
# Only inject database and API secrets
varsafe run --include 'DB_*,API_*' -- docker compose up

With docker run:

bash
varsafe run -- docker run -e DATABASE_URL -e API_KEY my-image

INFO

You need to list each variable explicitly in the compose file or docker run command. Use environment: - KEY (no value) to pass through from the host.

Pipe via stdin

Pass secrets directly into docker run without writing a file:

bash
varsafe export -f docker | docker run -i --env-file /dev/stdin my-image

INFO

This works with docker run only, not docker compose.

CI/CD

In CI, combine an API token with any approach above:

yaml
- name: Deploy
  run: |
    docker run \
      -e VARSAFE_API_TOKEN=${{ secrets.VARSAFE_API_TOKEN }} \
      my-image
yaml
deploy:
  script:
    - docker run
        -e VARSAFE_API_TOKEN=$VARSAFE_API_TOKEN
        my-image

For build-time secrets (e.g. private registries), use varsafe export with --mount=type=secret:

dockerfile
# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=env,target=/tmp/.env \
    cat /tmp/.env && npm run build
bash
varsafe export -f docker | docker build --secret id=env,src=/dev/stdin .