# Используем Alpine версию Node.js для минимального размера FROM node:20-alpine AS build # Устанавливаем рабочую директорию WORKDIR /app # Копируем только package.json и package-lock.json для кэширования зависимостей COPY package*.json ./ # Устанавливаем только production зависимости RUN npm ci --only=production && npm cache clean --force # Устанавливаем утилиты для минификации RUN npm install -g terser html-minifier-terser clean-css-cli # Копируем остальные файлы COPY . . # Минифицируем статические файлы RUN mkdir -p public/optimized RUN html-minifier-terser --remove-comments --collapse-whitespace --minify-css --minify-js public/index.html -o public/optimized/index.html RUN terser public/main.js --compress --mangle -o public/optimized/main.js RUN cleancss -o public/optimized/style.css public/style.css # Заменяем оригинальные файлы оптимизированными RUN cp public/optimized/* public/ && rm -rf public/optimized # Финальный stage - только runtime FROM node:20-alpine AS production # Создаем пользователя для безопасности RUN addgroup -g 1001 -S nodejs && adduser -S nodeuser -u 1001 WORKDIR /app # Копируем зависимости из build stage COPY --from=build /app/node_modules ./node_modules # Копируем приложение COPY --from=build /app/server.js ./ COPY --from=build /app/package.json ./ COPY --from=build /app/public ./public # Меняем владельца файлов RUN chown -R nodeuser:nodejs /app USER nodeuser # Открываем порт EXPOSE 3000 # Добавляем health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })" # Запускаем приложение CMD ["node", "server.js"]