# ---------- Build Stage ---------- FROM golang:1.24 AS builder WORKDIR /app COPY . . # Which commit this image is. Reported by GET /live/api/v1/health, so "I pushed # it" and "it is running" stop being the same sentence — a redeploy can reuse a # cached image, and there was no way to tell from outside. # # Passed by the platform as a build argument: # docker build --build-arg BUILD_VERSION=$(git rev-parse --short HEAD) . # In Dokploy this goes under the application's Build settings. Left unset it # reads "unknown", which is itself worth seeing — it means nothing stamped it. # # `.git` is not in the build context (see .dockerignore), so the build cannot # work this out for itself. ARG BUILD_VERSION=unknown RUN CGO_ENABLED=0 GOOS=linux go build \ -ldflags "-X nearle/controllers.Version=${BUILD_VERSION}" -o server # ---------- Runtime Stage ---------- FROM alpine:latest RUN apk add --no-cache tzdata WORKDIR /app COPY --from=builder /app/server /app COPY nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json . # The container's own configuration. # # Copied in so the deployment does not depend on every variable having been # entered into a hosting platform's settings screen. A variable missed there is # a variable unset in production, and the failure is silent — the assistant sat # switched off for two days for exactly that reason, with nothing on any screen # saying which value was absent. # # Anything the platform DOES set still wins: `godotenv` only fills variables # that are not already in the environment, so Dokploy can override any line in # this file without the file having to change. COPY .env.production . # Decides which rules config.Load applies — production insists on a signing # secret and never falls back to localhost values — and which file above is # read: loadEnvFiles reads `.env.` then `.env`. ENV APP_ENV=production # Must match APP_PORT in the platform's environment (1009 in production). EXPOSE 1009 CMD ["/app/server"]