πŸš€ [APEX-F1] AWS EC2 기반 ν’€μŠ€νƒ 도컀 배포 μš”μ•½

1. 인프라 ν”„λ‘œλΉ„μ €λ‹ (AWS EC2)

  • t2.micro (Ubuntu) μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜κ³ , μ•ˆμ •μ μΈ λΉŒλ“œλ₯Ό μœ„ν•΄ Swap λ©”λͺ¨λ¦¬λ₯Ό μ„€μ •ν–ˆμŠ΅λ‹ˆλ‹€.

  • λ³΄μ•ˆ κ·Έλ£Ή(Security Group)을 톡해 μ™ΈλΆ€ 접속을 μœ„ν•œ 80(ν”„λ‘ νŠΈμ—”λ“œ), 8080(λ°±μ—”λ“œ API) 포트λ₯Ό κ°œλ°©ν–ˆμŠ΅λ‹ˆλ‹€.

2. λ°±μ—”λ“œ (Spring Boot + PostgreSQL + Redis) 배포

  • docker-compose.yml (곡톡)κ³Ό docker-compose.override.yml (운영/둜컬 ν™˜κ²½ 뢄리)을 ν™œμš©ν•˜μ—¬ ν”„λ‘œνŽ˜μ…”λ„ν•œ μ•„ν‚€ν…μ²˜λ₯Ό κ΅¬μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

  • .env νŒŒμΌμ„ 톡해 λ°μ΄ν„°λ² μ΄μŠ€ λΉ„λ°€λ²ˆν˜Έμ™€ μ™ΈλΆ€ 섀정값듀을 μ•ˆμ „ν•˜κ²Œ μ£Όμž…ν–ˆμŠ΅λ‹ˆλ‹€.

3. ν”„λ‘ νŠΈμ—”λ“œ (Next.js) 배포

  • standalone λΉŒλ“œ μ˜΅μ…˜μ„ μ μš©ν•˜μ—¬, 무거운 node_modules 없이 가볍고 λΉ λ₯Έ 운영 μ „μš© 도컀 이미지λ₯Ό κ΅¬μΆ•ν–ˆμŠ΅λ‹ˆλ‹€.

  • λ°±μ—”λ“œμ™€ ν”„λ‘ νŠΈμ—”λ“œμ˜ docker-composeλ₯Ό λΆ„λ¦¬ν•˜μ—¬ μ„œλ‘œ λ…λ¦½μ μœΌλ‘œ 배포 및 관리가 κ°€λŠ₯ν•œ λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ ν˜•νƒœλ₯Ό κ°–μ·„μŠ΅λ‹ˆλ‹€.


πŸ’₯ νŠΈλŸ¬λΈ”μŠˆνŒ… ν•˜μ΄λΌμ΄νŠΈ (이슈 μš”μ•½)

πŸ”₯ 이슈 1: Tailwind CSS v4와 Alpine Linux 좩돌 (ν”„λ‘ νŠΈμ—”λ“œ λΉŒλ“œ)

  • ν˜„μƒ: 도컀 ν™˜κ²½μ—μ„œ Next.jsλ₯Ό λΉŒλ“œν•  λ•Œ, Tailwind의 Rust 기반 μ—”μ§„(Oxide) λ°”μ΄λ„ˆλ¦¬λ₯Ό μ°Ύμ§€ λͺ»ν•˜λŠ” μ—λŸ¬(ERESOLVE, Cannot find module)κ°€ μ§€μ†μ μœΌλ‘œ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

  • 원인: κ°€λ²Όμš΄ alpine λ¦¬λˆ…μŠ€(musl 라이브러리)와 μ΅œμ‹  Tailwind v4 ν„°λ³΄νŒ© λΉŒλ“œ ν™˜κ²½ κ°„μ˜ ν˜Έν™˜μ„± 버그, 그리고 package-lock.json의 OS 캐싱 λ¬Έμ œμ˜€μŠ΅λ‹ˆλ‹€.

  • ν•΄κ²°: κΈ°λ³Έ 베이슀 이미지λ₯Ό node:18-slim (λ°λΉ„μ•ˆ 계열)으둜 λ³€κ²½ν•˜κ³ , 도컀 μ•ˆμ—μ„œ npm install을 μƒˆλ‘œ 돌렀 ν•΄λ‹Ή OS에 λ§žλŠ” λ°”μ΄λ„ˆλ¦¬λ₯Ό 직접 λ‹€μš΄λ‘œλ“œν•˜λ„λ‘ μœ λ„ν•˜μ—¬ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ”₯ 이슈 2: ν”„λ‘ νŠΈμ—”λ“œ λ„μ»€μ˜ ν™˜κ²½λ³€μˆ˜(URL) λˆ„λ½

  • ν˜„μƒ: λ„μ»€λ‘œ λ„μš΄ ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ APIλ₯Ό ν˜ΈμΆœν•  λ•Œ, μ§€μ •ν•΄ λ‘” EC2 퍼블릭 IPκ°€ μ•„λ‹Œ 둜컬호슀트 μ£Όμ†Œλ‘œ μš”μ²­μ΄ λ‚ μ•„κ°€λŠ” λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

  • 원인: Next.js의 NEXT_PUBLIC_ ν™˜κ²½ λ³€μˆ˜λŠ” λŸ°νƒ€μž„(μ„œλ²„ μ‹€ν–‰ μ‹œ)이 μ•„λ‹Œ **λΉŒλ“œ νƒ€μž„(Build-time)**에 μ½”λ“œμ— μ‚½μž…λ˜μ–΄μ•Ό ν•˜λŠ”λ°, 도컀 μ‹€ν–‰ μ‹œμ μ—λ§Œ λ³€μˆ˜λ₯Ό λ„˜κ²¨μ£Όμ—ˆκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

  • ν•΄κ²°: ν”„λ‘ νŠΈμ—”λ“œ docker-compose.yml의 build.args 속성을 톡해 λΉŒλ“œν•˜λŠ” μˆœκ°„μ— NEXT_PUBLIC_API_URL 값을 λͺ…μ‹œμ μœΌλ‘œ μ£Όμž…ν•˜μ—¬ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

πŸ”₯ 이슈 3: λ°±μ—”λ“œ CORS (403 Forbidden) 차단

  • ν˜„μƒ: ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ νšŒμ›κ°€μž… API 등을 ν˜ΈμΆœν•˜λ©΄ 403 CORS μ—λŸ¬κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

  • 원인: λ°±μ—”λ“œ CorsConfigurationSource에 ν—ˆμš©λœ 도메인이 localhost둜 κ³ μ •λ˜μ–΄ μžˆμ—ˆκ³ , 도컀 λͺ…λ Ήμ–΄(--env-file)둜 μ „λ‹¬ν•œ ν™˜κ²½λ³€μˆ˜κ°€ μ‹€μ œ μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€μ˜ μŠ€ν”„λ§ λΆ€νŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜κΉŒμ§€ λ„λ‹¬ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

  • ν•΄κ²°: CORS 섀정을 ν™˜κ²½λ³€μˆ˜ν™” ν•˜μ—¬ μœ μ—°ν•˜κ²Œ λ§Œλ“€κ³  ([APEX-59]), docker-compose.override.yml에 env_file: μ˜΅μ…˜μ„ 직접 λͺ…μ‹œν•˜μ—¬ μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€λ‘œ 섀정값을 μ„±κ³΅μ μœΌλ‘œ μ£Όμž…ν–ˆμŠ΅λ‹ˆλ‹€.