# Build context must be the repo root (same as GHA docker-push: context `.`). # Respects .dockerignore (see repo root). Full tree copy keeps workspace installs correct. # docker build -f docker/Dockerfile.server --target prod-unified --build-arg COMMIT_HASH="$(git rev-parse --short HEAD)" -t tachi-server:local . # docker build -f docker/Dockerfile.server --target prod-api . # docker build -f docker/Dockerfile.server --target prod-job-worker . # docker build -f docker/Dockerfile.server --target prod-cron-worker . FROM oven/bun:alpine AS base WORKDIR /app # --- install: full tree so bun sees every workspace package --- FROM base AS deps COPY . . RUN bun install --frozen-lockfile # --- compile each entrypoint (inherits full /app from deps) --- FROM deps AS build-api RUN mkdir -p /out && bun build \ --compile \ --target=bun \ ./typescript/server/src/main.ts \ --outfile /out/server FROM deps AS build-job-worker RUN mkdir -p /out && bun build \ --compile \ --target=bun \ ./typescript/server/src/job-queue-worker.ts \ --outfile /out/job-queue-worker FROM deps AS build-cron-worker RUN mkdir -p /out && bun build \ --compile \ --target=bun \ ./typescript/server/src/cron-worker.ts \ --outfile /out/cron-worker # Runtime: `bun build --compile` links against libstdc++/libgcc; bare alpine:3.21 has neither. # --- API image --- FROM alpine:3.21 AS prod-api ARG COMMIT_HASH ENV COMMIT_HASH=${COMMIT_HASH} ENV MIGRATIONS_DIR=/app/db/migrations RUN apk add --no-cache curl libstdc++ libgcc COPY --from=build-api /out/server /server COPY --from=deps /app/db/migrations /app/db/migrations EXPOSE 8080 HEALTHCHECK --interval=15s --timeout=5s \ CMD curl -sf http://localhost:8080/.deploy/up || exit 1 CMD ["/server"] # --- Job queue worker (no HTTP port) --- FROM alpine:3.21 AS prod-job-worker ARG COMMIT_HASH ENV COMMIT_HASH=${COMMIT_HASH} ENV MIGRATIONS_DIR=/app/db/migrations RUN apk add --no-cache curl libstdc++ libgcc COPY --from=build-job-worker /out/job-queue-worker /job-queue-worker COPY --from=deps /app/db/migrations /app/db/migrations CMD ["/job-queue-worker"] # --- Cron worker (no HTTP port) --- FROM alpine:3.21 AS prod-cron-worker ARG COMMIT_HASH ENV COMMIT_HASH=${COMMIT_HASH} ENV MIGRATIONS_DIR=/app/db/migrations RUN apk add --no-cache curl libstdc++ libgcc COPY --from=build-cron-worker /out/cron-worker /cron-worker COPY --from=deps /app/db/migrations /app/db/migrations CMD ["/cron-worker"] # --- All-in-one image for Kamal (web + job + cron roles share network with accessories) --- FROM alpine:3.21 AS prod-unified ARG COMMIT_HASH ENV COMMIT_HASH=${COMMIT_HASH} ENV MIGRATIONS_DIR=/app/db/migrations RUN apk add --no-cache curl libstdc++ libgcc COPY --from=build-api /out/server /server COPY --from=build-job-worker /out/job-queue-worker /job-queue-worker COPY --from=build-cron-worker /out/cron-worker /cron-worker COPY --from=deps /app/db/migrations /app/db/migrations EXPOSE 8080 CMD ["/server"]