# ===================================================================== # Portal interno INSTA # Node 22 sobre Alpine. Sin paso de compilación: el portal se sirve tal # como está en public/, así que la imagen solo instala las dos # dependencias de producción (express y mysql2). # ===================================================================== FROM node:22-alpine # curl para el healthcheck; tini para que las señales lleguen bien. RUN apk add --no-cache curl tini WORKDIR /app ENV NODE_ENV=production # Las dependencias van primero para aprovechar la caché de capas: solo se # reinstalan cuando cambia el manifiesto, no en cada cambio de código. COPY package.json package-lock.json ./ RUN npm ci --omit=dev && npm cache clean --force COPY server ./server COPY db ./db COPY public ./public # El puerto real del portal. Traefik apunta aquí; nunca se publica 80 ni 443. ENV PORT=4180 EXPOSE 4180 # No corre como root. USER node HEALTHCHECK --interval=30s --timeout=5s --start-period=25s --retries=3 \ CMD curl -fsS http://127.0.0.1:4180/salud || exit 1 ENTRYPOINT ["/sbin/tini", "--"] # arranque.mjs espera a MySQL, siembra si hace falta y levanta el servidor. CMD ["node", "db/arranque.mjs"]