# The frontend is built and published separately; override to pin a version. ARG FRONTEND_IMAGE=gitea.sanplex.xyz/sansan/musicfrontend:latest # Stage 1: Build the backend on the build machine and cross-compile for the target platform, # so multi-platform builds need no emulation. FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS build ARG TARGETOS TARGETARCH WORKDIR /app COPY go.mod go.sum ./ RUN --mount=type=cache,target=/go/pkg/mod go mod download COPY cmd/ ./cmd/ COPY internal/ ./internal/ RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \ go tool templ generate RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \ CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH \ go build -trimpath -ldflags="-s -w" -tags timetzdata -o main ./cmd # Stage 2: Frontend static files (the same for every platform) FROM --platform=$BUILDPLATFORM ${FRONTEND_IMAGE} AS frontend # Stage 3: Final image. No RUN steps here, so no emulation is needed for other architectures. FROM alpine:3.22 COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ WORKDIR /app COPY --from=build /app/main . COPY --from=frontend /usr/share/nginx/html /frontend COPY ./songs/ ./songs/ # The music volume must be readable by uid 1000, and writable for the .id file cleanup during sync # and for soundtrack uploads (kept in .uploads until finished). USER 1000:1000 EXPOSE 8080 # Prometheus metrics (METRICS_PORT). Keep it off the public proxy. EXPOSE 2112 VOLUME /sorted VOLUME /characters # Required: DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_NAME, MUSIC_PATH, CHARACTERS_PATH # Covers (optional): COVERS_PATH, a writable folder such as a /covers volume, turns covers on. # STEAMGRIDDB_API_KEY also turns on the automatic search (SteamGridDB, then AniList). # Uploads (optional): UPLOAD_MAX_FILE_MB (default 50) and UPLOAD_MAX_TOTAL_MB (default 2048). ENV PORT=8080 CMD ["./main"]