The Deployer documentation
Creating & deploying a project

Build arguments and secrets

Some builds need more than your code. A Dockerfile can ask for a value while it builds, such as the version to stamp into the app, a token to download a private package, or a login to pull a private base image. This page explains the three kinds of input a build can take, where you give them, and what The Deployer does and never does with them.

The three kinds

KindWhat it isWho can see it
Build argumentA plain value used only while the image builds (an ARG in your Dockerfile), like NODE_ENV or RUN_TESTS.Anyone who can see the project's build settings. It is recorded in the image's build history and in the project's deployment file on your server, so never put a password or token in one.
Build secretA value handed to one build step (RUN --mount=type=secret,id=npm_token), such as a token for a private package registry.Nobody. Once saved it can be replaced but never shown again.
Registry loginA username and token (or a short-lived token made from your cloud account) used to pull a private base image, such as one on gcr.io, a Google Artifact Registry, GitHub's ghcr.io, Amazon ECR or Docker Hub.Nobody. It uses a connection you already made on the Connections page.

Environment variables are different again: they are for your running app, not for the build. See Environment variables.

What your build needs, before you build

When The Deployer reads your repository it also reads your Dockerfiles. It lists what they ask for:

  • every build secret a step mounts, and whether your Dockerfile reads it;
  • every registry your images come from, including a base image chosen by an argument such as FROM ${BASE_IMAGE};
  • every build argument, whether it has a default, and whether it chooses the base image;
  • placeholders such as ${NODE_AUTH_TOKEN} in a committed .npmrc.

Each need has a state: Needed (your build cannot work without it), Set, Optional, or Unused (you set it but no Dockerfile reads it, so builds do not receive it). A needed secret, a private registry with no login, or a base-image argument with no value stops the launch before any build or cloud cost, with a message that names exactly what to add.

The scan also warns about a Dockerfile step that writes a secret into the image, for example by copying it into a file. A secret that is written into a layer is part of the image whatever the build does afterwards.

Giving a build its inputs

Open the project's Build inputs. You need the Build permission to change them, and permission to see setting names to look at them.

  • Secrets. The name is fixed by your Dockerfile (the id= of the mount). Paste the value or upload a file; it can be up to 64 KiB and at least 10 characters. After saving you see its size, a short fingerprint, a version number and who changed it, never the value. Replacing a secret needs your account password.
  • Arguments. Type a value, or choose commit or branch so the build fills it in (handy for an APP_VERSION). The page warns you if a name or value looks like a credential and offers to make it a build secret instead.
  • Registry logins. Choose a connection and the registry hosts it is for. A login is sent only to the hosts its connection belongs to, so a project cannot send your credentials to an address of its choosing. The login is made fresh for each build and removed afterwards; nothing stays logged in on the server.

Test inputs tries each registry login against its image from the project's own server, without downloading the image. A build that succeeds from cache does not prove a rotated token still works, so use it after replacing one.

Rotating a secret

Replacing a secret raises its version, and the next build starts from scratch instead of reusing cached layers that were made with the old value.

When something is missing or refused

A build that cannot get an input stops with a card that names it and links to the right row, for example:

  • Your build is missing an input: the Dockerfile asked for the secret npm_token and none is set.
  • A build input was refused: the registry or package host answered 401 or 403 to the login, or the image was not found with it.
  • Docker Hub's pull limit was reached: add a Docker Hub login (a free account's read-only token is enough).

None of these is treated as a problem in your code: The Deployer does not ask an assistant to change your Dockerfile, does not try again by itself, and does not record the failure as something to learn from.

A secret no Dockerfile uses any more

Right before each build on a server, The Deployer reads the Dockerfiles in the code it is about to build. If a secret is set but none of them mounts it, the log says so. This happens when the Dockerfile that used it was removed or renamed, or when the branch was deleted and re-created from another branch that never had it. The build then runs without the secret.

If the build then fails because a registry refused a download, the card says Your build secret npm_token isn't used by any Dockerfile any more, and does not tell you to replace the token, because the token was never used. Put the Dockerfile back (or remove the secret if you no longer need it), then push. If the build fails for another reason, its usual card shows a note about the unused secret.

What The Deployer never does with them

  • It never writes a secret into the image, a log line, an assistant's context, a blueprint, a backup or an error message, and it hides every spelling of one (encoded, split over lines) from deployment logs.
  • Assistants (the guide, the Copilot, the recovery agent, MCP) are told only the names and states, never a value, and they cannot read the folders where secrets are placed for a build.
  • A blueprint carries the names of your build secrets and the values of your build arguments, never a secret.
  • When you create another environment from this project, arguments are copied and secrets are not: the new project shows what it still needs.

Where this works

Build inputs are delivered to builds that run on a server: a virtual machine in your cloud account or your own server. Projects that deploy to a managed container service (App Runner, Cloud Run, Container Apps and similar) cannot receive them yet, and the page says so before you launch rather than failing during the build.

Related