Skip to content

Setup

Register the provider in your stack:

alchemy.run.ts
import * as Docker from "alchemy/Docker";
providers: Docker.providers(),
state: Alchemy.localState(),

That’s the whole registration. When Docker runs alongside a cloud provider, merge the layers: providers: Layer.merge(Cloudflare.providers(), Docker.providers()).

A Docker daemon reachable from the docker CLI is the only requirement. The provider shells out through the active Docker CLI context, so whatever docker ps talks to — Docker Desktop, a remote Docker host, an SSH context, a CI runner’s daemon — is what alchemy provisions against. There is no alchemy login step and no stored token: this provider has no credentials of its own.

Terminal window
DOCKER_BIN=/opt/homebrew/bin/docker bun alchemy deploy

The provider resolves the Docker binary from the DOCKER_BIN environment variable, falling back to docker on the PATH.

Registry auth is a per-resource prop, not global configuration. Image and RemoteImage accept a registry with { server, username, password }, where password is a Redacted value:

const image = yield* Docker.Image("app", {
name: "my-app",
build: { context: "./app" },
registry: {
server: "ghcr.io",
username: "octocat",
password: Config.redacted("GITHUB_TOKEN"),
},
});

Push deliberately skips docker login: the credentials are written into an isolated DOCKER_CONFIG that only the push command reads, so your global docker config, buildx builders, and docker context setup stay intact.