# Written and tested using podman version 5.2.5 # See 'man 5 containerfile' for more info # Alternatively, https://docs.docker.com/reference/dockerfile/#overview # Builds the server in an isolated stage FROM docker.io/golang:alpine as go # Get some common dependencies # NOTE: that 'gcompat' might be required in the runner stage image # as well for glibc compatibility (sqlite3 is a notable example) RUN apk add gcompat RUN apk add gcc RUN apk add musl-dev RUN apk add sqlite # Set working directory WORKDIR /build # go.mod, go.sum e.t.c. are copied first to leverage caching ADD go.* . # Get the dependencies RUN go mod download # Add the source code, where . is relative to the container build # context (usually defined directly in the build command) ADD . . RUN CGO_ENABLED=1 GOOS=linux go build -a -installsuffix cgo -o ./server ./*.go # Strip the binary for a smaller image, optional RUN strip ./server # The final stage for building a minimal image FROM docker.io/alpine:latest as runner # Add a non-root user and group to facilitate dropping # privileges inside the container RUN adduser -D nonroot RUN addgroup nonroot nonroot # Set working directory and make user 'nonroot' the owner WORKDIR /app RUN chown nonroot:nonroot /app # Copy the server binary COPY --from=go /build/server server # Expose port 8080 # NOTE: Reserved ports (0-1023) require root privileges EXPOSE 8080 # Drop privileges USER nonroot:nonroot ENV CONTAINER true # Run the server CMD ["./server"]