[๐Ÿค–] Next.js Dockerfile ์ตœ์ ํ™”: ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ์™„๋ฒฝ ๊ฐ€์ด๋“œ

Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ํšจ์œจ์ ์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์„ธ์š”. ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ, ์บ์‹ฑ ์ „๋žต, ๋ณด์•ˆ ์„ค์ • ๋“ฑ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ์ตœ์ ํ™”๋œ Dockerfile ์ž‘์„ฑ ๊ฐ€์ด๋“œ๋ฅผ ์ œ๊ณตํ•ด ๋“œ๋ ค์š”.

20๋ถ„
๋‹จ์–ด: 1,563๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Docker๋กœ ๋ฐฐํฌํ•  ๋•Œ, ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ์™€ ๋ ˆ์ด์–ด ์บ์‹ฑ์„ ํ™œ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ๋นŒ๋“œ ์†๋„๋ฅผ ๋†’์ด๋ฉฐ, ๋ณด์•ˆ๊นŒ์ง€ ๊ณ ๋ คํ•œ ์ตœ์ ์˜ Dockerfile ์ž‘์„ฑ ์ „๋žต์„ ๋ฐฐ์›Œ๋ด์š”.

์•ˆ๋…•ํ•˜์„ธ์š”, ๋ธ”๋ฃจ์ž…๋‹ˆ๋‹ค! ์ €๋Š” 10๋…„ ์ด์ƒ์˜ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ์‹œ๋‹ˆ์–ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž์ด์ž ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ SEO ์ „๋ฌธ๊ฐ€๋กœ ํ™œ๋™ํ•˜๊ณ  ์žˆ๋Š” AI ๊ฐœ๋ฐœ์ž์˜ˆ์š”.
์˜ค๋Š˜์€ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด ์‹ค๋ฌด์—์„œ ๊ณ ๋ฏผํ•˜์‹œ๋Š” Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ Docker ๋ฐฐํฌ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด ๋ณด๋ ค๊ณ  ํ•ด์š”.

๐Ÿค” Next.js ์•ฑ, ์™œ Docker๋กœ ๋ฐฐํฌํ•ด์•ผ ํ• ๊นŒ์š”?

์ตœ์‹  ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์žˆ์–ด Docker์™€ ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ๊ธฐ์ˆ ์€ ์ด์ œ ์„ ํƒ์ด ์•„๋‹Œ ํ•„์ˆ˜๊ฐ€ ๋˜๊ณ  ์žˆ์–ด์š”. ํŠนํžˆ Next.js์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Docker๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ด์ ์ด ์ •๋ง ๋งŽ์•„์š”.
ํ•˜์ง€๋งŒ ๋‹จ์ˆœํžˆ next build ํ›„ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

0๏ธโƒฃ ์ปจํ…Œ์ด๋„ˆํ™”์˜ ์ด์ : ์ผ๊ด€๋œ ํ™˜๊ฒฝ, ์‰ฌ์šด ํ™•์žฅ, ๋น ๋ฅธ ๋ฐฐํฌ

Docker๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ๊ณผ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ ๊ฐ„์˜ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด์š”. "์ œ ์ปดํ“จํ„ฐ์—์„œ๋Š” ์ž˜ ๋˜๋Š”๋ฐ์š”?"๋ผ๋Š” ๋ง์€ ๋” ์ด์ƒ ํ†ตํ•˜์ง€ ์•Š๊ฒŒ ๋˜์ฃ .
๋ชจ๋“  ์ข…์†์„ฑ๊ณผ ์„ค์ •์ด ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— ์บก์Аํ™”๋˜์–ด ์žˆ์–ด, ์–ด๋””์„œ๋“  ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋Š” ํ™˜๊ฒฝ์„ ๋ณด์žฅํ•ด ์ค˜์š”.
๋˜ํ•œ, ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ™•์žฅ(Scale-out)์ด ์šฉ์ดํ•˜๊ณ , CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜์—ฌ ๋ฐฐํฌ ์ž๋™ํ™”๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ๋„ ํŽธ๋ฆฌํ•ด์š”.

1๏ธโƒฃ ์ผ๋ฐ˜์ ์ธ Dockerfile์˜ ํ•œ๊ณ„: ์ด๋ฏธ์ง€ ํฌ๊ธฐ, ๋นŒ๋“œ ์†๋„

์ดˆ๋ณด ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด ์ฒ˜์Œ Dockerfile์„ ์ž‘์„ฑํ•  ๋•Œ ํ”ํžˆ ํ•˜๋Š” ์‹ค์ˆ˜๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ํŒŒ์ผ๊ณผ ๋นŒ๋“œ ๋„๊ตฌ๋ฅผ ์ตœ์ข… ์ด๋ฏธ์ง€์— ํฌํ•จ์‹œํ‚ค๋Š” ๊ฑฐ์˜ˆ์š”.
์ด๋Ÿฐ ๋ฐฉ์‹์€ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์š”.

  • ๋ถˆํ•„์š”ํ•˜๊ฒŒ ํฐ ์ด๋ฏธ์ง€ ํฌ๊ธฐ: ๊ฐœ๋ฐœ ์˜์กด์„ฑ, ๋นŒ๋“œ ์บ์‹œ, ์†Œ์Šค ๋งต ๋“ฑ์ด ์ตœ์ข… ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜์–ด ์ด๋ฏธ์ง€ ํฌ๊ธฐ๊ฐ€ ์ˆ˜๋ฐฑ MB์—์„œ GB ๋‹จ์œ„๋กœ ์ปค์งˆ ์ˆ˜ ์žˆ์–ด์š”. ์ด๋Š” ๋ฐฐํฌ ์‹œ๊ฐ„ ์ฆ๊ฐ€์™€ ์Šคํ† ๋ฆฌ์ง€ ๋น„์šฉ ์ƒ์Šน์œผ๋กœ ์ด์–ด์ ธ์š”.
  • ๋А๋ฆฐ ๋นŒ๋“œ ์†๋„: ๋งค๋ฒˆ ๋ชจ๋“  ์˜์กด์„ฑ์„ ์ƒˆ๋กœ ์„ค์น˜ํ•˜๊ณ  ๋นŒ๋“œํ•˜๋Š” ๊ณผ์ •์€ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์„ ์†Œ๋ชจํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์š”.
  • ๋ณด์•ˆ ์ทจ์•ฝ์  ์ฆ๊ฐ€: ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ๊ณผ ๋„๊ตฌ๋Š” ์ž ์žฌ์ ์ธ ๋ณด์•ˆ ๊ณต๊ฒฉ ํ‘œ๋ฉด์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Next.js ์•ฑ์— ์ตœ์ ํ™”๋œ Dockerfile ์ „๋žต์ด ํ•„์š”ํ•ด์š”.

โš™๏ธ Next.js ํ”„๋กœ๋•์…˜ Dockerfile ํ•ต์‹ฌ ์ „๋žต

Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Docker๋กœ ๋ฐฐํฌํ•  ๋•Œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ 'ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ์ ํ•ฉํ•œ' ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“œ๋Š” ๊ฑฐ์˜ˆ์š”.
์—ฌ๊ธฐ์—๋Š” ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ํ•ต์‹ฌ ์ „๋žต์ด ์žˆ์–ด์š”.

0๏ธโƒฃ ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋กœ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ตœ์†Œํ™”

๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ FROM ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆ„๋Š” ๊ธฐ๋ฒ•์ด์—์š”.
๊ฐ ๋‹จ๊ณ„๋Š” ์ด์ „ ๋‹จ๊ณ„์˜ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ตœ์ข… ์ด๋ฏธ์ง€์—๋Š” ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•ด์„œ ํฌํ•จ์‹œ์ผœ์š”.
Next.js์˜ ๊ฒฝ์šฐ, ๋ณดํ†ต builder ์Šคํ…Œ์ด์ง€์—์„œ ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•œ ๋‹ค์Œ, runner ์Šคํ…Œ์ด์ง€์—์„œ ๋นŒ๋“œ๋œ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๋Ÿฐํƒ€์ž„์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ํŒŒ์ผ๋งŒ ๋ณต์‚ฌํ•ด์„œ ์ตœ์ข… ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋ผ์š”.
์ด๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ ๋„๊ตฌ, ์†Œ์Šค ์ฝ”๋“œ, ์ค‘๊ฐ„ ๋นŒ๋“œ ํŒŒ์ผ ๋“ฑ์ด ์ตœ์ข… ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ ํšจ์œจ์ ์ธ ๋ ˆ์ด์–ด ์บ์‹ฑ์œผ๋กœ ๋นŒ๋“œ ์†๋„ ํ–ฅ์ƒ

Docker ๋นŒ๋“œ๋Š” ๊ฐ RUN ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด '๋ ˆ์ด์–ด'๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์บ์‹œํ•ด์š”.
์ด ์บ์‹œ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ฉด ๋นŒ๋“œ ์†๋„๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”.
ํ•ต์‹ฌ์€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋ช…๋ น์„ Dockerfile์˜ ์ƒ๋‹จ์— ๋ฐฐ์น˜ํ•˜๊ณ , ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ๋ช…๋ น์„ ํ•˜๋‹จ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฑฐ์˜ˆ์š”.
์˜ˆ๋ฅผ ๋“ค์–ด, package.json๊ณผ pnpm-lock.yaml (๋˜๋Š” yarn.lock, package-lock.json) ํŒŒ์ผ์„ ๋จผ์ € ๋ณต์‚ฌํ•˜์—ฌ ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด, ์†Œ์Šค ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ์—๋„ ์˜์กด์„ฑ ์„ค์น˜ ๋‹จ๊ณ„๋Š” ์บ์‹œ๋ฅผ ์žฌํ™œ์šฉํ•˜์—ฌ ๋น ๋ฅด๊ฒŒ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ ๋ณด์•ˆ ๊ฐ•ํ™”: ๋น„๋ฃจํŠธ(Non-root) ์‚ฌ์šฉ์ž ์‹คํ–‰

๊ธฐ๋ณธ์ ์œผ๋กœ Docker ์ปจํ…Œ์ด๋„ˆ๋Š” root ์‚ฌ์šฉ์ž๋กœ ์‹คํ–‰๋ผ์š”. ํ•˜์ง€๋งŒ ์ด๋Š” ๋ณด์•ˆ์ƒ ์ข‹์ง€ ์•Š์€ ๊ด€ํ–‰์ด์—์š”.
์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ root ๊ถŒํ•œ์œผ๋กœ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰๋  ๊ฒฝ์šฐ, ์ž ์žฌ์ ์ธ ๊ณต๊ฒฉ์ž๊ฐ€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํƒˆ์ทจํ–ˆ์„ ๋•Œ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์— ๋” ํฐ ํ”ผํ•ด๋ฅผ ์ค„ ์ˆ˜ ์žˆ์–ด์š”.
๋”ฐ๋ผ์„œ Dockerfile ๋‚ด์—์„œ ๋ณ„๋„์˜ ๋น„๋ฃจํŠธ ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•ด๋‹น ์‚ฌ์šฉ์ž๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋ณด์•ˆ ๋ชจ๋ฒ” ์‚ฌ๋ก€์˜ˆ์š”.

๐Ÿงช ๋‹จ๊ณ„๋ณ„ Dockerfile ์ž‘์„ฑ ๋ฐ ์ตœ์ ํ™”

์ด์ œ ์‹ค์ œ๋กœ Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ์ตœ์ ํ™”๋œ Dockerfile์„ ์ž‘์„ฑํ•ด ๋ณผ ์‹œ๊ฐ„์ด์—์š”.
์—ฌ๊ธฐ์„œ๋Š” pnpm์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜์ง€๋งŒ, npm์ด๋‚˜ yarn๋„ ๋™์ผํ•œ ์›๋ฆฌ๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

0๏ธโƒฃ ๊ธฐ๋ณธ Dockerfile ๊ตฌ์กฐ (๊ฐœ๋ฐœ/ํ”„๋กœ๋•์…˜ ๋ถ„๋ฆฌ)

๋จผ์ € ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ์— ์ดˆ์ ์„ ๋งž์ถ˜ Dockerfile์„ ์ž‘์„ฑํ•  ๊ฑฐ์˜ˆ์š”.
๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ณดํ†ต next dev๋ฅผ ์ง์ ‘ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, docker compose๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ๋„์šฐ๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ .dockerignore ํŒŒ์ผ๋กœ ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ ์ œ์™ธ

.dockerignore ํŒŒ์ผ์€ git-ignore์™€ ์œ ์‚ฌํ•˜๊ฒŒ, Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์‹œ ์ปจํ…์ŠคํŠธ์—์„œ ์ œ์™ธํ•  ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ง€์ •ํ•˜๋Š” ์—ญํ• ์„ ํ•ด์š”.
์ด๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ , ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ์ด๋ฏธ์ง€์— ํฌํ•จ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

.env .env.local .env.development.local .env.production.local node_modules npm-debug.log yarn-debug.log yarn-error.log .pnpm-store .next .git .gitignore README.md Dockerfile docker-compose*
์œ ์šฉํ•œ ํŒ

.dockerignore์— .next๋ฅผ ํฌํ•จ์‹œํ‚ค๋Š” ์ด์œ ๋Š” ๋นŒ๋“œ๋œ ๊ฒฐ๊ณผ๋ฌผ์„ builder ์Šคํ…Œ์ด์ง€์—์„œ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  runner ์Šคํ…Œ์ด์ง€๋กœ ๋ณต์‚ฌํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด์—์š”. ๋กœ์ปฌ์—์„œ ๋นŒ๋“œ๋œ .next ํด๋”๊ฐ€ ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ณต์‚ฌ๋˜์ง€ ์•Š๋„๋ก ๋ฐฉ์ง€ํ•ด ์ค˜์š”.
node_modules๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ ์ƒˆ๋กœ ์„ค์น˜ํ•  ๊ฒƒ์ด๋ฏ€๋กœ ์ œ์™ธํ•ด์š”.

2๏ธโƒฃ package.json ์Šคํฌ๋ฆฝํŠธ ์„ค์ •

Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ package.json ํŒŒ์ผ์—๋Š” ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๋ฐ ์‹œ์ž‘ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์–ด์•ผ ํ•ด์š”.
ํŠนํžˆ start ์Šคํฌ๋ฆฝํŠธ๋Š” next start๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ด์š”.

{ "name": "my-nextjs-app", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "next": "^14.0.0", "react": "^18", "react-dom": "^18" } }

3๏ธโƒฃ ์ตœ์ข… ํ”„๋กœ๋•์…˜ Dockerfile ์˜ˆ์‹œ

์ด์ œ ์œ„์—์„œ ์„ค๋ช…ํ•œ ์ „๋žต๋“ค์„ ๋ชจ๋‘ ํฌํ•จํ•œ ์ตœ์ข… Dockerfile์„ ์‚ดํŽด๋ณผ๊ฒŒ์š”.
pnpm์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ, npm์ด๋‚˜ yarn์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ•ด๋‹น ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €์— ๋งž๊ฒŒ ๋ช…๋ น์–ด๋งŒ ๋ณ€๊ฒฝํ•ด ์ฃผ์‹œ๋ฉด ๋ผ์š”.

# --- 1. Builder Stage (๋นŒ๋“œ ํ™˜๊ฒฝ) --- FROM node:20-alpine AS builder # ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ • WORKDIR /app # pnpm ์„ค์น˜ RUN npm install -g pnpm # ์˜์กด์„ฑ ์บ์‹ฑ์„ ์œ„ํ•œ ํŒŒ์ผ ๋ณต์‚ฌ # package.json๊ณผ lock ํŒŒ์ผ์„ ๋จผ์ € ๋ณต์‚ฌํ•˜์—ฌ, ์ด ํŒŒ์ผ๋“ค์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ # pnpm install ๋‹จ๊ณ„๋Š” ์บ์‹œ๋ฅผ ์žฌํ™œ์šฉํ•˜๋„๋ก ์œ ๋„ํ•ด์š”. COPY package.json pnpm-lock.yaml* ./ # ์˜์กด์„ฑ ์„ค์น˜ # --frozen-lockfile: lock ํŒŒ์ผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •ํ™•ํžˆ ์„ค์น˜ํ•˜์—ฌ ๋นŒ๋“œ ์ผ๊ด€์„ฑ ์œ ์ง€ RUN pnpm install --frozen-lockfile # ๋‚˜๋จธ์ง€ ์†Œ์Šค ์ฝ”๋“œ ๋ณต์‚ฌ COPY . . # Next.js ์•ฑ ๋นŒ๋“œ # STANDALONE ์ถœ๋ ฅ ๋ชจ๋“œ ์‚ฌ์šฉ (์ตœ์†Œํ•œ์˜ ํŒŒ์ผ๋งŒ ํฌํ•จํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ตœ์ ํ™”) # https://nextjs.org/docs/app/api-reference/next-config-js/output#standalone ENV NEXT_SHARP_PATH=/app/node_modules/sharp RUN pnpm run build # --- 2. Runner Stage (์‹คํ–‰ ํ™˜๊ฒฝ) --- # ์ตœ์ข… ํ”„๋กœ๋•์…˜ ์ด๋ฏธ์ง€๋Š” ๋” ๊ฐ€๋ฒผ์šด nodejs ๋Ÿฐํƒ€์ž„๋งŒ ํฌํ•จํ•ด์š”. FROM node:20-alpine AS runner # Next.js ๊ณต์‹ ๊ถŒ์žฅ ์‚ฌํ•ญ: ๋น„๋ฃจํŠธ ์‚ฌ์šฉ์ž ์‚ฌ์šฉ # https://nextjs.org/docs/app/building-your-application/deploying/docker#non-root-user RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ • ๋ฐ ๊ถŒํ•œ ์„ค์ • # builder ์Šคํ…Œ์ด์ง€์—์„œ ์ƒ์„ฑ๋œ .next/standalone์„ ๋ณต์‚ฌํ•  ์œ„์น˜ WORKDIR /app # builder ์Šคํ…Œ์ด์ง€์—์„œ ๋นŒ๋“œ๋œ .next/standalone ํด๋” ๋ณต์‚ฌ # ์ด ํด๋”์—๋Š” Next.js ์•ฑ ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ชจ๋“  ํŒŒ์ผ์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด์š”. COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./. ext/standalone # public ํด๋” ๋ณต์‚ฌ COPY --from=builder --chown=nextjs:nodejs /app/public ./public # package.json ๋ณต์‚ฌ (start ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์„ ์œ„ํ•ด) # nextjs ์œ ์ €์—๊ฒŒ ๊ถŒํ•œ ๋ถ€์—ฌ COPY --from=builder --chown=nextjs:nodejs /app/package.json ./package.json # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ • (๋Ÿฐํƒ€์ž„์— ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋“ค) ENV NODE_ENV=production ENV PORT=3000 # ์ปจํ…Œ์ด๋„ˆ ํฌํŠธ ๋…ธ์ถœ EXPOSE 3000 # ๋น„๋ฃจํŠธ ์‚ฌ์šฉ์ž๋กœ ์ „ํ™˜ USER nextjs # Health Check ์„ค์ • (์˜ต์…˜) # ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ™•์ธํ•ด์š”. HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 CMD node ./.next/standalone/server.js || exit 1 # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ๋ช…๋ น์–ด CMD ["pnpm", "start"]
์ •๋ณด

NEXT_SHARP_PATH ํ™˜๊ฒฝ ๋ณ€์ˆ˜: Next.js 14๋ถ€ํ„ฐ ์ด๋ฏธ์ง€ ์ตœ์ ํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ Sharp๊ฐ€ Node.js ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ๋กœ ์ œ๊ณต๋˜๋ฉด์„œ, Docker ํ™˜๊ฒฝ์—์„œ ๋นŒ๋“œ ์‹œ ์ด ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด์š”. standalone ๋ชจ๋“œ์—์„œ๋Š” node_modules/sharp ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด ์ฃผ๋ฉด ๋ผ์š”.
output: 'standalone': next.config.js์— ์ด ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜๋ฉด Next.js๊ฐ€ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ์‹œ .next/standalone ํด๋”์— ๋ชจ๋“  ์˜์กด์„ฑ์„ ํฌํ•จํ•œ ์ตœ์†Œํ•œ์˜ ํŒŒ์ผ๋งŒ ์ƒ์„ฑํ•ด ์ค˜์š”. Docker ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๋Š” ๋ฐ ๋งค์šฐ ํšจ๊ณผ์ ์ด์—์š”.

4๏ธโƒฃ next.config.js ์„ค์ • (์„ ํƒ ์‚ฌํ•ญ์ด์ง€๋งŒ ๊ถŒ์žฅ)

์œ„ Dockerfile์€ output: 'standalone' ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ „์ œ๋กœ ํ•ด์š”.
next.config.js ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์ถ”๊ฐ€ํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ๋”์šฑ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”.

/** @type {import('next').NextConfig} */ const nextConfig = { output: 'standalone', // ๊ธฐํƒ€ Next.js ์„ค์ •๋“ค... }; module.exports = nextConfig;

๐Ÿš€ ์‹ค์ œ ๋ฐฐํฌ ์‹œ ๊ณ ๋ ค์‚ฌํ•ญ

์ตœ์ ํ™”๋œ Dockerfile์„ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด, ์ด์ œ ์ด ์ด๋ฏธ์ง€๋ฅผ ์‹ค์ œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•  ๋•Œ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ๋“ค์ด ์žˆ์–ด์š”.

0๏ธโƒฃ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ํ†ตํ•ฉ

Docker ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ‘ธ์‹œํ•˜๋Š” ๊ณผ์ •์„ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.
GitHub Actions, GitLab CI/CD, Jenkins ๋“ฑ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ ํ‘ธ์‹œ ์‹œ ์ž๋™์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด ๋ณด์„ธ์š”.
์ด๋Š” ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค์˜ ์•ˆ์ •์„ฑ๊ณผ ์†๋„๋ฅผ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œ์ผœ ์ค˜์š”.

1๏ธโƒฃ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ด€๋ฆฌ

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฏผ๊ฐํ•œ ์ •๋ณด(API ํ‚ค, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด ๋“ฑ)๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•ด์š”.
Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ docker run -e KEY=VALUE ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, Kubernetes์™€ ๊ฐ™์€ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋„๊ตฌ์˜ Secret ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์–ด์š”.
Dockerfile ๋‚ด์—์„œ๋Š” ENV ๋ช…๋ น์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋Ÿฐํƒ€์ž„์— ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด์—์š”.

2๏ธโƒฃ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋กœ๊น…

๋ฐฐํฌ๋œ Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๋กœ๊ทธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ด์š”.
Docker์˜ ๋กœ๊น… ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜, Prometheus, Grafana, ELK Stack(Elasticsearch, Logstash, Kibana)๊ณผ ๊ฐ™์€ ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ ์ƒํƒœ์™€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๊ทธ๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด ์ฃผ์„ธ์š”.
Health Check ์„ค์ •์€ ์ปจํ…Œ์ด๋„ˆ์˜ ๊ธฐ๋ณธ์ ์ธ ์ƒํƒœ๋ฅผ ํŒŒ์•…ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜์ง€๋งŒ, ๋ณด๋‹ค ์‹ฌ์ธต์ ์ธ ๋ชจ๋‹ˆํ„ฐ๋ง ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์•„์š”.

๐Ÿ“ ์ •๋ฆฌํ•˜๋ฉฐ

์˜ค๋Š˜์€ Next.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ Docker๋กœ ๋ฐฐํฌํ•  ๋•Œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ์ตœ์ ํ™”๋œ Dockerfile์„ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์•˜์–ด์š”.
๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ , ํšจ์œจ์ ์ธ ๋ ˆ์ด์–ด ์บ์‹ฑ์œผ๋กœ ๋นŒ๋“œ ์†๋„๋ฅผ ๋†’์ด๋ฉฐ, ๋น„๋ฃจํŠธ ์‚ฌ์šฉ์ž ์‹คํ–‰์„ ํ†ตํ•ด ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด์—ˆ์–ด์š”.

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ

  • ๋ฉ€ํ‹ฐ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ: builder์™€ runner ์Šคํ…Œ์ด์ง€๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ตœ์†Œํ™”ํ•ด์š”.
  • ๋ ˆ์ด์–ด ์บ์‹ฑ: package.json๊ณผ lock ํŒŒ์ผ์„ ๋จผ์ € ๋ณต์‚ฌํ•˜์—ฌ ์˜์กด์„ฑ ์„ค์น˜ ๋‹จ๊ณ„๋ฅผ ์บ์‹œํ•˜๊ณ , ๋นŒ๋“œ ์†๋„๋ฅผ ๋†’์—ฌ์š”.
  • ๋น„๋ฃจํŠธ ์‚ฌ์šฉ์ž: adduser, addgroup ๋ช…๋ น์œผ๋กœ nextjs ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด ์‚ฌ์šฉ์ž๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜์—ฌ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•ด์š”.
  • output: 'standalone': next.config.js์— ์ด ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜์—ฌ Next.js๊ฐ€ ์ตœ์†Œํ•œ์˜ ํ”„๋กœ๋•์…˜ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์„ฑํ•˜๋„๋ก ํ•ด์š”.
  • .dockerignore: ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ๊ณผ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ œ์™ธํ•˜์—ฌ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์ค„์ด๊ณ  ๋ณด์•ˆ์„ ๋†’์—ฌ์š”.

1๏ธโƒฃ ๋‹ค์Œ ๋‹จ๊ณ„

์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์˜ Next.js ํ”„๋กœ์ ํŠธ์— ์ด Dockerfile ์ตœ์ ํ™” ์ „๋žต์„ ์ ์šฉํ•ด ๋ณผ ์‹œ๊ฐ„์ด์—์š”.
์ž‘์„ฑ๋œ Dockerfile์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ , ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•ด ๋ณด๋ฉด์„œ ์ตœ์ข… ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ์˜ ๋™์ž‘์„ ํ™•์ธํ•ด ๋ณด์„ธ์š”.
๋‚˜์•„๊ฐ€ CI/CD ํŒŒ์ดํ”„๋ผ์ธ์— ํ†ตํ•ฉํ•˜์—ฌ ์ž๋™ํ™”๋œ ๋ฐฐํฌ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•œ๋‹ค๋ฉด ๋”์šฑ ํšจ์œจ์ ์ธ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ์šฐ๋ฅผ ์™„์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

๊ถ๊ธˆํ•œ ์ ์ด๋‚˜ ์ถ”๊ฐ€์ ์œผ๋กœ ๋‹ค๋ฃจ๊ณ  ์‹ถ์€ ์ฃผ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”! ๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋˜ ๋งŒ๋‚˜์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ