# The web app's image. Build it from the repository root, which holds the workspace's lockfile: # # docker build -f apps/web/Dockerfile -t vectrum . # # ---- build: install dependencies (which also downloads PocketBase into apps/web/bin/) and build Next.js FROM node:24-bookworm-slim AS build WORKDIR /app COPY --from=oven/bun:1.4.2 /usr/local/bin/bun /usr/local/bin/bun RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates unzip && rm -rf /var/lib/apt/lists/* COPY package.json bun.lock ./ COPY patches ./patches COPY apps/mobile/package.json ./apps/mobile/ COPY apps/web/package.json ./apps/web/ COPY apps/web/scripts ./apps/web/scripts RUN bun install --frozen-lockfile COPY apps/web ./apps/web ENV NEXT_TELEMETRY_DISABLED=1 NEXT_OUTPUT=standalone RUN bun run build # ---- runtime: the standalone server, PocketBase, git FROM node:24-bookworm-slim RUN apt-get update && apt-get install -y --no-install-recommends git tini ca-certificates && rm -rf /var/lib/apt/lists/* WORKDIR /app # The standalone output mirrors the workspace: the server is apps/web/server.js, next to a trimmed node_modules/. COPY --from=build --chown=node:node /app/apps/web/.next/standalone ./ WORKDIR /app/apps/web COPY --from=build --chown=node:node /app/apps/web/.next/static ./.next/static COPY --from=build --chown=node:node /app/apps/web/public ./public COPY --from=build --chown=node:node /app/apps/web/pb_migrations ./pb_migrations COPY --from=build --chown=node:node /app/apps/web/bin ./bin COPY --from=build --chown=node:node /app/apps/web/scripts/create-user.mjs ./scripts/ RUN mkdir /data && chown node:node /data VOLUME /data ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ HOSTNAME=0.0.0.0 \ PORT=3000 \ DATA_ROOT=/data \ SSH_PORT=2222 USER node EXPOSE 3000 2222 HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --start-interval=2s \ CMD node -e "fetch('http://127.0.0.1:'+process.env.PORT+'/api/health').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))" # tini forwards stop signals to the whole process group, so PocketBase shuts down cleanly too. ENTRYPOINT ["/usr/bin/tini", "-g", "--"] CMD ["node", "server.js"]