107 lines
3.6 KiB
Docker
107 lines
3.6 KiB
Docker
# --- UI Build Stage: Build the React + Vite frontend ---
|
|
FROM node:25-alpine3.23@sha256:cf38e1f3c28ac9d81cdc0c51d8220320b3b618780e44ef96a39f76f7dbfef023 AS ui-builder
|
|
WORKDIR /app
|
|
ENV CI=1
|
|
ENV NODE_OPTIONS=--max-old-space-size=4096
|
|
|
|
# Copy UI package files and install dependencies
|
|
COPY ui/package*.json ./
|
|
RUN npm ci
|
|
|
|
# Copy UI source code
|
|
COPY ui/ ./
|
|
|
|
# Build UI (skip the copy-build step)
|
|
RUN npm run build-enterprise -- --debug
|
|
# Skip the copy-build step since we'll copy the files in the Go build stage
|
|
|
|
# --- Go Build Stage: Compile the Go binary ---
|
|
FROM golang:1.26.2-alpine3.23@sha256:f85330846cde1e57ca9ec309382da3b8e6ae3ab943d2739500e08c86393a21b1 AS builder
|
|
WORKDIR /app
|
|
|
|
# Install dependencies including gcc for CGO and sqlite
|
|
RUN apk add --no-cache gcc musl-dev sqlite-dev binutils binutils-gold
|
|
|
|
# Set environment for CGO-enabled build (required for go-sqlite3)
|
|
ENV CGO_ENABLED=1 GOOS=linux
|
|
|
|
COPY transports/go.mod transports/go.sum ./
|
|
RUN ls
|
|
RUN cat go.mod
|
|
RUN go mod download
|
|
|
|
# Copy source code and dependencies
|
|
COPY transports/ ./
|
|
|
|
COPY --from=ui-builder /app/out ./bifrost-http/ui
|
|
|
|
# Build the binary with CGO enabled and static SQLite linking
|
|
ENV GOWORK=off
|
|
ARG VERSION=unknown
|
|
RUN go build \
|
|
-ldflags="-w -s -X main.Version=v${VERSION} -extldflags '-static'" \
|
|
-a -trimpath \
|
|
-tags "sqlite_static" \
|
|
-o /app/main \
|
|
./bifrost-http
|
|
|
|
# Verify build succeeded
|
|
RUN test -f /app/main || (echo "Build failed" && exit 1)
|
|
|
|
# --- Runtime Stage: Minimal runtime image ---
|
|
FROM alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659
|
|
WORKDIR /app
|
|
|
|
# Install runtime dependencies for CGO-enabled binary
|
|
# musl: C standard library (required for CGO binaries)
|
|
# libgcc: GCC runtime library
|
|
# ca-certificates: For HTTPS connections
|
|
RUN apk add --no-cache musl libgcc ca-certificates wget zlib=1.3.2-r0
|
|
|
|
# Create data directory and set up user
|
|
COPY --from=builder /app/main .
|
|
COPY --from=builder /app/docker-entrypoint.sh .
|
|
|
|
# Getting arguments
|
|
ARG ARG_APP_PORT=8080
|
|
ARG ARG_APP_HOST=0.0.0.0
|
|
ARG ARG_LOG_LEVEL=info
|
|
ARG ARG_LOG_STYLE=json
|
|
ARG ARG_APP_DIR=/app/data
|
|
|
|
# Environment variables with defaults (can be overridden at runtime)
|
|
ENV APP_PORT=$ARG_APP_PORT \
|
|
APP_HOST=$ARG_APP_HOST \
|
|
LOG_LEVEL=$ARG_LOG_LEVEL \
|
|
LOG_STYLE=$ARG_LOG_STYLE \
|
|
APP_DIR=$ARG_APP_DIR
|
|
|
|
# Go runtime performance tuning (override at runtime for your workload)
|
|
# GOGC: GC target percentage. Higher = less frequent GC, more memory usage.
|
|
# Default: 100. For high-throughput with available memory, try 200-400.
|
|
# GOMEMLIMIT: Soft memory limit for Go runtime. Set to ~90% of container memory limit.
|
|
# Example: "1800MiB" for a 2GB container, "3600MiB" for 4GB.
|
|
# When set, Go will be more aggressive about GC as it approaches this limit.
|
|
# Note: GOMAXPROCS is automatically detected from cgroup CPU limits via automaxprocs.
|
|
ENV GOGC="" \
|
|
GOMEMLIMIT=""
|
|
|
|
|
|
RUN mkdir -p $APP_DIR/logs && \
|
|
adduser -D -s /bin/sh appuser && \
|
|
chown -R appuser:appuser /app && \
|
|
chmod +x /app/docker-entrypoint.sh
|
|
USER appuser
|
|
|
|
|
|
# Declare volume for data persistence
|
|
VOLUME ["/app/data"]
|
|
EXPOSE $APP_PORT
|
|
|
|
# Health check for container status monitoring
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
CMD wget --no-verbose --tries=1 -O /dev/null http://127.0.0.1:${APP_PORT}/health || exit 1
|
|
|
|
# Use entrypoint script that handles volume permissions and argument processing
|
|
ENTRYPOINT ["/app/docker-entrypoint.sh"]
|
|
CMD ["/app/main"] |