Skip to content

Capability gap: composite Go images (multi-binary, embedded atlas, templates, entrypoint) for Permanu BE dogfood #12

@gopherine

Description

@gopherine

Context

Permanu's own backend (Dockerfile.production in permanu/Deploy) cannot currently be expressed via Docksmith. Per Permanu's hard dogfood rule (Permanu deploys customer apps via Docksmith, so it must use Docksmith for itself), we need to delete the hand-written Dockerfile — but Docksmith today produces only a single-binary, single-stage Go image. The Permanu BE image needs:

  1. Custom build targetgo build ./cmd/server (not auto-detected entrypoint), with version ldflags injected via -X (already partially expressible via [build].command, but no first-class "ldflags" field).
  2. Pinned external binary fetchatlas migration tool (https://release.ariga.io/atlas/...) baked into the image at /app/bin/atlas. Server execs literal path; cannot rely on PATH.
  3. Cross-arch sibling binarycmd/permanu-agent cross-built for linux/amd64 + linux/arm64, copied into /app/bin/permanu-agent-linux-{amd64,arm64}. Served via HTTP for agent installs/auto-update.
  4. Asset copiesatlas.hcl, sql/, migrations/, templates/ directories must land in image with --chown.
  5. Entrypoint scriptentrypoint.sh runs atlas migrate apply (gated on env), then execs /app/main. ENTRYPOINT must point at the script, not the binary.
  6. Alpine runtime override — distroless is wrong here (entrypoint.sh + atlas need a shell + libc + ca-certs + tzdata). [runtime_config].image = \"alpine:3.21\" may cover it but distroless-by-default for Go means the user fights the tool.
  7. Custom HEALTHCHECKCMD [\"/app/main\", \"health\"] (the binary has a subcommand).
  8. Custom ENV blockDEPLOY_ENV=prod, SERVER_PORT=4290, ATLAS_CONFIG=atlas.hcl, ATLAS_ENV=prod.

Why this matters

  • Without (1)–(8), Docksmith can't replace Dockerfile.production. Either Permanu keeps a hand-written Dockerfile (dogfood violation), or Docksmith grows enough to express composite Go images.
  • This isn't unique to Permanu. Any Go service that ships sibling binaries (CLI + daemon, multi-arch agents) or bundles a migration tool hits the same wall.

Suggested shape

A [stages] array in docksmith.toml that lets users add stages between detected builder and runtime, plus first-class fields for:

  • [build].ldflags = [\"-X foo=bar\"]
  • [[runtime.copy]] blocks (src, dst, chown, from-stage)
  • [runtime.entrypoint] (script path) + [runtime.cmd]
  • [runtime.healthcheck] (custom CMD)
  • [runtime.env] (already exists as [env])

Or alternatively: emit a base Dockerfile and let users append a Dockerfile.overlay that Docksmith concatenates — keeps the simple case simple, lets composite cases extend without forking.

Blocker

Permanu PR #957 (publish BE image to ghcr.io) and PR #958 (one-shot install.sh) both need to drop Dockerfile.production to comply with the dogfood rule. They are blocked on this gap. Permanu cannot delete Dockerfile.production until Docksmith can produce an equivalent — every gap above maps to a real runtime requirement (atlas migration gate, agent binary serving, template loading).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions