# Stage 1: Build frontend FROM node:20-alpine AS frontend-builder WORKDIR /build/web COPY web/package.json web/package-lock.json* ./ RUN npm ci --no-audit COPY web/ ./ RUN npm run build # Stage 2: Build Go binary FROM golang:1.24-alpine AS backend-builder RUN apk add --no-cache git ca-certificates WORKDIR /build COPY go.mod go.sum ./ ENV GOTOOLCHAIN=auto RUN go mod download COPY . . # Copy built frontend into the expected embed location. COPY --from=frontend-builder /build/web/build ./web/build RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /docker-watcher ./cmd/server # Stage 3: Minimal runtime image FROM alpine:3.19 RUN apk add --no-cache ca-certificates tzdata # Create non-root user. RUN addgroup -g 1000 -S app && adduser -u 1000 -S app -G app WORKDIR /app COPY --from=backend-builder /docker-watcher /app/docker-watcher # Data directory for SQLite database. RUN mkdir -p /app/data && chown -R app:app /app USER app EXPOSE 8080 ENV DATA_DIR=/app/data ENV LISTEN_ADDR=:8080 ENTRYPOINT ["/app/docker-watcher"]