starter-kit/Dockerfile

103 lines
2.4 KiB
Docker

# syntax=docker/dockerfile:1.4
# Production-ready multi-stage build for server deployment
# Build arguments
ARG GO_VERSION=1.23.6
ARG ALPINE_VERSION=3.19
ARG APP_USER=appuser
ARG APP_GROUP=appgroup
# --- Builder Stage ---
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
# Install build dependencies
RUN apk add --no-cache git make gcc libc-dev
# Set working directory
WORKDIR /build
# Enable Go modules
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64
# Copy dependency files first for better layer caching
COPY go.mod go.sum ./
# Download dependencies
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
# Copy source code
COPY . .
# Create the configs directory in the build context
RUN mkdir -p /build/configs && \
cp -r configs/* /build/configs/ 2>/dev/null || :
# Build the application with optimizations
RUN --mount=type=cache,target=/root/.cache/go-build \
go build -ldflags="-w -s -X 'main.Version=$(git describe --tags --always 2>/dev/null || echo 'dev')'" \
-o /build/bin/app ./cmd/app
# --- Final Stage ---
FROM alpine:${ALPINE_VERSION}
# Re-declare ARG to use in this stage
ARG APP_USER=appuser
ARG APP_GROUP=appgroup
ARG APP_HOME=/app
# Set environment variables
ENV TZ=Asia/Ho_Chi_Minh \
APP_USER=${APP_USER} \
APP_GROUP=${APP_GROUP} \
APP_HOME=${APP_HOME}
# Install runtime dependencies
RUN apk add --no-cache \
ca-certificates \
tzdata \
tini \
&& rm -rf /var/cache/apk/*
# Create app user and group
RUN addgroup -S ${APP_GROUP} && \
adduser -S -G ${APP_GROUP} -h ${APP_HOME} -D ${APP_USER}
# Create necessary directories
RUN mkdir -p ${APP_HOME}/configs ${APP_HOME}/logs ${APP_HOME}/storage
# Switch to app directory
WORKDIR ${APP_HOME}
# Copy binary and configs from builder
COPY --from=builder --chown=${APP_USER}:${APP_GROUP} /build/bin/app .
COPY --from=builder --chown=${APP_USER}:${APP_GROUP} /build/configs ./configs/
# Set file permissions
RUN chmod +x ./app && \
chown -R ${APP_USER}:${APP_GROUP} ${APP_HOME}
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
# Switch to non-root user
USER ${APP_USER}
# Default command
CMD ["./app"]
# Expose port
EXPOSE 3000
# Set environment variable for production
ENV APP_ENV=production
# Command to run the application
ENTRYPOINT ["/sbin/tini", "--"]