fetch_ml/build/docker/simple.Dockerfile
Jeremie Fraeys cb142213fa
chore(build): update build system, Dockerfiles, and dependencies
Build and deployment improvements:

Makefile:
- Native library build targets with ASan support
- Cross-platform compilation helpers
- Performance benchmark targets
- Security scan integration

Docker:
- secure-prod.Dockerfile: Hardened production image (non-root, minimal surface)
- simple.Dockerfile: Lightweight development image

Scripts:
- build/: Go and native library build scripts, cross-platform builds
- ci/: checks.sh, test.sh, verify-paths.sh for validation
- benchmarks/: Local performance testing and regression tracking
- dev/: Monitoring setup

Dependencies: Update to latest stable with security patches

Commands:
- api-server/main.go: Server initialization updates
- data_manager/data_sync.go: Data sync with visibility
- errors/main.go: Error handling improvements
- tui/: TUI improvements for group management
2026-03-08 13:03:48 -04:00

88 lines
3.3 KiB
Docker

# Cache-Optimized Dockerfile for homelab use
# Build with: docker build --build-context native=./native -f build/docker/simple.Dockerfile .
# ============================================================================
# STAGE 1: Native C++ Builder (separate cache layer)
# ============================================================================
FROM alpine:3.19 AS native-builder
RUN apk add --no-cache gcc g++ cmake make musl-dev linux-headers
WORKDIR /build
COPY native/ ./
ENV FETCHML_DOCKER_BUILD=1
RUN mkdir -p build && cd build && \
cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_NVML_GPU=OFF && \
make -j$(nproc)
# ============================================================================
# STAGE 2: Go Dependencies (cached layer - only changes when go.mod/sum changes)
# ============================================================================
FROM golang:1.25-alpine AS go-deps
RUN apk add --no-cache git make gcc g++ musl-dev cmake
WORKDIR /app
# Copy only module files first for maximum cache efficiency
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download && \
go mod verify
# ============================================================================
# STAGE 3: Go Builder (source changes don't invalidate deps)
# ============================================================================
FROM go-deps AS go-builder
# Copy source code (changes here won't rebuild deps layer)
COPY cmd/ ./cmd/
COPY internal/ ./internal/
COPY pkg/ ./pkg/
COPY tools/ ./tools/
# Build Go binaries with cache mount for build cache
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=1 go build -ldflags="-w -s" -o bin/api-server ./cmd/api-server/main.go && \
CGO_ENABLED=1 go build -ldflags="-w -s" -o bin/worker ./cmd/worker
# ============================================================================
# STAGE 4: Final Runtime (minimal layers)
# ============================================================================
FROM alpine:3.19
# Install runtime deps in single layer with cache mount
RUN --mount=type=cache,target=/var/cache/apk \
apk add --no-cache bash ca-certificates redis openssl curl podman fuse-overlayfs slirp4netns iptables libstdc++
# Create app user
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
WORKDIR /app
# Copy binaries (separate layer for quick updates)
COPY --from=go-builder /app/bin/api-server /usr/local/bin/
COPY --from=go-builder /app/bin/worker /usr/local/bin/
# Copy configs (changes often - keep near end)
COPY configs/ /app/configs/
# Setup directories and SSL in single layer
RUN mkdir -p /app/data/experiments /app/data/datasets /app/data/snapshots /app/logs /app/ssl && \
openssl req -x509 -newkey rsa:2048 -keyout /app/ssl/key.pem -out /app/ssl/cert.pem -days 365 -nodes \
-subj "/C=US/ST=Homelab/L=Local/O=ML/OU=Experiments/CN=localhost" && \
chmod 644 /app/ssl/cert.pem && \
chmod 600 /app/ssl/key.pem && \
chown -R appuser:appgroup /app/data /app/logs /app/ssl /app/configs
USER appuser
EXPOSE 9101
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD curl -f http://localhost:9101/health || curl -k -f https://localhost:9101/health || exit 1
CMD ["/usr/local/bin/api-server", "-config", "/app/configs/api/dev.yaml"]