๋ชฉ๋ก์œผ๋กœ
ํ”„๋กœ์ ํŠธ

Project - Wedge ๐Ÿ’

ยท6๋ถ„ ์ฝ๊ธฐ
๋ฐ๋ธŒ์ฝ”์Šค๋ฐฑ์—”๋“œ๋ถ€ํŠธ์บ ํ”„ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

๐Ÿ’ Wedge ํ”„๋กœ์ ํŠธ ํšŒ๊ณ  โ€” 2์ฃผ ๋งŒ์— ์›จ๋”ฉ ๋งค์นญ ํ”Œ๋žซํผ ๋งŒ๋“ค๊ธฐ

2026.06.11 ~ 06.24 | ํŒ€ ํ”„๋กœ์ ํŠธ | 4์ธ ๊ฐœ๋ฐœ


ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

Wedge๋Š” ์˜ˆ๋น„๋ถ€๋ถ€(CLIENT)์™€ ์›จ๋”ฉ ์ „๋ฌธ ํ”„๋ฆฌ๋žœ์„œ(FREELANCER)๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๋งค์นญ ํ”Œ๋žซํผ์ด๋‹ค.

์›จ๋”ฉํ™€ ํŒจํ‚ค์ง€์— ๋ฌถ์—ฌ ์žˆ์œผ๋ฉด ๋น„์‹ธ๊ณ  ์„ ํƒ์ง€๋„ ์ข๋‹ค. ๋ฐ˜๋Œ€๋กœ ํ”„๋ฆฌ๋žœ์„œ ์ž…์žฅ์—์„œ๋Š” ์‹ค๋ ฅ์ด ์žˆ์–ด๋„ ํ™๋ณด ์ฑ„๋„์ด ์—†์œผ๋ฉด ์ผ๊ฐ์„ ๋ชป ์ฐพ๋Š”๋‹ค. Wedge๋Š” ์ด ๋‘˜์„ ์ง์ ‘ ์—ฐ๊ฒฐํ•˜๋Š” ๊ตฌ์กฐ๋‹ค. ํ•ต์‹ฌ ์ฐจ๋ณ„์ ์€ ์—ญ๊ฒฝ๋งค ๋ฐฉ์‹: ์˜ˆ๋น„๋ถ€๋ถ€๊ฐ€ ๊ตฌ์ธ๊ธ€์„ ์˜ฌ๋ฆฌ๋ฉด ํ”„๋ฆฌ๋žœ์„œ๊ฐ€ ์ง์ ‘ ์ œ์•ˆ์„œ๋ฅผ ๋‚ด๊ณ , ๋ถ€๋ถ€๊ฐ€ ๋งˆ์Œ์— ๋“œ๋Š” ์ œ์•ˆ์„ ์ˆ˜๋ฝํ•˜๋ฉด ์˜ˆ์•ฝ์ด ์ž๋™ ์ƒ์„ฑ๋œ๋‹ค.

๊ธฐ๋Šฅ ๋ฒ”์œ„๊ฐ€ ๊ฝค ๋„“์—ˆ๋‹ค. ์ธ์ฆ, ํ”„๋กœํ•„, ํฌํŠธํด๋ฆฌ์˜ค, ๋ถ๋งˆํฌ, ์˜ˆ์•ฝ, ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, ๋ฆฌ๋ทฐ, ์ปค๋ฎค๋‹ˆํ‹ฐ, ๊ตฌ์ธ/์ œ์•ˆ, AI ์ฑ—๋ด‡, CI/CD๊นŒ์ง€ โ€” ์ด๊ฑธ 2์ฃผ ์•ˆ์— 4๋ช…์ด ์™„์„ฑํ•ด์•ผ ํ–ˆ๋‹ค.

๋ฐฐํฌ URL: wedge-tawny.vercel.app
์‹œ์—ฐ ์˜์ƒ: streamable.com/6dklaq


ํŒ€์›๊ณผ ์—ญํ•  ๋ถ„๋‹ด

์ด๋ฆ„๋‹ด๋‹น
์œคํ•˜๋นˆ์ฐœ(๋ถ๋งˆํฌ), ์ „๋ฌธ๊ฐ€ ํƒ์ƒ‰ API, ์ถ”์ฒœ ์บ๋Ÿฌ์…€(Redis ์บ์‹ฑ), AI ๊ฒฌ์  ์ฑ—๋ด‡
์ •๋ฏผํ˜ (๋‚˜)ํšŒ์› ์ธ์ฆ(JWTยทOAuth2ยท์ด๋ฉ”์ผ), ๊ตฌ์ธ/์ œ์•ˆ ์‹œ์Šคํ…œ, ์ปค๋ฎค๋‹ˆํ‹ฐ, CI/CD, AWS ๋ฐฐํฌ
์ด์ฐฝ๋ฏผ์˜ˆ์•ฝ ์‹œ์Šคํ…œ, ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…(WebSocketยทSTOMP), ๋ฆฌ๋ทฐ ๊ธฐ๋Šฅ
์ด๋ฏผ์„œํ”„๋ฆฌ๋žœ์„œ ํ”„๋กœํ•„, ํฌํŠธํด๋ฆฌ์˜ค(Cloudflare R2), ๋งˆ์ดํŽ˜์ด์ง€ UX, ๋””์ž์ธ ์‹œ์Šคํ…œ

๋‚ด๊ฐ€ ๋งก์€ ํŒŒํŠธ โ€” ๊ธฐ์ˆ ์  ๊ฒฐ์ •๋“ค

1. ์ธ์ฆ ์‹œ์Šคํ…œ: JWT + RTR + OAuth2

์ธ์ฆ์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์ด ์˜์กดํ•˜๋Š” ๋ฟŒ๋ฆฌ๋ผ์„œ ๊ฐ€์žฅ ๋จผ์ €, ๊ฐ€์žฅ ๊ผผ๊ผผํ•˜๊ฒŒ ์„ค๊ณ„ํ–ˆ๋‹ค.

RTR(Refresh Token Rotation)

์ผ๋ฐ˜ JWT ๊ตฌ์กฐ์—์„œ Refresh Token์ด ํƒˆ์ทจ๋˜๋ฉด, ๋งŒ๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ณ„์† ์“ธ ์ˆ˜ ์žˆ๋‹ค. RTR์„ ์ ์šฉํ•˜๋ฉด ํ† ํฐ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ ํ† ํฐ์œผ๋กœ ๊ต์ฒด๋˜๋ฏ€๋กœ, ํƒˆ์ทจ ํ”ผํ•ด๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ตฌํ˜„ ๋ฐฉ์‹์€ ๊ฐ„๋‹จํ•˜๋‹ค. Redis์— memberId๋ฅผ ํ‚ค๋กœ Refresh Token 1๊ฐœ๋งŒ ์œ ์ง€ํ•œ๋‹ค. save()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ์กด ํ† ํฐ์ด ๋ฎ์–ด์จ์ง€๋ฉด์„œ ์ž๋™์œผ๋กœ ๋ฌดํšจํ™”๋œ๋‹ค. ๋ˆ„๊ฐ€ ๋จผ์ € ์“ฐ๋“  ๋‚˜๋จธ์ง€ ํ•œ์ชฝ์€ ์ฐจ๋‹จ๋œ๋‹ค.

refreshTokenRepository.save(RefreshToken.builder()
    .memberId(memberId)
    .token(newRefreshToken)  // upsert โ€” ๊ธฐ์กด ํ† ํฐ ์ž๋™ ๋ฌดํšจํ™”
    .build());

์ด๋ฉ”์ผ ์ธ์ฆ ์ƒํƒœ ๋จธ์‹ 

Redis ํ‚ค๋ฅผ ๋‘ ๊ฐœ๋กœ ๋ถ„๋ฆฌํ–ˆ๋‹ค: ์ธ์ฆ ์ฝ”๋“œ(TTL 5๋ถ„)์™€ ์™„๋ฃŒ ํ”Œ๋ž˜๊ทธ(TTL 30๋ถ„). ์—ญํ• ๊ณผ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜๋กœ ํ•ฉ์น  ์ˆ˜ ์—†๋‹ค. ์ธ์ฆ ์ฝ”๋“œ ๊ฒ€์ฆ ์ฆ‰์‹œ ์‚ญ์ œํ•ด์„œ 1ํšŒ์šฉ์„ ๋ณด์žฅํ•˜๊ณ , ํšŒ์›๊ฐ€์ž… ์™„๋ฃŒ ์‹œ ํ”Œ๋ž˜๊ทธ๋„ ์‚ญ์ œํ•ด์„œ ์ค‘๋ณต ๊ฐ€์ž…์„ ์ฐจ๋‹จํ•œ๋‹ค. DB ๋Œ€์‹  Redis๋ฅผ ์“ด ์ด์œ ๋Š” TTL ๋•์— ๋งŒ๋ฃŒ ๋ฐฐ์น˜ ์ž‘์—…์ด ํ•„์š” ์—†๊ณ , ์กฐํšŒ๋„ ~1ms๋กœ ๋น ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

OAuth2 (Google + Kakao) ํ†ตํ•ฉ

๊ตฌ๊ธ€๊ณผ ์นด์นด์˜ค๋Š” JSON ์‘๋‹ต ๊ตฌ์กฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค. providerId, email, name์˜ ๊ฒฝ๋กœ๊ฐ€ ์ œ๊ฐ๊ฐ์ด๋‹ค. OAuth2MemberService.loadUser()์—์„œ provider๋ณ„ ํŒŒ์‹ฑ๋งŒ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ๊ทธ ์ดํ›„๋Š” ๋™์ผํ•œ Member ์—”ํ‹ฐํ‹ฐ๋กœ ํ†ตํ•ฉํ–ˆ๋‹ค. ํ”„๋ก ํŠธ์—”๋“œ๋Š” ๋กœ๊ทธ์ธ ๊ฒฝ๋กœ์™€ ์ƒ๊ด€์—†์ด JWT ํ•˜๋‚˜๋กœ๋งŒ ํ†ต์‹ ํ•œ๋‹ค.


2. Mixed Content & Caddy ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ

๋ฐฐํฌ ์ง์ „์— ์ƒ๊ฐ์ง€ ๋ชปํ•œ ๋ฌธ์ œ๊ฐ€ ํ„ฐ์กŒ๋‹ค. Vercel(HTTPS)์—์„œ AWS EC2(HTTP, 8080) API๋ฅผ ํ˜ธ์ถœํ•˜๋‹ˆ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ Mixed Content ์ •์ฑ…์œผ๋กœ ์ „๋ถ€ ์ฐจ๋‹จํ–ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ € โ†’ Vercel(HTTPS) โ†’ AWS EC2:8080(HTTP) โ† ์ฐจ๋‹จ!

ํ•ด๊ฒฐ์ฑ…์€ Caddy์˜€๋‹ค.

api.wedge.o-r.kr {
    reverse_proxy localhost:8080
}

์ด ๋‘ ์ค„์ด ์ „๋ถ€๋‹ค. ๋„๋ฉ”์ธ์„ ์ ์œผ๋ฉด Caddy๊ฐ€ Let's Encrypt์—์„œ ์ธ์ฆ์„œ๋ฅผ ์ž๋™ ๋ฐœ๊ธ‰ํ•˜๊ณ , ๋งŒ๋ฃŒ 30์ผ ์ „์— ์•Œ์•„์„œ ๊ฐฑ์‹ ํ•œ๋‹ค.

๋ธŒ๋ผ์šฐ์ € โ†’ Vercel(HTTPS) โ†’ Caddy(HTTPS, 443) โ†’ Spring Boot(HTTP, 8080)

Spring Boot์— SSL์„ ์ง์ ‘ ๋ถ™์ด๋ฉด keystore ์„ค์ •, ์ธ์ฆ์„œ ๊ฐฑ์‹  ์‹œ ์žฌ์‹œ์ž‘์ด ํ•„์š”ํ•œ๋ฐ, Caddy๋กœ ๋ถ„๋ฆฌํ•˜๋ฉด ๊ทธ ๋ณต์žกํ•จ์ด ์‚ฌ๋ผ์ง„๋‹ค. 2์ฃผ์งœ๋ฆฌ ํ”„๋กœ์ ํŠธ์—์„œ ์ธํ”„๋ผ์— ์“ธ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์€ ์ œํ•œ์ ์ด์—ˆ๊ณ , Caddy ๋•๋ถ„์— ์ธํ”„๋ผ ์„ธํŒ… ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

CaddyNginx
SSL ์ธ์ฆ์„œ์ž๋™ ๋ฐœ๊ธ‰ + ์ž๋™ ๊ฐฑ์‹ certbot ๋ณ„๋„ ์„ค์น˜, cron ๋“ฑ๋ก
์„ค์ • ํŒŒ์ผ2์ค„20์ค„+

3. CI/CD ํŒŒ์ดํ”„๋ผ์ธ

dev ๋ธŒ๋žœ์น˜์— push๋˜๋ฉด CI๊ฐ€ ๋Œ๊ณ , main์— ๋จธ์ง€๋˜๋ฉด ์ž๋™ ๋ฐฐํฌ๋œ๋‹ค.

CI: GitHub Actions๊ฐ€ MySQL 8.0 + Redis ์„œ๋น„์Šค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ง์ ‘ ๋„์›Œ์„œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ฆฐ๋‹ค. Mock์ด ์•„๋‹ˆ๋ผ ์‹ค์ œ DB์— ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆฐ๋‹ค. ํ…Œ์ŠคํŠธ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด PR ๋จธ์ง€๊ฐ€ ์ฐจ๋‹จ๋œ๋‹ค.

CD: bootJar ๋นŒ๋“œ โ†’ Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ โ†’ Docker Hub ํ‘ธ์‹œ(latest + commit SHA ํƒœ๊ทธ) โ†’ SSH๋กœ EC2 ์ ‘์† โ†’ ์ปจํ…Œ์ด๋„ˆ ๊ต์ฒด.

EC2์—์„œ ์ง์ ‘ Gradle ๋นŒ๋“œํ•˜๋ฉด t2.micro(๋ฉ”๋ชจ๋ฆฌ 1GB)๊ฐ€ OOM์œผ๋กœ ์ฃฝ๋Š”๋‹ค. ๊ทธ๋ž˜์„œ GitHub Actions์—์„œ ๋นŒ๋“œํ•ด์„œ ์™„์„ฑ๋œ ์ด๋ฏธ์ง€๋งŒ EC2๋กœ ๋‹น๊ฒจ์˜ค๋Š” ๊ตฌ์กฐ๋ฅผ ํƒํ–ˆ๋‹ค. commit SHA ํƒœ๊ทธ๋ฅผ ๋”ฐ๋กœ ๋ถ™์—ฌ๋‘๋Š” ์ด์œ ๋Š” ๋กค๋ฐฑ์„ ์œ„ํ•ด์„œ๋‹ค. latest๋งŒ ์žˆ์œผ๋ฉด ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ ์–ด๋ ต๋‹ค.

Docker ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋„ ์ ์šฉํ–ˆ๋‹ค. Stage 1(JDK + Gradle)์—์„œ ๋นŒ๋“œํ•˜๊ณ , Stage 2(JRE๋งŒ)์—์„œ jar๋ฅผ ๋ณต์‚ฌํ•ด ์‹คํ–‰ํ•œ๋‹ค. ์ตœ์ข… ์ด๋ฏธ์ง€์— JDK์™€ ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•„์„œ ์ด๋ฏธ์ง€๊ฐ€ ~300MB ๊ฐ€๋ฒผ์›Œ์ง„๋‹ค.

๋ฐฐํฌ ํ๋ฆ„ ์ „์ฒด:

์กฐ์ง ๋ ˆํฌ dev โ†’ main ๋จธ์ง€
    โ†“ (ํฌํฌ ์ž๋™ ๋™๊ธฐํ™”)
๊ฐœ์ธ ํฌํฌ main ์—…๋ฐ์ดํŠธ
    โ†“ (CD ํŠธ๋ฆฌ๊ฑฐ)
GitHub Actions: ๋นŒ๋“œ โ†’ Docker Hub
    โ†“ (SSH)
AWS EC2: pull โ†’ ์ปจํ…Œ์ด๋„ˆ ๊ต์ฒด โ†’ ์™„๋ฃŒ

4. ๊ตฌ์ธ/์ œ์•ˆ ์‹œ์Šคํ…œ

๊ตฌ์ธ๊ธ€์—์„œ ์ œ์•ˆ์„œ ์ˆ˜๋ฝ๊นŒ์ง€ ์ด์–ด์ง€๋Š” ํ๋ฆ„์„ ์„ค๊ณ„ํ–ˆ๋‹ค. ์ œ์•ˆ์„œ๊ฐ€ ์ˆ˜๋ฝ๋˜๋ฉด ์˜ˆ์•ฝ์ด ์ž๋™ ์ƒ์„ฑ๋œ๋‹ค. DB ์ œ์•ฝ๋„ ๊ผผ๊ผผํ•˜๊ฒŒ ๊ฑธ์—ˆ๋‹ค: ๊ตฌ์ธ๊ธ€ ๋™์‹œ ๋“ฑ๋ก ์ตœ๋Œ€ 3๊ฑด, ์ œ์•ˆ์„œ ๋™์‹œ ์ œ์ถœ ์ตœ๋Œ€ 5๊ฑด. ๋งˆ๊ฐ๋œ ๊ตฌ์ธ๊ธ€์€ ์ˆ˜์ • ์ฐจ๋‹จ, proposals ํ…Œ์ด๋ธ”์— (recruit_post_id, freelancer_profile_id) ๋ณตํ•ฉ UNIQUE ํ‚ค๋กœ ์ค‘๋ณต ์ œ์•ˆ์„ ๋ง‰์•˜๋‹ค.


5. ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ

REVIEW/TIP ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋ถ„๋ฆฌ๋œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค. ์†Œํ”„ํŠธ ์‚ญ์ œ(is_deleted)๋ฅผ ์ ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ๋Š” ๋‚จ๊ธฐ๊ณ  ๋…ธ์ถœ๋งŒ ๋„๋Š” ๊ตฌ์กฐ๋‹ค. ํ›„๋ฐ˜์— ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ๊ธฐ๋Šฅ๊ณผ ํ”„๋ฆฌ๋žœ์„œ ์–ธ๊ธ‰ ๊ธฐ๋Šฅ๊นŒ์ง€ ์ถ”๊ฐ€๋๋‹ค.


ํŒ€ ํ˜‘์—…: ์ž˜ ๋œ ๊ฒƒ๋“ค

Git ์ „๋žต์ด ๋‹จ์ˆœํ•˜๊ณ  ๋ช…ํ™•ํ–ˆ๋‹ค. dev ๋ธŒ๋žœ์น˜์—์„œ ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜๋ฅผ ๋”ฐ๊ณ , PR์„ ํ†ตํ•ด ํ•ฉ์ณค๋‹ค. CI๊ฐ€ ๋ถ™์–ด ์žˆ์œผ๋‹ˆ ๊นจ์ง„ ์ฝ”๋“œ๊ฐ€ dev์— ์„ž์ด๋Š” ์ผ์ด ๊ฑฐ์˜ ์—†์—ˆ๋‹ค.

์—ญํ•  ๋ถ„๋ฆฌ๊ฐ€ ๊น”๋”ํ–ˆ๋‹ค. ๋ฐฑ์—”๋“œ 4๋ช…์ด ๋„๋ฉ”์ธ ๋‹จ์œ„๋กœ ๋‚˜๋ˆ ์„œ ์ž‘์—…ํ–ˆ๋Š”๋ฐ, ์ธํ„ฐํŽ˜์ด์Šค(API ์ŠคํŽ™)๋งŒ ๋งž์ถ”๋ฉด ์„œ๋กœ ํฌ๊ฒŒ ์ถฉ๋Œํ•˜์ง€ ์•Š์•˜๋‹ค. ํ”„๋ก ํŠธ๋Š” ์ด๋ฏผ์„œ ๋‹˜์ด ๋””์ž์ธ ์‹œ์Šคํ…œ๊ณผ ๋งˆ์ดํŽ˜์ด์ง€๋ฅผ ๋‹ด๋‹นํ•˜๋ฉด์„œ UI ์ผ๊ด€์„ฑ์„ ์žก์•„์คฌ๋‹ค.

Mock ์—†์ด ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ. CI์—์„œ ์‹ค์ œ MySQL๊ณผ Redis๋ฅผ ๋„์›Œ์„œ ํ…Œ์ŠคํŠธํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— "๋กœ์ปฌ์—์„œ๋Š” ๋๋Š”๋ฐ ์„œ๋ฒ„์—์„œ ์•ˆ ๋จ" ๊ฐ™์€ ์ƒํ™ฉ์ด ํ›จ์”ฌ ์ค„์—ˆ๋‹ค.


์•„์‰ฌ์šด ๊ฒƒ๋“ค

t2.micro์˜ ํ•œ๊ณ„. ๋ฉ”๋ชจ๋ฆฌ 1GB๋กœ MySQL + Redis + Spring Boot๋ฅผ ๋™์‹œ์— ๋Œ๋ฆฌ๋‹ˆ ๊ฐ€๋” OOM์ด ๋‚ฌ๋‹ค. Swap 2GB๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๊ฒจ์šฐ ๋ฒ„ํ…ผ๋Š”๋ฐ, ์‹ค์ œ ์„œ๋น„์Šค๋ผ๋ฉด ์ธ์Šคํ„ด์Šค ์ŠคํŽ™์„ ์˜ฌ๋ ค์•ผ ํ•œ๋‹ค.

ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€. CI์—์„œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ฆฌ๊ธด ํ–ˆ์ง€๋งŒ, ์ž‘์„ฑ๋œ ํ…Œ์ŠคํŠธ์˜ ์–‘์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์•˜๋‹ค. ๋น ๋ฅด๊ฒŒ ๊ธฐ๋Šฅ์„ ๋งŒ๋“œ๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๋‹ค ๋ณด๋‹ˆ ์—ฃ์ง€ ์ผ€์ด์Šค ํ…Œ์ŠคํŠธ๊ฐ€ ๋ถ€์กฑํ–ˆ๋‹ค.

AI ๊ธฐ๋Šฅ๊ณผ ์ฑ„ํŒ…์ด ํ›„์ˆœ์œ„๋กœ ๋ฐ€๋ ธ๋‹ค. ์›๋ž˜ MVP ์šฐ์„ ์ˆœ์œ„์—์„œ ํ•˜์œ„์˜€๋˜ ๊ธฐ๋Šฅ๋“ค์ด ๋งˆ์ง€๋ง‰์— ๋ถ™์—ˆ๋‹ค. ์™„์„ฑ์€ ๋์ง€๋งŒ ๋” ๋‹ค๋“ฌ์„ ์‹œ๊ฐ„์ด ์—†์—ˆ๋‹ค.

๋ฐฐํฌ ์ž๋™ํ™”์˜ ๋นˆํ‹ˆ. ์กฐ์ง ๋ ˆํฌ โ†’ ๊ฐœ์ธ ํฌํฌ ๋™๊ธฐํ™”๋ฅผ GitHub Actions๋กœ ์ž๋™ํ™”ํ–ˆ๋Š”๋ฐ, ๊ฐ„ํ˜น sync๊ฐ€ ๋Šฆ๊ฑฐ๋‚˜ ์‹คํŒจํ•˜๋Š” ์ผ€์ด์Šค๊ฐ€ ์žˆ์—ˆ๋‹ค. ๋” ๊ฒฌ๊ณ ํ•œ ํŒŒ์ดํ”„๋ผ์ธ์ด ํ•„์š”ํ•˜๋‹ค.


๋ฐฐ์šด ๊ฒƒ

2์ฃผ๋Š” ์ƒ๊ฐ๋ณด๋‹ค ํ›จ์”ฌ ์งง๋‹ค. ๊ธฐ๋Šฅ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์™„๋ฒฝํ•˜๊ฒŒ ๋งŒ๋“ค๋ ค๊ณ  ํ•˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์™„์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค. MVP ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•˜๊ณ , ํ•ต์‹ฌ์ด ์•„๋‹Œ ๊ฒƒ์€ ๊ณผ๊ฐํ•˜๊ฒŒ ๋’ค๋กœ ๋ฏธ๋ฃจ๋Š” ํŒ๋‹จ์ด ์ค‘์š”ํ–ˆ๋‹ค.

์ธ์ฆ ์‹œ์Šคํ…œ์€ ํ”„๋กœ์ ํŠธ ์ดˆ๋ฐ˜์— ์™„์„ฑ๋„ ์žˆ๊ฒŒ ์„ค๊ณ„ํ•ด๋‘๊ธธ ์ž˜ํ–ˆ๋‹ค. ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ์ธ์ฆ์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๊ฒŒ ๋ถˆ์•ˆ์ •ํ•˜๋ฉด ํŒ€ ์ „์ฒด๊ฐ€ ํ”๋“ค๋ฆฐ๋‹ค.

Caddy๋Š” ์ •๋ง ์ข‹์€ ๋„๊ตฌ๋‹ค. ๋‹จ, ACME ์ฑŒ๋ฆฐ์ง€๋ฅผ ์œ„ํ•ด 80ํฌํŠธ๊ฐ€ ์—ด๋ ค ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฑธ ์ฒ˜์Œ์— ๋ชฐ๋ผ์„œ ์‚ฝ์งˆํ–ˆ๋‹ค.

CI/CD๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ตฌ์„ฑํ•ด๋‘” ๊ฒŒ ํŒ€ ์ „์ฒด ์ƒ์‚ฐ์„ฑ์— ํฌ๊ฒŒ ๊ธฐ์—ฌํ–ˆ๋‹ค. ์ˆ˜๋™์œผ๋กœ ๋ฐฐํฌํ•˜๋А๋ผ ์‹œ๊ฐ„์„ ์“ฐ์ง€ ์•Š์•„๋„ ๋๊ณ , ํ…Œ์ŠคํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋Œ์•„๊ฐ€๋‹ˆ ์„œ๋กœ ์ฝ”๋“œ๋ฅผ ํ•ฉ์น˜๋Š” ๋ฐ ๋œ ๋ถˆ์•ˆํ–ˆ๋‹ค.


๋งˆ๋ฌด๋ฆฌ

2์ฃผ ์•ˆ์— ์ด ์ •๋„ ๊ทœ๋ชจ์˜ ์„œ๋น„์Šค๋ฅผ ์™„์„ฑํ•œ ๊ฒŒ ์‹ ๊ธฐํ•˜๊ฒŒ ๋А๊ปด์ง„๋‹ค. ํŒ€์› ๊ฐ์ž๊ฐ€ ๋งก์€ ์˜์—ญ์„ ๋๊นŒ์ง€ ์ฑ…์ž„์กŒ๊ณ , ๋•๋ถ„์— ๋ฐฐํฌ URL์ด ์‹ค์ œ๋กœ ๋Œ์•„๊ฐ„๋‹ค.

๋‹ค์Œ์—๋Š” ํ…Œ์ŠคํŠธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ฑ™๊ธฐ๋ฉด์„œ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค.


GitHub | ๋ฐฐํฌ URL | ์‹œ์—ฐ ์˜์ƒ

โ† ๋ชฉ๋ก์œผ๋กœ
๋ฐ๋ธŒ์ฝ”์Šค๋ฐฑ์—”๋“œ๋ถ€ํŠธ์บ ํ”„ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค