# syntax=docker/dockerfile:1 # ---------- Build stage ---------- FROM node:20-alpine AS builder WORKDIR /app # Install Yarn 1 (classic) – ensures compatibility with existing lockfile RUN if command -v yarn >/dev/null && [ "$(yarn --version)" = "1.22.19" ]; then \ echo "Yarn 1.22.19 already installed"; \ else \ rm -f /usr/local/bin/yarn /usr/local/bin/yarnpkg && \ npm install -g yarn@1.22.19 && yarn --version; \ fi # Install dependencies (cache layer) COPY package.json . COPY yarn.lock . RUN yarn install --production=false # Copy source code COPY . . # Prune dev dependencies for production image RUN yarn install --production && \ rm -rf **/*.test.js # ---------- Runtime stage ---------- FROM node:20-alpine AS runtime # Crear el usuario y grupo del sistema RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app # Copiar los archivos desde el builder COPY --from=builder /app/package.json . COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/src ./src # CRUCIAL: Asegurar que appuser sea dueño de la carpeta de la app # Esto evita problemas si el script 'actualizarToken.js' necesita escribir logs o archivos temporales RUN chown -R appuser:appgroup /app ENV NODE_ENV=production # Mantenemos el usuario seguro para la ejecución normal de la app USER appuser # EXPOSE 3000 # HEALTHCHECK --interval=30s --timeout=5s --start-period=5s \ # CMD node -e "require('http').get('http://localhost:3000/health', () => process.exit(0)).on('error', () => process.exit(1))" # # # Comando por defecto para iniciar tu aplicación (descoméntalo si Dokploy no lo maneja externamente) # # CMD ["node", "src/index.js"]