๐Ÿณ ๋กœ์ปฌ Docker ํ™˜๊ฒฝ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฐ€์ด๋“œ

๋กœ์ปฌ์—์„œ๋Š” ์ž˜ ๋˜๋Š”๋ฐ Docker์—์„œ ์•ˆ ๋  ๋•Œ ํ™•์ธํ•  ์‚ฌํ•ญ๋“ค

โš ๏ธ ์ฐธ๊ณ : ์˜ˆ์‹œ์˜ doll_gacha ์ด๋ฆ„์€ ์ด์ „ ํ”„๋กœ์ ํŠธ ์ฐธ์กฐ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ํ”„๋กœ์ ํŠธ๋ช…์— ๋งž๊ฒŒ ๋ณ€๊ฒฝํ•˜์„ธ์š”.

๐Ÿ“ ํŒŒ์ผ ๊ฒฝ๋กœ ๊ฒฐํ•ฉ ๋ฌธ์ œ

๋ฌธ์ œ ํ˜„์ƒ

  • ์—๋””ํ„ฐ์—์„œ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ โ†’ 201 ์„ฑ๊ณต, ํ•˜์ง€๋งŒ ์ด๋ฏธ์ง€ ํ‘œ์‹œ ์•ˆ๋จ
  • ์ฒจ๋ถ€ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ โ†’ 404 ์—๋Ÿฌ
  • <img src="/uploads/xxx.png"> ์ด๋ฏธ์ง€ ๊นจ์ง

    ์›์ธ

    ๊ฒฝ๋กœ ๊ฒฐํ•ฉ ์‹œ ๋ฌธ์ž์—ด ๋‹จ์ˆœ ๊ฒฐํ•ฉ(+) ์‚ฌ์šฉ ๋ฐ application.yml์—๋Š” ./uploads application-prod.yml์—๋Š” /app/uploads ์ด๋ ‡๊ฒŒ ๋’ค์— / ๊ฐ€ ์žˆ๋ƒ ์—†๋ƒ ์ฐจ์ด์˜€๋‹ค. ```java // โŒ ๋ฌธ์ž์—ด ๋‹จ์ˆœ ๊ฒฐํ•ฉ - yml ์„ค์ •์— ๋”ฐ๋ผ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง uploadDir + filename = โ€œ/app/uploadsโ€ + โ€œtest.pngโ€ = โ€œ/app/uploadstest.pngโ€ โŒ uploadDir + filename = โ€œ/app/uploads/โ€ + โ€œtest.pngโ€ = โ€œ/app/uploads/test.pngโ€ โœ…

// โœ… Paths.resolve() - yml ์„ค์ •์— ์ƒ๊ด€์—†์ด ํ•ญ์ƒ ์ •์ƒ ์ž‘๋™ Paths.get(โ€œ/app/uploadsโ€).resolve(โ€œtest.pngโ€) = โ€œ/app/uploads/test.pngโ€ โœ… Paths.get(โ€œ/app/uploads/โ€).resolve(โ€œtest.pngโ€) = โ€œ/app/uploads/test.pngโ€ โœ…

### ์™œ Paths.resolve()์ธ๊ฐ€?
- **yml ์„ค์ •์— `/` ๋ถ™์ด๋“  ์•ˆ ๋ถ™์ด๋“  ์ƒ๊ด€์—†์Œ** โ†’ ์„ค์ • ์‹ค์ˆ˜ ๋ฐฉ์ง€
- **๊ทผ๋ณธ์ ์ธ ํ•ด๊ฒฐ์ฑ…** - ๊ฒฝ๋กœ ๊ด€๋ จ ๋ฒ„๊ทธ ์›์ฒœ ์ฐจ๋‹จ
#### 3. Docker ๋ณผ๋ฅจ ๋งคํ•‘ ํ™•์ธ
```yaml
# docker-compose.yml
services:
  app:
    volumes:
      - ./uploads:/app/uploads  # ํ˜ธ์ŠคํŠธ โ†” ์ปจํ…Œ์ด๋„ˆ ์—ฐ๊ฒฐ

์ฐธ๊ณ  : yml์—์„œ ์œˆ๋„์šฐ๋“  ๋ฆฌ๋ˆ…์Šค๋“  / ๋กœ ๊ฒฝ๋กœํ•ด๋„ ์•Œ์•„์„œ jvm์ด ์ฒ˜๋ฆฌํ•จ


๐ŸŽฏ 1. ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ์ฒดํฌ๋ฆฌ์ŠคํŠธ

๋กœ์ปฌ โ†’ Docker ๋ฐฐํฌ ์‹œ ํ™•์ธ์‚ฌํ•ญ

์ฒดํฌ ํ•ญ๋ชฉ ์ ์šฉ ์œ„์น˜
โœ… ํŒŒ์ผ ๊ฒฝ๋กœ ๊ฒฐํ•ฉ ์‹œ Paths.resolve() ์‚ฌ์šฉ FileUtil.java, FileController.java
โœ… ๋ณผ๋ฅจ ๋งคํ•‘์œผ๋กœ ํŒŒ์ผ ์˜์†์„ฑ ํ™•๋ณด docker-compose.yml โ†’ ./uploads:/app/uploads
โœ… ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ „๋‹ฌ docker-compose.yml โ†’ environment: ์„น์…˜
โœ… DB ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด (localhost โ†’ ์ปจํ…Œ์ด๋„ˆ๋ช…) application-prod.yml + docker-compose.yml
โœ… ๋ธŒ๋ผ์šฐ์ € ์ฟ ํ‚ค ์ •๋ฆฌ ํ™˜๊ฒฝ ์ „ํ™˜ ์‹œ ์ˆ˜๋™ ์‚ญ์ œ ํ•„์š”

๊ฐ ํ•ญ๋ชฉ ์ƒ์„ธ ์„ค๋ช…

1๏ธโƒฃ ๋ณผ๋ฅจ ๋งคํ•‘ (docker-compose.yml)

app:
  volumes:
    - ./uploads:/app/uploads  # ํ˜ธ์ŠคํŠธ โ†” ์ปจํ…Œ์ด๋„ˆ ์—ฐ๊ฒฐ

2๏ธโƒฃ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ „๋‹ฌ (docker-compose.yml)

app:
  environment:
    # DB ์„ค์ • - ์ปจํ…Œ์ด๋„ˆ๋ช… 'db' ์‚ฌ์šฉ
    SPRING_DATASOURCE_URL: jdbc:mariadb://db:3306/doll_gacha
    SPRING_DATASOURCE_USERNAME: doll_gacha
    SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD:-ckdlsk13!}
    
    # OAuth2 ์„ค์ • - .env ํŒŒ์ผ์—์„œ ์ฝ์–ด์˜ด
    KAKAO_CLIENT_ID: ${KAKAO_CLIENT_ID}
    KAKAO_CLIENT_SECRET: ${KAKAO_CLIENT_SECRET}
    GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
    GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
    
    # JWT ์„ค์ •
    JWT_SECRET_KEY: ${JWT_SECRET_KEY}
    
    # ์•ฑ URL
    APP_BASE_URL: ${APP_BASE_URL:-http://localhost:8080}

3๏ธโƒฃ DB ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด ๋ณ€๊ฒฝ

# application.yml (๋กœ์ปฌ)
url: jdbc:mariadb://localhost:3406/doll_gacha

# application-prod.yml (Docker)
url: ${SPRING_DATASOURCE_URL:jdbc:mariadb://localhost:3406/doll_gacha}
# โ†’ docker-compose์—์„œ jdbc:mariadb://db:3306/doll_gacha ๋กœ ๋ฎ์–ด์”€

4๏ธโƒฃ ๋ธŒ๋ผ์šฐ์ € ์ฟ ํ‚ค ์ •๋ฆฌ

๋กœ์ปฌ โ†’ Docker ์ „ํ™˜ ์‹œ:
1. F12 (๊ฐœ๋ฐœ์ž๋„๊ตฌ) โ†’ Application ํƒญ
2. Cookies โ†’ localhost
3. access_token, refresh_token ์‚ญ์ œ
4. ์ƒˆ๋กœ๊ณ ์นจ

ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๋น„๊ต

์„ค์ • ๋กœ์ปฌ (application.yml) Docker (application-prod.yml + docker-compose.yml)
DB URL localhost:3406 db:3306 (์ปจํ…Œ์ด๋„ˆ๋ช…)
ํŒŒ์ผ ๊ฒฝ๋กœ C:/workspace/.../uploads /app/uploads
ํ”„๋กœํŒŒ์ผ default prod (Dockerfile์—์„œ ์ง€์ •)
ํฌํŠธ 8080 8080:8080 (ํ˜ธ์ŠคํŠธ:์ปจํ…Œ์ด๋„ˆ)
OAuth redirect localhost:8080 ${APP_BASE_URL} (ํ™˜๊ฒฝ๋ณ€์ˆ˜)

๐Ÿ“ 2. ๋””๋ฒ„๊น… ๋ช…๋ น์–ด ๋ชจ์Œ

Docker ๋กœ๊ทธ ํ™•์ธ

# ์‹ค์‹œ๊ฐ„ ๋กœ๊ทธ ํ™•์ธ
docker-compose logs -f app

# ์ตœ๊ทผ 100์ค„๋งŒ ํ™•์ธ
docker-compose logs --tail=100 app

์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํ™•์ธ

# ์—…๋กœ๋“œ ํด๋” ํŒŒ์ผ ๋ชฉ๋ก
docker exec -it doll_gacha_app ls -la /app/uploads/

# ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํ™•์ธ
docker exec -it doll_gacha_app env | grep -E "(SPRING|FILE)"

# ์ปจํ…Œ์ด๋„ˆ ์‰˜ ์ ‘์†
docker exec -it doll_gacha_app /bin/sh

๐Ÿ”‘ 4. ํ•ต์‹ฌ ๊ตํ›ˆ

โŒ ํ”ํ•œ ์ฐฉ๊ฐ๋“ค

  1. โ€œ๋กœ์ปฌ์—์„œ ๋˜๋ฉด Docker์—์„œ๋„ ๋œ๋‹คโ€
    • ๊ฒฝ๋กœ, DB, ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋ชจ๋‘ ๋‹ค๋ฆ„
  2. โ€œ์ƒ๋Œ€ ๊ฒฝ๋กœ๊ฐ€ ํŽธํ•˜๋‹คโ€
    • Docker์—์„œ๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ๊ฐ€ ์•ˆ์ „

      โœ… ๊ถŒ์žฅ ์‚ฌํ•ญ

  3. ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๋Š” ํ•ญ์ƒ Paths.get().toAbsolutePath().normalize() ์‚ฌ์šฉ
  4. ์ถฉ๋ถ„ํ•œ ๋กœ๊ทธ ๋‚จ๊ธฐ๊ธฐ (Docker ๋””๋ฒ„๊น…์€ ๋กœ๊ทธ๊ฐ€ ์ƒ๋ช…)

    ๐Ÿ“š ๊ด€๋ จ ํŒŒ์ผ ๋ชฉ๋ก

    • src/main/resources/application-prod.yml - Docker ํ™˜๊ฒฝ ์„ค์ •
    • docker-compose.yml - Docker ๊ตฌ์„ฑ
    • Dockerfile - ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์„ค์ •