# syntax=docker/dockerfile:1 # Stage 1: Build the static frontend once on the native platform FROM --platform=$BUILDPLATFORM oven/bun:latest AS frontend-builder WORKDIR /app/frontend COPY frontend/package.json frontend/bun.lock ./ RUN bun install --frozen-lockfile COPY frontend/ . # nuxt.config.ts outputs to ../backend/cmd/server/dist RUN bun run build # Stage 2: Build backend FROM --platform=$BUILDPLATFORM golang:1.27-alpine AS backend-builder WORKDIR /app/backend RUN apk add --no-cache git ca-certificates COPY backend/go.mod backend/go.sum ./ RUN go mod download COPY backend/ . # Copy frontend build output (nuxt generates to backend/cmd/server/dist) COPY --from=frontend-builder /app/backend/cmd/server/dist ./cmd/server/dist ARG TARGETOS ARG TARGETARCH ARG ATTIC_TMDB_API_KEY="" RUN --mount=type=cache,target=/root/.cache/go-build \ CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build \ -ldflags="-w -s -X github.com/lmmendes/attic/internal/plugin/tmdb.APIKey=${ATTIC_TMDB_API_KEY}" \ -o /app/attic ./cmd/server # Stage 3: Runtime FROM alpine:3.20 WORKDIR /app RUN apk add --no-cache ca-certificates su-exec tzdata COPY --from=backend-builder /app/attic /app/attic COPY --chmod=755 backend/docker-entrypoint.sh /app/docker-entrypoint.sh RUN addgroup -g 1000 appgroup \ && adduser -D -u 1000 -G appgroup appuser \ && mkdir -p /data/uploads \ && chown appuser:appgroup /data/uploads EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 USER 1000:1000 ENTRYPOINT ["/app/docker-entrypoint.sh"] CMD ["/app/attic"]