# Web Meteor 3.1 — imagen de producción (fase 3, Docker Compose). # # Multi-stage: # 1. meteor-builder (debian/glibc): instala el meteor-tool y construye el bundle. # 2. server-deps (alpine/musl): npm install de programs/server con toolchain # nativa, sobre la MISMA libc que el runtime. # 3. runtime (node:22-alpine): solo el bundle listo. # # Secretos: NUNCA en la imagen. El entrypoint carga METEOR_SETTINGS desde el # fichero apuntado por METEOR_SETTINGS_FILE (montado por compose). FROM node:22-bookworm AS meteor-builder ENV METEOR_ALLOW_SUPERUSER=1 # Node 22 + Happy Eyeballs elige IPv6 sin ruta contra warehouse.meteor.com # (mismo workaround que en dev, ver UPGRADE.md). ENV NODE_OPTIONS="--dns-result-order=ipv4first --no-network-family-autoselection" # python-is-python3: node-gyp 3.x (pulled by some Atmosphere npm deps) invokes # `python`, absent on bookworm by default. RUN apt-get update \ && apt-get install -y --no-install-recommends curl ca-certificates python3 python-is-python3 make g++ git \ && rm -rf /var/lib/apt/lists/* RUN curl -fsSL "https://install.meteor.com/?release=3.1" | sh WORKDIR /app COPY . . RUN meteor npm install RUN meteor build /build --directory --server-only FROM node:22-alpine AS server-deps RUN apk add --no-cache python3 make g++ WORKDIR /bundle COPY --from=meteor-builder /build/bundle . RUN cd programs/server && npm install --omit=dev FROM node:22-alpine ENV NODE_ENV=production PORT=3000 WORKDIR /app COPY --from=server-deps --chown=node:node /bundle . COPY --chown=node:node docker/web-entrypoint.sh /web-entrypoint.sh RUN chmod +x /web-entrypoint.sh USER node EXPOSE 3000 # 127.0.0.1 (not localhost): busybox wget resolves localhost to ::1 first, but # the Meteor server listens on IPv4 only -> the check would false-negative. HEALTHCHECK --interval=30s --timeout=5s --start-period=90s --retries=5 \ CMD wget -qO /dev/null "http://127.0.0.1:${PORT}/" || exit 1 ENTRYPOINT ["/web-entrypoint.sh"] CMD ["node", "main.js"]