Cloud Dev v1 Dockerfile - 100-hours-a-week/KTB4-1st-wiki GitHub Wiki

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Docker Image ๊ตฌ์„ฑ

์„œ๋น„์Šค๋ณ„ Dockerfile ๊ตฌ์กฐ

์„œ๋น„์Šค ๋Ÿฐํƒ€์ž„ ๋นŒ๋“œ ์ „๋žต ํฌํŠธ
Backend
Frontend Next.js ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ (node ๋นŒ๋“œ โ†’ node ๋Ÿฐํƒ€์ž„, standalone node server.js) 3000
AI FastAPI ๋‹จ์ผ ์Šคํ…Œ์ด์ง€ 8000
  • ๋”๋ฏธ ์•ฑ์€ ํ—ฌ์Šค์ฒดํฌ ์—”๋“œํฌ์ธํŠธ๋งŒ ์ œ๊ณตํ•˜๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์—†์Œ
    • ์ถ”ํ›„ ์ฝ”๋“œ๊ฐ€ ์™„์„ฑ๋˜๋ฉด ์ฝ”๋“œ๋งŒ ๋„ฃ์–ด Docker Image๋กœ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • Frontend, AI๋Š” tobby๊ฐ€, Backend๋Š” janna๊ฐ€ ์ž‘์„ฑํ•œ๋‹ค. ์ด ๋ฌธ์„œ์˜ Dockerfile์€ Frontend, AI๋‹ค.

์ตœ์ ํ™” ๋ฒ”์œ„ ๊ฒฐ์ •

์ž‘์„ฑ ์ „ ๊ณ„ํšํ•œ ์ตœ์ ํ™” ๋ฒ”์œ„๋Š” ๋‹ค์Œ 4๋‹จ๊ณ„์˜€๋‹ค.

  1. COPY/RUN๋งŒ์œผ๋กœ ๊ธฐ๋ณธ ๋นŒ๋“œ
  2. ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ถ•์†Œ โ€” ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ, Next.js standalone ๋ชจ๋“œ
  3. ๋นŒ๋“œ ์†๋„ ๊ฐœ์„  โ€” ์ด๋ฏธ์ง€ ๋ ˆ์ด์–ด ๋ฐฐ์น˜, BuildKit cache mount
  4. ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ์ง€ํ‘œ๋ฅผ ๋‘๊ณ  ๊ฐœ์„  ํญ ์ธก์ •

์ด ๋ฒ”์œ„๋Š” v1์˜ ๋ฐฐํฌ ๋ชฉํ‘œ์™€ ๋งž์ง€ ์•Š์•˜๋‹ค. v1์˜ ๊ธฐ์ค€์€ ์ ์€ ๋น„์šฉ๊ณผ ๋น ๋ฅธ ๋ฐฐํฌ์ธ๋ฐ, ์œ„ ๊ณ„ํš์€ ํ”„๋กœ๋•์…˜ ์ˆ˜์ค€์˜ ์„ธ๋ฐ€ํ•œ ์ตœ์ ํ™”์— ํ•ด๋‹นํ•œ๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ๋น„์šฉ์— ์ง์ ‘ ์˜ํ–ฅ์„ ์ฃผ๋Š” ํ•ญ๋ชฉ๊ณผ ์ง€๊ธˆ ๊ธ‰ํ•˜์ง€ ์•Š์€ ํ•ญ๋ชฉ์„ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ  ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋ ค ํ•œ ๊ฒƒ์ด ๋ฌธ์ œ์˜€๋‹ค.

๊ทธ๋ž˜์„œ ๋น„์šฉ์— ๊ฐ€์žฅ ํฌ๊ฒŒ ์˜ํ–ฅ์„ ์ฃผ๋Š” ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋งŒ v1์˜ ์ตœ์ ํ™” ๋Œ€์ƒ์œผ๋กœ ์ขํ˜”๋‹ค.

ํ•ญ๋ชฉ v1 ์ ์šฉ ํŒ๋‹จ ๊ทผ๊ฑฐ
์ด๋ฏธ์ง€ ํฌ๊ธฐ (๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€, standalone) ์ ์šฉ GHCR ์ „์†ก๋Ÿ‰๊ณผ EC2 ๋ฃจํŠธ ๋ณผ๋ฅจ ์‚ฌ์šฉ๋Ÿ‰์— ์ง์ ‘ ์˜ํ–ฅ. ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์— ํ˜„์žฌ ์ด๋ฏธ์ง€์™€ ๋กค๋ฐฑ์šฉ ์ด์ „ ์ด๋ฏธ์ง€๊ฐ€ ํ•จ๊ป˜ ๋‚จ๋Š”๋‹ค
์˜์กด์„ฑ ๋ ˆ์ด์–ด ๋ถ„๋ฆฌ (์˜์กด์„ฑ ํŒŒ์ผ ๋จผ์ € COPY) ์ ์šฉ ๋‘ ์ค„๋กœ ๋๋‚˜๊ณ  PR๋งˆ๋‹ค ๋„๋Š” CI ๋นŒ๋“œ ์‹œ๊ฐ„์— ๋ฐ”๋กœ ๋ฐ˜์˜๋œ๋‹ค
BuildKit cache mount ์ œ์™ธ ๋นŒ๋“œ ์†๋„ ํ•ญ๋ชฉ. v1 ๊ทœ๋ชจ์—์„œ CI ์‹œ๊ฐ„์ด ์•„์ง ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋‹ค
non root ์œ ์ € ์‹คํ–‰ ์ œ์™ธ ๋ณด์•ˆ ํ•ญ๋ชฉ. v1์€ ๋ถ€ํŠธ์บ ํ”„ ๋‚ด๋ถ€ ์ „์šฉ ์„œ๋น„์Šค์ด๋ฉฐ, ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ด๋ฏธ์ง€ ํฌ๊ธฐ์— ๋‘์—ˆ๋‹ค

Dockerfile ๊ณตํ†ต ์š”๊ตฌ์‚ฌํ•ญ

  • linux/arm64 (AWS EC2 t4g.medium)
    • ํŒ€์› ๋ชจ๋‘ Mac(arm64)๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋กœ์ปฌ, ์šด์˜ ํ™˜๊ฒฝ ๋ชจ๋‘ arm64๋งŒ ํ•„์š”ํ•จ
    • Github Actions ๋Ÿฌ๋„ˆ
      • Github Actions Runner๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ x86(amd64)
      • ARM์šฉ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ARM ๋Ÿฌ๋„ˆ๋ฅผ ๋”ฐ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ QEMU buildx๋กœ ํฌ๋กœ์Šค ๋นŒ๋“œ ํ•„์š”(๋„ค์ดํ‹ฐ๋ธŒ ๋นŒ๋“œ์— ๋น„ํ•ด ๋А๋ฆผ)
      • ๋”ฐ๋ผ์„œ Github Actions์—์„œ runs on์œผ๋กœ ๋„ค์ดํ‹ฐ๋ธŒ arm64 ๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•ด ๋นŒ๋“œํ•œ๋‹ค
  • ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ๋‚˜์ค‘์— ๋“ค์–ด์™€๋„ ๋ณ€๊ฒฝ ์—†์ด ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” ๋Ÿฐํƒ€์ž„์— ์ฃผ์ž…
    • NEXT.js์˜ NEXT_PUBLIC_ ์ œ์™ธ
  • HEALTHCHECK์€ docker compose์—์„œ ๊ด€๋ฆฌํ•ด, ์–ด๋А ์ชฝ์ด ๋กค๋ฐฑ์˜ ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์ถ”์ ํ•˜๊ธฐ ์‰ฝ๋„๋ก ํ•œ๋‹ค.

ํ”„๋ก ํŠธ์—”๋“œ Dockerfile

Next.js๋Š” ์š”์ฒญ๋งˆ๋‹ค ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๋Š” Node ํ”„๋กœ์„ธ์Šค์ด๋ฏ€๋กœ(์„ค๊ณ„ ๋ฌธ์„œ์˜ FE โ†’ BE SSR ํ˜ธ์ถœ) ์ •์  ํŒŒ์ผ๋กœ ๋‚ด๋ณด๋‚ผ ์ˆ˜ ์—†๊ณ , ์ปจํ…Œ์ด๋„ˆ๋กœ ๋‹จ๋… ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ output: 'standalone'์„ ์ „์ œ๋กœ ํ•œ๋‹ค.

๊ธฐ๋ณธ ๊ตฌ์„ฑ (๋น„๊ต์šฉ)

FROM node:22

WORKDIR /app

COPY . .

RUN npm install
RUN npm run build

EXPOSE 3000
CMD ["npm", "start"]
  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ 2.61 GB
  • ๋‹จ์ผ ์Šคํ…Œ์ด์ง€์ด๋ฏ€๋กœ ๋นŒ๋“œ ๋„๊ตฌ, devDependencies, ์†Œ์Šค๊ฐ€ ๋ชจ๋‘ ์ตœ์ข… ์ด๋ฏธ์ง€์— ๋‚จ๋Š”๋‹ค

์ฑ„ํƒ ๊ตฌ์„ฑ โ€” ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ + standalone

FROM node:24.21.0-alpine AS builder

WORKDIR /app

# ์˜์กด์„ฑ ํŒŒ์ผ๋งŒ ๋จผ์ € ๋ณต์‚ฌํ•˜์—ฌ ์„ค์น˜
COPY package.json package-lock.json ./
RUN npm ci

COPY . .
RUN npm run build

FROM node:24.21.0-alpine AS runner

WORKDIR /app

ENV HOSTNAME=0.0.0.0

COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public

EXPOSE 3000
CMD ["node", "server.js"]
  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ 284.92 MB โ€” ๊ธฐ๋ณธ ๊ตฌ์„ฑ์˜ ์•ฝ 1/9
  • output: 'standalone'์€ ์šด์˜์— ์‹ค์ œ๋กœ ํ•„์š”ํ•œ ํŒŒ์ผ๋งŒ ๊ณจ๋ผ์ฃผ๊ณ , ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€๋Š” ๊ทธ๊ฒƒ๋งŒ ์ตœ์ข… ์ด๋ฏธ์ง€์— ์˜ฎ๊ธด๋‹ค.
  • .next/standalone์—๋Š” .next/static๊ณผ public์ด ํฌํ•จ๋˜์ง€ ์•Š์•„ ๋ณ„๋„๋กœ COPYํ•œ๋‹ค. .next/static์ด ๋น ์ง€๋ฉด ํŽ˜์ด์ง€๋Š” ๋œจ์ง€๋งŒ JS/CSS๊ฐ€ 404๊ฐ€ ๋œ๋‹ค
  • ENV HOSTNAME=0.0.0.0 โ€” standalone server.js๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ localhost์— ๋ฐ”์ธ๋”ฉํ•œ๋‹ค. 0.0.0.0์œผ๋กœ ์—ด์ง€ ์•Š์œผ๋ฉด Nginx ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค
  • npm install ๋Œ€์‹  npm ci โ€” lock ํŒŒ์ผ ๊ทธ๋Œ€๋กœ ์„ค์น˜
  • ์•ฑ์ด ๋ ˆํฌ ๋ฃจํŠธ๊ฐ€ ์•„๋‹Œ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ(ktb_agile_frontend/)์— ์žˆ์œผ๋ฏ€๋กœ Dockerfile์„ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ๋‘์—ˆ๋‹ค.
  • Frontend Dockerfile PR

AI Dockerfile

FROM python:3.13.13-slim

WORKDIR /app

COPY . .

RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
  • ์ด๋ฏธ์ง€ ํฌ๊ธฐ 268.32 MB
  • Python์€ ์ปดํŒŒ์ผ ์‚ฐ์ถœ๋ฌผ์ด ์—†์–ด์„œ ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋‹ฌ๋ฆฌ ๋‹จ์ผ ์Šคํ…Œ์ด์ง€๋กœ ๋‘์–ด๋„ ํฌ๊ธฐ๊ฐ€ ์ถฉ๋ถ„ํžˆ ์ž‘๋‹ค
  • --no-cache-dir โ€” pip์ด ๋‚ด๋ ค๋ฐ›์€ wheel์„ ~/.cache/pip์— ์ €์žฅํ•˜๋Š”๋ฐ ์ด๊ฒƒ์ด ๋ ˆ์ด์–ด์— ๋‚จ์œผ๋ฏ€๋กœ ์• ์ดˆ์— ๋งŒ๋“ค์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ๋‹ค
  • --host 0.0.0.0 โ€” uvicorn์˜ ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์€ 127.0.0.1์ด๋ฉฐ, ๊ทธ๋Œ€๋กœ ๋‘๋ฉด ์ปจํ…Œ์ด๋„ˆ ์ž์‹ ๋งŒ ์ ‘์†ํ•  ์ˆ˜ ์žˆ์–ด ๋ฐฑ์—”๋“œ ์ปจํ…Œ์ด๋„ˆ์˜ ์š”์ฒญ์ด ๋‹ฟ์ง€ ์•Š๋Š”๋‹ค
  • AI ์„œ๋ฒ„๋Š” ๋ฐฑ์—”๋“œ๋งŒ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ compose์—์„œ ports:๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ์•Š๊ณ  ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ๋กœ๋งŒ ๋‘”๋‹ค
  • AI Dockerfile PR

์‹ค์ œ ์ฝ”๋“œ ๋ฐ˜์˜ ์‹œ ํ™•์ธํ•  ์กฐ๊ฑด

Dockerfile์ด ๊ฐ ๋ ˆํฌ์˜ ๊ตฌ์กฐ์— ์˜์กดํ•˜๋Š” ์ง€์ ์œผ๋กœ, ๋ฐ”๋€Œ๋ฉด Dockerfile์„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

์„œ๋น„์Šค ์กฐ๊ฑด
Frontend next.config์— output: 'standalone'
Frontend package.json + package-lock.json, npm run build ์Šคํฌ๋ฆฝํŠธ
Frontend public/ ๋””๋ ‰ํ„ฐ๋ฆฌ ์กด์žฌ
Frontend ํด๋ผ์ด์–ธํŠธ์—์„œ ์“ฐ๋Š” API ์ฃผ์†Œ๋Š” ์ƒ๋Œ€ ๊ฒฝ๋กœ(/api). NEXT_PUBLIC_*๋Š” ๋นŒ๋“œ ์‹œ์ ์— ๋ฒˆ๋“ค์— ์ธ๋ผ์ธ๋˜๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„ ์ฃผ์ž…์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค. ์ ˆ๋Œ€ URL์ด ํ•„์š”ํ•ด์ง€๋ฉด ARG ์ถ”๊ฐ€์™€ dev/prod ์ด๋ฏธ์ง€ ๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค
AI requirements.txt๊ฐ€ ์ปจํ…์ŠคํŠธ ๋ฃจํŠธ์— ์žˆ์„ ๊ฒƒ
AI app/main.py์˜ FastAPI ์ธ์Šคํ„ด์Šค๋ช…์ด app์ผ ๊ฒƒ