# node:22-bookworm-slim 으로 glibc 환경 유지 (yt-dlp_linux 가 glibc 바이너리). # alpine 으로 가면 musl 충돌로 yt-dlp 실행 실패함. FROM node:22-bookworm-slim AS build # 빌드에 필요한 도구 + 다운로드용 CA RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates curl python3 \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # 디펜던시 캐시 분리 COPY package.json package-lock.json* ./ RUN npm install --no-audit --no-fund # 소스 복사 후 빌드 (yt-dlp 도 같이 받아둠) COPY tsconfig.json ./ COPY src ./src COPY scripts ./scripts COPY views ./views COPY public ./public RUN SKIP_NPM_INSTALL=1 node scripts/setup.mjs # ───── 런타임 스테이지 ────────────────────────────────────────────── FROM node:22-bookworm-slim # ffmpeg 는 영상 trim 에 필요. yt-dlp 는 build 단계에서 받아둔 바이너리를 그대로 가져온다. RUN apt-get update \ && apt-get install -y --no-install-recommends ffmpeg ca-certificates \ && rm -rf /var/lib/apt/lists/* WORKDIR /app ENV NODE_ENV=production # 컨테이너 안에서는 외부에서 들어오는 트래픽을 받아야 하니까 반드시 0.0.0.0. ENV HOST=0.0.0.0 ENV PORT=3000 # 빌드 산출물 + 런타임에 필요한 정적 자원만 복사 COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/dist ./dist COPY --from=build /app/bin ./bin COPY --from=build /app/views ./views COPY --from=build /app/public ./public COPY --from=build /app/package.json ./package.json COPY account.json ./account.json # 데이터 디렉토리 (영상/잡 영속화). docker-compose 에서 볼륨 마운트. RUN mkdir -p /app/data/folders /app/data/jobs /app/data/tmp EXPOSE 3000 # tini 없이도 큰 영상 업로드/yt-dlp 자식 프로세스를 깔끔히 끄도록 신호를 받게 한다. STOPSIGNAL SIGTERM CMD ["node", "dist/app.js"]