Slide 52 of 53

Containers

Writing it, and running what it wrote
$ hive container main.hive
Wrote Dockerfile for main.hive (0s)
$ docker build -t main .
$ docker run --rm -p 8080:8080 main
What it writes
# syntax=docker/dockerfile:1
#
# Builds and runs main.hive, from nothing but this folder.
#
#   docker build -t main .
#   docker run --rm -p 8080:8080 main

##############################################################################
# Stage 1 — download Go and the compiler, then build
##############################################################################
FROM debian:bookworm-slim AS builder

# What Docker is building for: amd64 on an ordinary machine, arm64 on an
# Apple-silicon one or a Graviton.
ARG TARGETARCH

# ... Go itself, then the compiler's latest release for that architecture ...

WORKDIR /app

# The whole folder, because a program is its entrypoint and whatever that
# imported. A .dockerignore is what narrows this.
COPY . .

RUN hivec build /app/main.hive \
 && test -x /app/main

##############################################################################
# Stage 2 — runtime
##############################################################################
FROM gcr.io/distroless/static-debian12 AS runtime
WORKDIR /app
COPY --from=builder /app/main /usr/local/bin/main

# 8080 is where this program serves: hive.net.httpServe(8080, ...) says so.
EXPOSE 8080

ENTRYPOINT ["/usr/local/bin/main"]
`hive container entrypoint.hive` writes a Dockerfile for the program, into the folder the command was run in — which is also the build's context. Nothing has to be installed to build the image but Docker itself: the first stage downloads Go and the compiler's latest release for the platform being built for — amd64 on an ordinary machine, arm64 on an Apple-silicon one, so the build is native either way — and compiles the program with the two of them. The second stage is the executable and nothing else, on distroless/static: no Go, no compiler, not even a shell.The parts of the file that are not a template are read off the program rather than guessed at. A hive.net.httpServe(8080, ...) becomes an EXPOSE 8080 that says in a comment where the number came from; an import that names a repository puts git in the build stage, since the compiler clones it while the image builds; a program that opens a database says why go mod tidy runs before anything compiles. Everything beside the Dockerfile goes into the build, so a .dockerignore is what narrows that.What comes out is an ordinary Dockerfile, and editing it is expected. A Dockerfile already in the folder is never written over — ours is called Dockerfile-hive-container instead, and the command says which of the two it wrote. This tour is served out of an image built exactly this way.