dockman
v0.4.0
Published
Build, tag, and push images with Docker or Podman from Bun and Node.
Readme
dockman
Build, tag, and push container images from Bun or Node with Docker or Podman, and deploy with kubectl.
Install with bun add dockman. Requires Node 22+ or Bun 1.3+ and an engine CLI on PATH.
import { DockmanConnection } from 'dockman'
const connection = await DockmanConnection.create({
preference: ['docker', 'podman'],
startIfNeeded: true,
interactive: true,
})
const image = await connection.build({
context: '.',
file: 'Dockerfile',
buildArgs: { NODE_ENV: 'production' },
})
await connection.tag(image, 'ghcr.io/my-org/my-app:latest')
await connection.push('ghcr.io/my-org/my-app:latest')Connecting
DockmanConnection.create(options?) checks engines in preference order, defaulting
to Docker then Podman. Use ['podman'] or ['docker'] to restrict discovery.
An already-running engine is used before attempting to start any engine. The readonly
connection.engine identifies the selected engine; operations never fail over to a
different image store. The CLI's existing environment and context/connection settings apply.
startIfNeeded defaults to true. Automatic startup is Windows-only: Dockman starts
Docker Desktop or Podman's existing default machine and polls for readiness.
startupTimeoutMs defaults to 120,000 per engine; individual probes have a five-second
limit. Set startIfNeeded: false to require an already-running engine. On macOS/Linux,
start engines yourself. Dockman does not install engines, initialize machines, elevate
privileges, change connection defaults, or stop engines after use.
Docker launches use hidden windows as a best effort. Docker controls its dashboard; if it still opens, disable Open Docker Dashboard when Docker Desktop starts in Docker's settings. Dockman does not change saved preferences.
Images
build(options?)streams progress and returns asha256:image ID. Options:context(default.),file,tags,buildArgs,labels,target,platform(one platform), andnoCache. An automatically cleaned temporary iidfile avoids parsing progress output. Build arguments are not a safe channel for secrets.tag(image, target)assigns one local name. Repeat it for additional tags.push(reference)streams progress and uploads an explicitly tagged reference. Any registry can use existing engine credentials; automatic login supports GHCR only.
Kubernetes deployments
KubernetesConnection uses kubectl on PATH and existing kubeconfig credentials independently
of Docker or Podman. Its constructor accepts context and namespace; omitted values use
kubectl's current settings. It does not change kubeconfig or contact the cluster until a method runs.
import { KubernetesConnection, kustomizeBuild, kustomizeSetImage } from 'dockman'
const cluster = new KubernetesConnection({ context: 'production', namespace: 'my-app' })
await kustomizeSetImage('./k8s', 'ghcr.io/example/my-app:v2')
const yaml = await kustomizeBuild('./k8s')
const diff = await cluster.diff(yaml)
console.log(diff)
await cluster.apply(yaml, {
dryRun: 'server', // Use 'none' to persist changes after your application's confirmation.
serverSide: true,
fieldManager: 'kustomize',
applySet: 'my-app-deploy',
})
// After applying with dryRun: 'none':
// await cluster.rolloutRestart('deploy/deployment')
// await cluster.rolloutStatus('deploy/deployment', { timeout: '10m' })diff(manifests, options?)returns the complete diff text and accepts kubectl exit codes 0 (unchanged) and 1 (differences). Other failures reject. Options includeserverSideandfieldManagerso previews can match apply semantics. kubectl requires a diff executable on PATH orKUBECTL_EXTERNAL_DIFFconfigured.apply(manifests, options?)streams output.dryRunaccepts'none'(default),'client', or'server'.serverSideandfieldManagercontrol field ownership. SettingapplySetenables--prune --applyset=..., removing previously managed resources absent from the manifests. It setsKUBECTL_APPLYSET=trueonly for that subprocess.rolloutRestart(resource)restarts a resource specified astype/name.rolloutStatus(resource, { timeout? })streams progress until the latest rollout finishes, rejecting on failure or timeout. Durations use kubectl syntax, such as'10m'; the default waits indefinitely. A newer rollout is followed if one starts while watching.
Manifests accept strings, Uint8Array (including Node buffers), or ArrayBuffer and are
piped to stdin. Diff formatting and confirmation prompts remain in your script.
See the kubectl reference
for command behavior and prerequisites.
Kustomize utilities
These standalone utilities require kustomize on PATH and work without a cluster or container
engine connection. Both require an explicit local directory containing the kustomization.
Relative paths resolve from the current working directory; neither utility changes it.
kustomizeBuild(directory)returns the complete UTF-8 YAML string, ready fordifforapply.kustomizeSetImage(directory, image)persists an image change to the local kustomization file. It accepts native image expressions such asghcr.io/example/my-app:v2,my-app=ghcr.io/example/my-app:v2, and digest references.
Both reject on command failures with CLI diagnostics. They use the standalone executable without falling back to kubectl's bundled Kustomize.
GHCR login
On recognizable GHCR authentication failures, interactive: true (the default)
allows GitHub CLI browser authentication in a terminal. Install gh beforehand.
Dockman reuses the active account, requests write:packages when needed, logs the
selected engine into ghcr.io using secret stdin, and retries the push once.
GitHub CLI and the engine manage credential persistence through their usual stores.
Generic permission denials, missing images, and network errors do not trigger login.
With interactive: false or no terminal, authentication failures include manual
instructions. For example:
gh auth login --hostname github.com --web --scopes write:packages
# For an existing account that needs the package scope:
gh auth refresh --hostname github.com --scopes write:packages
gh auth token --hostname github.com | docker login ghcr.io --username YOUR_GITHUB_USERNAME --password-stdinReplace docker with podman when appropriate. Verify package write permissions and
organization SSO authorization. Environment-provided GH_TOKEN/GITHUB_TOKEN values
take precedence in GitHub CLI; replace or unset insufficient tokens rather than
attempting browser refresh. Configure registry credentials ahead of time in CI.
See GitHub CLI login and GHCR authentication.
