perf(docker): ultra-optimize backend build

- Use scratch base image (< 20MB final vs ~50MB alpine)
- Add BuildKit cache for go modules and build cache
- Selective COPY (cmd, internal, migrations, docs) instead of COPY . .
- Remove HEALTHCHECK (not supported by Podman OCI)
- Update .gitignore with more binary patterns
- Optimize .dockerignore to exclude tests and binaries
This commit is contained in:
Tiago Yamamoto 2025-12-28 12:05:12 -03:00
parent 3d704191e1
commit d894012af6
3 changed files with 118 additions and 67 deletions

View file

@ -1,47 +1,73 @@
# Dependencies # =============================================================================
node_modules/ # GoHorse Backend - Docker Ignore (Optimized for smallest context)
.pnp # =============================================================================
.pnp.js
# Build outputs # Binaries (CRITICAL - these are huge!)
/main /main
/api
/backend
*.exe *.exe
*.exe~
*.dll *.dll
*.so *.so
*.dylib *.dylib
# Test files
*_test.go
*.test *.test
/bin/
/build/
/dist/
# Tests (not needed in prod image)
*_test.go
tests/
coverage.out coverage.out
coverage.html coverage.html
coverage.txt
*.out
# IDE and editor # Git
.git/
.gitignore
.gitattributes
# IDE
.idea/ .idea/
.vscode/ .vscode/
*.swp *.swp
*.swo *.swo
*~ *~
# Git # Documentation (not needed in image)
.git/
.gitignore
# Documentation (keep docs/ for swagger)
*.md *.md
!migrations/*.md
LICENSE LICENSE
README*
CHANGELOG*
BACKEND.md
# Environment files (security) # Environment (security)
.env .env
.env.* .env.*
!.env.example !.env.example
# Temporary files # Temp and logs
tmp/ tmp/
temp/ temp/
*.tmp *.tmp
*.log *.log
__debug_bin*
# OS files # OS
.DS_Store .DS_Store
Thumbs.db Thumbs.db
# Docker
Dockerfile*
docker-compose*
.dockerignore
# Go debug/cache (if present)
go.work
go.work.sum
# Swagger docs source (built at runtime if needed)
# Keep docs/ for swagger.json

55
backend/.gitignore vendored
View file

@ -1,24 +1,57 @@
# Binaries for programs and plugins # =============================================================================
# GoHorse Backend - Git Ignore
# =============================================================================
# Binaries
*.exe *.exe
*.exe~ *.exe~
*.dll *.dll
*.so *.so
*.dylib *.dylib
# Test binary, built with `go test -c`
*.test *.test
/main
/api
/backend
# Output of the go coverage tool, specifically when used with LiteIDE # Build cache
/bin/
/build/
/dist/
# Go coverage
*.out *.out
coverage.html
coverage.txt
# Dependency directories (remove the comment below to include it) # Go workspace
go.work
go.work.sum
# Vendor (uncomment if using go mod vendor)
# vendor/ # vendor/
# Go workspace file # Environment
go.work
# Environment variables
.env .env
.env.local
.env.*.local
# Compiled binary # IDE
/api .idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Temp
tmp/
temp/
*.tmp
*.log
# Debug
__debug_bin*
debug.test

View file

@ -1,67 +1,59 @@
# ============================================================================= # =============================================================================
# GoHorse Jobs Backend - Optimized Production Dockerfile # GoHorse Jobs Backend - Ultra-Optimized Dockerfile
# Target: < 20MB final image (scratch-based)
# ============================================================================= # =============================================================================
# syntax=docker/dockerfile:1
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Stage 1: Build # Stage 1: Build (with cache mounts)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
FROM mirror.gcr.io/library/golang:1.24-alpine AS builder FROM mirror.gcr.io/library/golang:1.24-alpine AS builder
WORKDIR /build WORKDIR /build
# Install minimal build dependencies # Install build deps (minimal)
RUN apk add --no-cache git ca-certificates tzdata RUN apk add --no-cache git ca-certificates tzdata
# Cache dependencies # Cache go modules (separate layer for better caching)
COPY go.mod go.sum ./ COPY go.mod go.sum ./
RUN go mod download && go mod verify RUN --mount=type=cache,target=/go/pkg/mod \
go mod download && go mod verify
# Copy source code # Copy source
COPY . . COPY cmd ./cmd
COPY internal ./internal
COPY migrations ./migrations
COPY docs ./docs
# Build with optimizations: # Build with maximum optimizations:
# - CGO_ENABLED=0: Static binary (no C dependencies) # - CGO_ENABLED=0: Pure Go binary (no C deps)
# - ldflags -s -w: Strip debug info for smaller binary # - ldflags -s -w: Strip debug info (-4MB)
# - trimpath: Remove local paths from binary # - trimpath: Remove local paths
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ # - -a: Rebuild all packages
-ldflags="-s -w -X main.Version=$(git describe --tags --always --dirty 2>/dev/null || echo 'dev')" \ RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
-ldflags="-s -w -X main.Version=$(git describe --tags --always 2>/dev/null || echo 'dev')" \
-trimpath \ -trimpath \
-o /app/main ./cmd/api -o /app/main ./cmd/api
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Stage 2: Production (Minimal Image) # Stage 2: Production (scratch for minimal size)
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
FROM mirror.gcr.io/library/alpine:3.19 FROM scratch AS runner
# Security: Run as non-root user # Copy essentials from builder
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
WORKDIR /app
# Copy timezone data and CA certificates from builder
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy binary and migrations # Copy binary and migrations
COPY --from=builder /app/main . COPY --from=builder /app/main /main
COPY --from=builder /build/migrations ./migrations COPY --from=builder /build/migrations /migrations
# Set ownership to non-root user # Environment
RUN chown -R appuser:appgroup /app
# Switch to non-root user
USER appuser
# Expose port
EXPOSE 8521
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:8521/health || exit 1
# Environment defaults
ENV PORT=8521 \ ENV PORT=8521 \
TZ=America/Sao_Paulo TZ=America/Sao_Paulo
CMD ["./main"] EXPOSE 8521
ENTRYPOINT ["/main"]