# syntax=docker/dockerfile:1 # ---- build: install dependencies (which also downloads PocketBase into 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 scripts ./scripts RUN bun install --frozen-lockfile COPY . . 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 COPY --from=build --chown=node:node /app/.next/standalone ./ COPY --from=build --chown=node:node /app/.next/static ./.next/static COPY --from=build --chown=node:node /app/public ./public COPY --from=build --chown=node:node /app/pb_migrations ./pb_migrations COPY --from=build --chown=node:node /app/bin ./bin COPY --from=build --chown=node:node /app/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"]