You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

85 lines
2.7 KiB

# Multi-stage build for GitCitadel Online
# Using Alpine Linux for smaller image size (~50MB vs ~200MB+ for Debian)
# Alpine works well here because:
# - Go binary is statically compiled (CGO_ENABLED=0)
# - Node.js packages are pure JavaScript (no native bindings)
# - No C library dependencies required
# Stage 1: Build Go application
FROM golang:1.22-alpine AS builder
# Install build dependencies
RUN apk add --no-cache git
# Set working directory
WORKDIR /build
# Copy go mod files
COPY go.mod go.sum ./
RUN go mod download
# Copy source code
COPY . .
# Build the application
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-w -s' -o gitcitadel-online ./cmd/server
# Stage 2: Runtime with Node.js for AsciiDoc processing
FROM node:20-alpine
# Install runtime dependencies (wget for health check and nostr-tools download)
RUN apk add --no-cache ca-certificates tzdata wget
# Set working directory
WORKDIR /app
# Install Node.js dependencies for AsciiDoc processing
# Note: gc-parser is referenced from ../gc-parser in package.json
# Before building, ensure gc-parser is built: cd ../gc-parser && npm install && npm run build
# Then npm install here will link to the built gc-parser
COPY package.json package-lock.json ./
RUN npm ci --only=production
# Copy gc-parser wrapper script
COPY scripts/ ./scripts/
RUN chmod +x ./scripts/process-content.js
# Copy built binary from builder
COPY --from=builder /build/gitcitadel-online /app/gitcitadel-online
# Copy static files and templates
COPY static/ ./static/
COPY templates/ ./templates/
# Download nostr-tools bundle if not present (for contact form)
RUN if [ ! -f ./static/js/nostr.bundle.js ]; then \
mkdir -p ./static/js && \
wget -O ./static/js/nostr.bundle.js https://unpkg.com/nostr-tools@latest/lib/nostr.bundle.js || \
echo "Warning: Failed to download nostr-tools bundle"; \
fi
# Copy example config (user should mount their own config.yaml)
COPY config.yaml.example ./config.yaml.example
# Copy entrypoint script
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
# Create non-root user for security
# node:20-alpine already has a 'node' user with UID 1000
# Change ownership of /app to node user
RUN chown -R node:node /app && \
chmod +x /app/docker-entrypoint.sh
# Switch to non-root user
USER node
# Expose port (default 8080, can be overridden via config)
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# Run the application via entrypoint script
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["/app/gitcitadel-online", "--config", "/app/config.yaml"]