# ===================================================== # Stage 1: build frontend # ===================================================== FROM node:20-alpine AS frontend-build WORKDIR /app/frontend COPY frontend/package.json frontend/package-lock.json* ./ RUN npm install COPY frontend/ ./ RUN npm run build # ===================================================== # Stage 2: build backend # ===================================================== FROM node:20-alpine AS backend-build WORKDIR /app/backend COPY backend/package.json backend/package-lock.json* ./ RUN npm install COPY backend/ ./ RUN npm run build # ===================================================== # Stage 3: production image # ===================================================== FROM node:20-alpine AS runtime RUN apk add --no-cache nginx supervisor curl WORKDIR /app # Backend production deps COPY backend/package.json backend/package-lock.json* ./backend/ RUN cd backend && npm install --omit=dev # Built backend COPY --from=backend-build /app/backend/dist ./backend/dist # DB migrations COPY db ./db # Frontend static COPY --from=frontend-build /app/frontend/dist /var/www/umbyte # Nginx config COPY nginx.conf /etc/nginx/http.d/default.conf # Supervisor config COPY supervisord.conf /etc/supervisord.conf EXPOSE 80 HEALTHCHECK --interval=30s --timeout=5s --start-period=20s \ CMD curl -f http://localhost/api/health || exit 1 CMD ["supervisord", "-c", "/etc/supervisord.conf"]