# ─── Build stage ──────────────────────────────────────────── FROM oven/bun:1 AS builder WORKDIR /build # Copy workspace root config COPY package.json bun.lock tsconfig.json ./ # Copy all packages the server + observer + dashboard need COPY packages ./packages RUN bun install --frozen-lockfile # Build the dashboard SPA → dist/, then copy to observer's dist/ RUN cd packages/shade-dashboard && bun run build # ─── Production stage ─────────────────────────────────────── FROM oven/bun:1-alpine LABEL org.opencontainers.image.title="Shade Prekey Server" LABEL org.opencontainers.image.description="E2EE prekey distribution server with live observer (Signal Protocol)" LABEL org.opencontainers.image.source="https://gt.zyon.no/Stian/Shade" LABEL org.opencontainers.image.licenses="MIT" LABEL org.opencontainers.image.vendor="Stian" # curl for healthcheck RUN apk add --no-cache curl # Non-root user RUN addgroup -S shade && adduser -S shade -G shade WORKDIR /app COPY --from=builder --chown=shade:shade /build /app # Persistent data directory (SQLite file or any sidecar state) RUN mkdir -p /data && chown shade:shade /data VOLUME ["/data"] USER shade EXPOSE 3900 # Defaults — override via `docker run -e` ENV SHADE_PREKEY_DB_PATH=/data/shade-prekeys.db ENV PORT=3900 ENV SHADE_LOG_LEVEL=info ENV SHADE_STALE_DAYS=30 ENV SHADE_CLEANUP_INTERVAL_HOURS=24 HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD curl -fsS http://localhost:${PORT}/health || exit 1 CMD ["bun", "run", "packages/shade-server/src/standalone.ts"]