Ctrl K
ComunidadGuías…

docker/Dockerfile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Multi-stage Dockerfile for ActaLog
# Builds both frontend and backend in a single optimized image

# ============================================================================
# Stage 1: Build Frontend (Vue.js)
# ============================================================================
FROM node:24-alpine@sha256:a0b9bf06e4e6193cf7a0f58816cc935ff8c2a908f81e6f1a95432d679c54fbfd AS frontend-builder

WORKDIR /app/web

# Copy package files
COPY web/package.json web/package-lock.json ./

# Pin npm to the version that generated package-lock.json. The node:24-alpine
# base image's bundled npm floats across rebuilds; a newer npm reshapes the
# rolldown wasm-fallback @emnapi optional deps and breaks `npm ci`. Keep this in
# lockstep with the "packageManager" field in web/package.json.
RUN npm i -g npm@11.16.0

# Install dependencies (including dev dependencies needed for build)
RUN npm ci

# Copy frontend source
COPY web/ ./

# Build frontend for production
RUN npm run build

# ============================================================================
# Stage 2: Build Backend (Go)
# ============================================================================
FROM golang:1.26-alpine@sha256:8ac98ca534ac3f51e1f420a1dd2c15e74c75cfa0f23f3ad27eb5d7236c349a0c AS backend-builder

# Install build dependencies
RUN apk add --no-cache git gcc musl-dev sqlite-dev

WORKDIR /app

# Copy go mod files
COPY go.mod go.sum ./

# Download dependencies
# Allow Go to auto-download required toolchain version
ENV GOTOOLCHAIN=auto
RUN go mod download

# Copy source code
COPY cmd/ ./cmd/
COPY configs/ ./configs/
COPY docs/ ./docs/
COPY internal/ ./internal/
COPY pkg/ ./pkg/

# Build the application
# CGO is required for SQLite support
# GOTOOLCHAIN=auto allows automatic toolchain download if needed
RUN CGO_ENABLED=1 GOOS=linux GOTOOLCHAIN=auto go build -a -installsuffix cgo \
    -ldflags '-extldflags "-static"' \
    -o /app/bin/actalog \
    ./cmd/actalog

# ============================================================================
# Stage 3: Runtime Image
# ============================================================================
FROM alpine:latest@sha256:294b683cb724975bec92580e1e685676bd4b50bda910ddb8c51d4cabeaec77e6

# Install runtime dependencies
RUN apk add --no-cache \
    ca-certificates \
    sqlite \
    sqlite-libs \
    tzdata

# Create non-root user
RUN addgroup -g 1000 actalog && \
    adduser -D -u 1000 -G actalog actalog

WORKDIR /app

# Copy backend binary from builder
COPY --from=backend-builder /app/bin/actalog /app/actalog

# Copy frontend build from builder
COPY --from=frontend-builder /app/web/dist /app/web/dist

# Copy seed CSV files (movements and WODs)
COPY seeds/ /app/seeds/

# Copy seed initialization script and entrypoint
COPY docker/scripts/init-seeds.sh /app/scripts/init-seeds.sh
COPY docker/scripts/entrypoint.sh /app/scripts/entrypoint.sh

# Create directories for uploads, database, and backups
RUN mkdir -p /app/uploads /app/data /app/backups /app/scripts && \
    chmod +x /app/scripts/init-seeds.sh /app/scripts/entrypoint.sh && \
    chown -R actalog:actalog /app

# Switch to non-root user
USER actalog

# Expose port
EXPOSE 8080

# Health check
# Probe 127.0.0.1 rather than "localhost": where localhost resolves to ::1 first,
# wget targets [::1] while the server binds IPv4 only, so the check never passes.
# Shell form (not exec form) so ${SERVER_PORT} is expanded at runtime.
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider "http://127.0.0.1:${SERVER_PORT:-8080}/health" || exit 1

# Set default environment variables
ENV DB_DRIVER=sqlite3 \
    DB_NAME=/app/data/actalog.db \
    PORT=8080 \
    UPLOADS_DIR=/app/uploads \
    FRONTEND_DIR=/app/web/dist

# Run the application via entrypoint (handles optional seed import)
CMD ["/app/scripts/entrypoint.sh"]