# --- Builder Stage --- ARG GO_VERSION=1.23 FROM golang:${GO_VERSION}-alpine AS builder # Set necessary environment variables ENV CGO_ENABLED=0 ENV GOOS=linux ENV GOARCH=amd64 # Set the working directory inside the container WORKDIR /app # Install build dependencies (e.g., git, tools for private repos if needed) # RUN apk add --no-cache git # Copy go module files COPY go.mod go.sum ./ # Download Go modules # Using 'go mod download' allows Docker to cache these layers RUN go mod download # Copy the entire source code # Consider using .dockerignore to exclude unnecessary files/dirs (like .git, tmp, build, vendor if not needed) COPY . . # Build the Go application # Use -ldflags "-w -s" to strip debug information and reduce binary size for production # Replace './cmd/server/main.go' with your actual main package path if different RUN go build -ldflags="-w -s" -o /app/server ./cmd/server/main.go # --- Final Stage --- # Use a minimal base image like alpine or distroless # alpine is small and includes a shell, useful for debugging FROM alpine:latest AS final # OR use distroless for a more secure, minimal image (no shell, only the app and its dependencies) # FROM gcr.io/distroless/static-debian11 AS final # Install necessary certificates (needed for HTTPS connections) # For Alpine: RUN apk add --no-cache ca-certificates # For Debian-based (like distroless): Usually included, but verify # Create a non-root user and group RUN addgroup -S appgroup && adduser -S appuser -G appgroup # Set the working directory WORKDIR /app # Copy the built binary from the builder stage COPY --from=builder /app/server /app/server # Copy configuration files, migrations, or other necessary assets # Adjust paths as needed based on your application structure COPY configs/ /app/configs/ COPY migrations/ /app/migrations/ # Add other COPY lines for templates, static assets etc. if needed # Ensure the non-root user owns the application files RUN chown -R appuser:appgroup /app # Switch to the non-root user USER appuser # Expose the port the application listens on (replace 8080 if different) EXPOSE 8080 # Define the entry point for the container # CMD ["/app/server", "--config=/app/configs/config.yaml"] # Example with config flag ENTRYPOINT ["/app/server"]