Pass API tokens at runtime instead of baking them into images
You will run MCP servers with tokens injected at container start, keeping secrets out of image layers, shell history and process listings. This lowers the chance that a leaked image or command line exposes your credentials.
- Build imageNo credentials inside the Dockerfile
- Store tokenEnv file or platform secret store
- Start containerInject with -e at runtime
- Check logsConfirm the server starts before connecting a client
Why it matters
A Docker container that connects to Claude Desktop needs its API token at startup, and the easiest shortcut is to bake it into the image or pass it inline on the command line. Brightdata's containerized server takes API_TOKEN as a runtime environment variable (the brightdata-mcp Docker thread (opens external site)), and a Fly.io deployment that used the same secret failed there without a confirmed cause. Injecting values at runtime and reading the deployment logs keeps the token out of the image and makes failures easier to trace.
Steps
- Build the image without any credentials. Keep
ENV API_TOKEN=...and any token value out of the Dockerfile, since anyone with the image can read them. - Store the token in a
.envfile kept out of version control, or in your platform's secret store. PuttingAPI_TOKENdirectly on the command line leaves it visible in shell history and process listings (the brightdata-mcp Docker thread (opens external site)). - Pass the variables when the container starts. The run command that worked for the maintainer uses
-i --rmwith-eflags, and the image is the published one from the metorial catalog:
docker run -i --rm -e API_TOKEN=<my-token> -e WEB_UNLOCKER_ZONE=unblocker ghcr.io/metorial/mcp-container--brightdata--brightdata-mcp--brightdata-mcp "node ./server.js"
- In your real setup, replace the inline value with an env file or secret reference so the token does not appear in your shell history.
- Keep the startup command quoted exactly as in the working example. The maintainer suspected the missing quotes around
node ./server.jscould matter, but did not confirm it as the cause. - If a platform deployment fails, check the machine logs first and confirm the secret is set in that environment before changing code.
- Limit each token to the permissions the server needs. A narrow token limits the damage if it leaks.
Common mistakes
- Adding
ENVlines with real values to a Dockerfile, which leaves the token in every image layer. - Pasting tokens into commands that end up in shell history or
psoutput. - Assuming a platform secret is set correctly without checking the runtime logs.
- Giving one broad token to every server instead of scoping each one.
Checklist
0 of 7 done