Secrets in a build
Ferry gives the variables to a build as BuildKit secrets. A secret does not stay in the image.
Docker records the value of a build argument in the history of the image.
In a generated Dockerfile, Ferry uses BuildKit secrets and never build arguments. Each person who has the image can read its history.
In your own Dockerfile
Each variable is a secret. Its id is the name of the variable. Mount it into the steps that need it.
FROM node:22-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=secret,id=NPM_TOKEN,env=NPM_TOKEN npm ci
COPY . .
RUN npm run build
CMD ["npm", "start"]Requires Docker Engine 27.3 or newer
env= in --mount=type=secret needs Docker Engine 27.3 or newer on the Ferry server. With an older engine, a build that uses variables fails. The message tells you to upgrade Docker.
Ferry also gives each variable as --build-arg. Thus an ARG NPM_TOKEN in your Dockerfile gets the value too. But secrets are safer: Docker records ARG values in the image history.
- Ferry gives the values to
docker buildthrough its environment, never on its command line. - A generated Dockerfile mounts the secrets only into the steps that run your code. These steps are the install of the dependencies and the build command.
# Generated by Ferry: Node.js app (npm).
# Commit your own Dockerfile to customize the build.
FROM node:22-alpine
WORKDIR /app
ARG FERRY_BUILD_ENV_DIGEST
COPY package.json ./
RUN --mount=type=secret,id=LOG_LEVEL,env=LOG_LEVEL \
--mount=type=secret,id=DATABASE_URL,env=DATABASE_URL \
--mount=type=secret,id=GREETING,env=GREETING \
npm install --include=dev --no-audit --no-fund
COPY . .
ENV NODE_ENV=production
CMD ["npm","start"]FERRY_BUILD_ENV_DIGEST gets a keyed digest of the values, not the values. When a variable changes, the digest changes. Then Docker runs the steps that use the variables again and does not take them from the cache.