Files
LokiStack/Dockerfile
T
logan 2d73661dd1 feat: complete Loki query, insights, settings and deployment workflows
Add the Loki query UI, access policies, ingress insights, alert and registry settings, and their backend APIs. Include the related Kubernetes deployment and collector updates required by the integrated application.

Validated with go test ./..., npm run build, and npm run lint.
2026-10-25 21:28:32 +08:00

125 lines
4.4 KiB
Docker

# ============================================================
# opsx-loki - Secure Multi-Stage Dockerfile
# ============================================================
# P0 Fixes:
# - Non-root user (opsxloki:1000)
# - No hardcoded JWT_SECRET (validated at runtime)
# - HEALTHCHECK instruction added
# - Binary installation verification
# P1 Fixes:
# - Supply chain risk reduction (--ignore-scripts where applicable)
# - File ownership with --chown
# - Security environment variables
# ============================================================
# ---------------------------------------------------------------
# Stage 1: Frontend Builder (Node.js)
# ---------------------------------------------------------------
FROM node:20-alpine AS frontend-builder
WORKDIR /app/frontend
# Install dependencies separately to leverage layer caching
COPY frontend/package*.json ./
# Use --ignore-scripts to reduce supply chain attack surface
RUN npm ci --ignore-scripts && \
npm cache clean --force
# Copy source and build
COPY frontend/ ./
RUN npm run build
# ---------------------------------------------------------------
# Stage 2: Backend Builder (Go)
# ---------------------------------------------------------------
FROM golang:1.24-alpine AS backend-builder
RUN apk add --no-cache git ca-certificates tzdata
ENV GOTOOLCHAIN=local
WORKDIR /app/backend
# Download dependencies (cached layer)
COPY backend/go.* ./
RUN go mod download
# Copy source and build static binary
COPY backend/ ./
RUN CGO_ENABLED=0 GOOS=linux go build \
-a -installsuffix cgo \
-ldflags="-s -w -extldflags '-static'" \
-o bin/opsxloki .
# ---------------------------------------------------------------
# Stage 3: Final Runtime Image
# ---------------------------------------------------------------
FROM alpine:3.20
# Install runtime dependencies:
# ca-certificates: HTTPS TLS verification
# openssh-client: SSH key auth for host deployment
# bash: Entrypoint script support
# wget: HEALTHCHECK (lighter than curl)
RUN apk --no-cache add \
ca-certificates \
openssh-client \
bash \
wget
# ---------------------------------------------------------------
# P0: Create non-root user and group
# ---------------------------------------------------------------
RUN addgroup -g 1000 opsxloki && \
adduser -u 1000 -G opsxloki -s /bin/sh -D opsxloki
# ---------------------------------------------------------------
# Working directory with proper ownership
# ---------------------------------------------------------------
WORKDIR /app
RUN chown opsxloki:opsxloki /app
# ---- Copy application files with correct ownership (P1) ----
COPY --from=frontend-builder --chown=opsxloki:opsxloki /app/frontend/dist ./dist
COPY --from=backend-builder --chown=opsxloki:opsxloki /app/backend/bin/opsxloki ./opsxloki
# Create data directory with non-root ownership
RUN mkdir -p /app/data && chown -R opsxloki:opsxloki /app/data
# Create .kube directory for non-root user (P0: not /root/.kube)
RUN mkdir -p /home/opsxloki/.kube && \
chown -R opsxloki:opsxloki /home/opsxloki && \
chmod 700 /home/opsxloki/.kube
# ---- Security hardening: remove unnecessary tools ----
RUN rm -rf /tmp/* /var/cache/apk/*
# ---------------------------------------------------------------
# Security environment variables
# ---------------------------------------------------------------
ENV DATA_DIR=/app/data
ENV SERVER_PORT=8080
ENV KUBECONFIG=/home/opsxloki/.kube/config
ENV HOME=/home/opsxloki
# NOTE: JWT_SECRET and ENCRYPTION_KEY are NOT set here.
# They MUST be provided at runtime via docker-compose env or secrets.
# The entrypoint script will enforce this requirement.
# ---- Copy and configure entrypoint script ----
COPY --chown=opsxloki:opsxloki docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE 8080
# ---------------------------------------------------------------
# P0: HEALTHCHECK - verifies static file serving (no auth needed)
# ---------------------------------------------------------------
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD wget --no-verbose --tries=1 --spider \
http://localhost:${SERVER_PORT}/index.html || exit 1
# ---------------------------------------------------------------
# P0: Switch to non-root user
# ---------------------------------------------------------------
USER opsxloki
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["./opsxloki"]