# Multi-stage build for GitCitadel Online # Stage 1: Build Go application FROM golang:1.22-alpine AS go-builder # Install build dependencies RUN apk add --no-cache git make 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 go build -a -installsuffix cgo -o gitcitadel-online ./cmd/server/main.go # Stage 2: Build and install gc-parser from local directory # We copy the local gc-parser directory, build it, and install it to avoid git repository access issues FROM node:18-alpine AS node-setup WORKDIR /app # Copy package.json and the local gc-parser directory COPY package.json package-lock.json* ./ COPY gc-parser ./gc-parser # Build gc-parser (install dependencies and compile TypeScript) WORKDIR /app/gc-parser RUN npm install && npm run build # Go back to /app and install gc-parser from local directory # This will install gc-parser and @asciidoctor/core (as a dependency of gc-parser) WORKDIR /app RUN npm install ./gc-parser # Verify gc-parser is installed and can be required RUN node -e "require('gc-parser'); console.log('✓ gc-parser installed and verified')" || \ (echo "Error: gc-parser verification failed" && exit 1) # Ensure gc-parser is a directory, not a symlink (for proper copying to final stage) RUN if [ -L node_modules/gc-parser ]; then \ echo "Warning: gc-parser is a symlink, copying as directory..."; \ rm node_modules/gc-parser; \ cp -r gc-parser node_modules/gc-parser; \ fi # Stage 3: Final runtime image FROM alpine:latest # Install runtime dependencies RUN apk add --no-cache \ ca-certificates \ wget \ nodejs \ npm \ git \ && rm -rf /var/cache/apk/* WORKDIR /app # Copy Node.js dependencies from node-setup stage COPY --from=node-setup /app/node_modules ./node_modules # Copy built Go binary from go-builder stage COPY --from=go-builder /build/gitcitadel-online . # Copy necessary files COPY scripts ./scripts COPY static ./static COPY templates ./templates COPY docker-entrypoint.sh ./ # Make entrypoint executable RUN chmod +x docker-entrypoint.sh # Create cache directory RUN mkdir -p cache/media && chmod 755 cache # Expose port 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 # Use entrypoint script ENTRYPOINT ["./docker-entrypoint.sh"] # Run the application CMD ["./gitcitadel-online"]