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
100 lines
4.1 KiB
Docker
100 lines
4.1 KiB
Docker
# Secure Production Dockerfile with cache optimization
|
|
# Build with: DOCKER_BUILDKIT=1 docker build --build-arg WORKER_PASSWORD=$(openssl rand -base64 32) -f build/docker/secure-prod.Dockerfile .
|
|
|
|
# ============================================================================
|
|
# STAGE 1: Go Dependencies (cached layer)
|
|
# ============================================================================
|
|
FROM golang:1.25-alpine AS go-deps
|
|
|
|
RUN apk add --no-cache git make gcc musl-dev
|
|
|
|
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 2: Go Builder
|
|
# ============================================================================
|
|
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 3: Final Runtime with Podman and secure SSH
|
|
# ============================================================================
|
|
FROM alpine:3.19
|
|
|
|
# Build argument for worker password (no hardcoded secrets)
|
|
ARG WORKER_PASSWORD=changeme
|
|
ENV WORKER_PASSWORD=$WORKER_PASSWORD
|
|
|
|
# Create app user and worker user, configure SSH in combined layer
|
|
RUN addgroup -g 1001 -S appgroup && \
|
|
adduser -u 1001 -S appuser -G appgroup && \
|
|
addgroup -g 1002 -S workergroup && \
|
|
adduser -u 1002 -S worker -G workergroup -s /bin/sh && \
|
|
echo "worker:$WORKER_PASSWORD" | chpasswd && \
|
|
mkdir -p /home/worker/.ssh && \
|
|
chown -R worker:workergroup /home/worker && \
|
|
\
|
|
# Generate SSH keys for worker user
|
|
ssh-keygen -t rsa -b 4096 -f /home/worker/.ssh/id_rsa -N "" && \
|
|
cp /home/worker/.ssh/id_rsa.pub /home/worker/.ssh/authorized_keys && \
|
|
chmod 700 /home/worker/.ssh && \
|
|
chmod 600 /home/worker/.ssh/id_rsa && \
|
|
chmod 644 /home/worker/.ssh/id_rsa.pub /home/worker/.ssh/authorized_keys && \
|
|
chown -R worker:workergroup /home/worker/.ssh && \
|
|
\
|
|
# Configure SSH daemon securely
|
|
echo "Port 2222" >> /etc/ssh/sshd_config && \
|
|
echo "PermitRootLogin no" >> /etc/ssh/sshd_config && \
|
|
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config && \
|
|
echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config && \
|
|
echo "AuthorizedKeysFile %h/.ssh/authorized_keys" >> /etc/ssh/sshd_config && \
|
|
echo "AllowUsers worker" >> /etc/ssh/sshd_config && \
|
|
echo "MaxAuthTries 3" >> /etc/ssh/sshd_config && \
|
|
echo "ClientAliveInterval 300" >> /etc/ssh/sshd_config && \
|
|
echo "ClientAliveCountMax 2" >> /etc/ssh/sshd_config && \
|
|
echo "X11Forwarding no" >> /etc/ssh/sshd_config && \
|
|
echo "AllowTcpForwarding no" >> /etc/ssh/sshd_config && \
|
|
echo "Banner /etc/ssh/banner" >> /etc/ssh/sshd_config && \
|
|
\
|
|
# Create SSH banner
|
|
echo "=================================================" > /etc/ssh/banner && \
|
|
echo " ML Experiments Production Server" >> /etc/ssh/banner && \
|
|
echo " Unauthorized access is prohibited" >> /etc/ssh/banner && \
|
|
echo "=================================================" >> /etc/ssh/banner && \
|
|
\
|
|
# Generate SSH host keys
|
|
ssh-keygen -A && \
|
|
\
|
|
# Give appuser sudo permissions for SSH and worker user for Podman
|
|
echo "appuser ALL=(ALL) NOPASSWD: /usr/sbin/sshd" >> /etc/sudoers && \
|
|
echo "worker ALL=(ALL) NOPASSWD: /usr/bin/podman" >> /etc/sudoers
|
|
|
|
# Switch to app user for application
|
|
USER appuser
|
|
|
|
# Expose ports
|
|
EXPOSE 9101 2222
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
|
CMD curl -k -f https://localhost:9101/health || exit 1
|
|
|
|
# Default command for API server
|
|
CMD ["/usr/local/bin/api-server", "-config", "/app/configs/api/prod.yaml"]
|