Slide 73 de 74

Contêineres

Escrevendo, e rodando o que foi escrito
$ hive container main.hive
Wrote Dockerfile for main.hive (0s)
$ docker build -t main .
$ docker run --rm -p 8080:8080 main

# Um Dockerfile que já esteja lá é deixado em paz, e o nosso leva nome próprio.
$ hive container main.hive
Wrote Dockerfile-hive-container for main.hive (0s)
$ docker build -f Dockerfile-hive-container -t main .
O que ele escreve
# 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

# ... curl, then Go itself for that architecture ...

# The compiler itself — this one, rather than whatever release is newest on
# the day the image is built.
ARG HIVEC_VERSION=v0.2.10
RUN curl -fsSL \
      "https://github.com/R0DR160HM/hive-lang/releases/download/${HIVEC_VERSION}/hivec-linux-${TARGETARCH}" \
      -o /usr/local/bin/hivec \
 && chmod +x /usr/local/bin/hivec

# A static binary, so the runtime stage below needs no libc.
ENV CGO_ENABLED=0

WORKDIR /app
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 main.hive escreve um Dockerfile para o programa na pasta em que o comando foi rodado, que é também o contexto do build. Ele checa o programa antes, como o hive check faria, então um programa que não compila recebe os erros dele em vez de um build de imagem que falha dez minutos depois.

Nada precisa estar instalado para construir a imagem além do Docker:

  • O primeiro estágio baixa o Go, e o compilador que escreveu o arquivo, para a plataforma para a qual se está construindo: amd64 numa máquina comum e arm64 numa de silício Apple, então o build é nativo de qualquer jeito. O compilador fica fixado em ARG HIVEC_VERSION, então uma imagem nunca segue um lançamento mais novo sozinha, e docker build --build-arg HIVEC_VERSION=v9.9.9 . constrói com outro.
  • O segundo estágio é só o executável, sobre distroless/static: sem Go, sem compilador, nem sequer um shell — só os certificados de que uma chamada HTTPS precisa e os fusos horários.

O que não é template é lido do programa. Um hive.net.httpServe(8080, ...) vira um EXPOSE 8080, com um comentário dizendo de onde o número veio, e um programa que não serve nada não expõe nada. Um import que nomeia um repositório coloca git no estágio de build, e um programa que abre um banco de dados roda go mod tidy antes de qualquer coisa compilar. Tudo que está ao lado do Dockerfile entra no build, então um .dockerignore é o que o estreita.

O que sai é um Dockerfile comum, e editá-lo é esperado. Um Dockerfile que já esteja na pasta nunca é sobrescrito: o nosso se chama Dockerfile-hive-container em vez disso, o comando diz qual escreveu, e construir a partir dele pede docker build -f Dockerfile-hive-container .. Este tour é servido a partir de uma imagem construída assim.