Dockerfile
Rama main · réplica de lectura del repositorio original.
# A self-contained Kite server.
#
# The binary is compiled here rather than copied out of a release archive, so
# that `docker build .` works from any checkout and a contributor can try a
# change in a container without publishing anything first. The versions below
# are pinned for the same reason they are pinned everywhere else in this
# repository: the same commit should produce the same image next year.
# Must match the toolchain directive in go.mod.
ARG GO_VERSION=1.26.8
# Must match web/.nvmrc.
ARG NODE_VERSION=22.19.0
ARG ALPINE_VERSION=3.22
# The admin is embedded in the binary, so it has to exist before the binary is
# built. Its own stage keeps Node out of the image that ships. It is the same
# bytes for every platform, so it is built once, on the machine running the
# build: under emulation, for another platform, pnpm install can hang.
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION}-alpine AS admin
WORKDIR /src/web
# The manifest and the lockfile alone first: dependencies change far less
# often than the code does, and this layer is then reused across builds.
COPY web/package.json web/pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY web/ ./
RUN pnpm build
# Go cross-compiles, so the binary is built on that machine too, for the
# platform the image is for.
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS build
ARG TARGETOS TARGETARCH TARGETVARIANT
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
COPY --from=admin /src/web/dist ./web/dist
# Stamped rather than read from the repository, because .git is not in the
# build context: an image should know what it is without carrying history.
ARG VERSION=dev
ARG COMMIT=none
ARG DATE=unknown
# No cgo, for the same reason the released binaries have none: one
# self-contained executable, and a dependency that quietly needs a C
# toolchain fails here rather than at run time.
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH GOARM=${TARGETVARIANT#v} \
go build -trimpath -buildvcs=false \
-ldflags "-s -w \
-X github.com/kite-plus/kite/internal/buildinfo.Version=${VERSION} \
-X github.com/kite-plus/kite/internal/buildinfo.Commit=${COMMIT} \
-X github.com/kite-plus/kite/internal/buildinfo.Date=${DATE}" \
-o /out/kite ./cmd/kite
FROM alpine:${ALPINE_VERSION}
# git is not optional: publishing commits the content, and a container that
# cannot do that is a Kite with half its job missing. ca-certificates is for
# pushing over https, tzdata so that dates render in the site's own zone.
RUN apk add --no-cache ca-certificates git tzdata && \
adduser -D -u 1717 -h /data kite
COPY --from=build /out/kite /usr/local/bin/kite
COPY docker/entrypoint.sh /usr/local/bin/kite-entrypoint
# The project lives in a volume, not in the image. An image holding a site
# would have to be rebuilt to publish a post.
WORKDIR /data
VOLUME /data
USER kite
EXPOSE 1717
# The site itself, not the API: it answers whether or not the studio is
# mounted, and whether or not this server has been set up yet.
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget -q -O /dev/null http://127.0.0.1:1717/ || exit 1
ENTRYPOINT ["kite-entrypoint"]
CMD ["serve"]