FROM node:24.18-trixie-slim AS backend-build WORKDIR /opt/app COPY backend/package*.json ./ COPY backend/tsconfig.json ./ COPY backend/tsconfig.build.json ./ RUN npm ci --prefer-offline --no-audit --no-fund COPY backend/ . RUN npm run build \ && npm run trace FROM node:24.18-trixie-slim WORKDIR /opt/app LABEL org.opencontainers.image.title="Remnawave Subscription Page" LABEL org.opencontainers.image.description="Remnawave Subscription Page" LABEL org.opencontainers.image.url="https://github.com/remnawave/subscription-page" LABEL org.opencontainers.image.source="https://github.com/remnawave/subscription-page" LABEL org.opencontainers.image.vendor="Remnawave" LABEL org.opencontainers.image.licenses="AGPL-3.0" LABEL org.opencontainers.image.documentation="https://docs.rw" RUN apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/* COPY --from=backend-build /opt/app/dist ./dist COPY frontend/dist/ ./frontend/ COPY backend/ecosystem.config.js ./ COPY backend/docker-entrypoint.sh ./ ENV PM2_DISABLE_VERSION_CHECK=true ENV NODE_OPTIONS="--max-old-space-size=16384" RUN npm install pm2 -g \ && rm -rf /usr/local/lib/node_modules/npm \ /usr/local/lib/node_modules/corepack \ /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack \ /usr/local/include/node HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --start-interval=2s --retries=3 \ CMD curl -fsS -o /dev/null --max-time 2 "http://127.0.0.1:${APP_PORT:-3010}/internal/health" || exit 1 ENTRYPOINT [ "/bin/sh", "docker-entrypoint.sh" ] CMD [ "pm2-runtime", "start", "ecosystem.config.js", "--env", "production" ]