๐ Alpha-Helix ๋ฐฐํฌ ์ฌ์ โ ์ฒ์ ๋ฐฐ์ฐ๋ ์ฌ๋์ ์ํ ์ ์ฒด ์ ๋ฆฌ
๋ก์ปฌ์์ ๋๋ ์น์ฑ์ ์ง์ง ์ธํฐ๋ท ์ฃผ์(
https://quant-alphahelix.com) ๋ก ๋์ฐ๊ธฐ๊น์ง.
Docker ยท AWS ยท ๋๋ฉ์ธ ยท HTTPS ยท ๊ตฌ๊ธ ๋ก๊ทธ์ธ ยท ์๋๋ฐฐํฌ(CI/CD) ๋ฅผ ํ๋์ฉ.
๐บ๏ธ ํฐ ๊ทธ๋ฆผ โ ์ฐ๋ฆฌ๊ฐ ๋ง๋ ๊ฒ
3๊ฐ์ ํ๋ก๊ทธ๋จ์ด ํ๋ ฅํ๋ ์น์๋น์ค์์:
[๋ธ๋ผ์ฐ์ ] โ (์ธํฐ๋ท) โ [ํ๋ก ํธ์๋(React)] โ [๋ฐฑ์๋(Spring Boot)] โ [DB(MySQL)]
โ [๋ถ์์๋ฒ(FastAPI, ํ์ด์ฌ)]์ด๊ฑธ ๋ด ๋ ธํธ๋ถ์ด ์๋๋ผ 24์๊ฐ ์ผ์ง ์๋ฒ(AWS EC2) ์ ์ฌ๋ ค์, ๋๊ตฌ๋ ์ฃผ์๋ก ์ ์ํ๊ฒ ๋ง๋๋ ๊ฒ "๋ฐฐํฌ"์์.
1๏ธโฃ Docker โ "๋ด ์ปดํจํฐ์์ ๋๋๋ฐ?" ๋ฅผ ์์ ๋ ๋์๋ฝ
๋ฌธ์ : ํ๋ก๊ทธ๋จ์ OSยท๋ฒ์ ยท์ค์ ์ด ์กฐ๊ธ๋ง ๋ฌ๋ผ๋ ์ ๋์๊ฐ์. ๋ด ๋ ธํธ๋ถ์์ ๋๋๋ฐ ์๋ฒ์์ ์ ๋๋ ์ผ์ด ํํ์ฃ .
Docker = ํ๋ก๊ทธ๋จ + ํ์ํ ํ๊ฒฝ์ ํต์งธ๋ก "๋์๋ฝ(์ด๋ฏธ์ง)"์ ๋ด๋ ๊ธฐ์ . ๊ทธ ๋์๋ฝ์ ์ด๋์ ์ด๋ ๋๊ฐ์ด ๋์๊ฐ์.
- ์ด๋ฏธ์ง(Image) = ๋์๋ฝ (๋ ์ํผ๋๋ก ๋ง๋ ๊ฒฐ๊ณผ๋ฌผ)
- ์ปจํ ์ด๋(Container) = ๊ทธ ๋์๋ฝ์ ์ค์ ๋ก ๋ฐ์ ๋จน๋ ๊ฒ(์คํ ์ค์ธ ์ํ)
Dockerfile= ๋์๋ฝ ๋ง๋๋ ๋ ์ํผdocker-compose.yml= ์ฌ๋ฌ ๋์๋ฝ(์ฐ๋ฆฌ๋ 4๊ฐ: dbยทbackendยทanalyticsยทfrontend)์ ํ ๋ฒ์ ์ฐจ๋ฆฌ๋ ์์ฐจ๋ฆผํ
์ฐ๋ฆฌ๊ฐ ํ ์ผ: 4๊ฐ ์๋น์ค์ Dockerfile + compose ์์ฑ โ
docker compose up -d --build # ํ ์ค๋ก ์ ์ฒด ์คํ ๊ธฐ๋
ํ ๋ฐฉ์ ์ ๋ถ ๋จ๊ฒ ๋ง๋ค์์ด์. (๋ฐฑ์๋ ๋์๋ฝ ์์ Claude CLI๋ ๊ฐ์ด ๋ฃ์ด์, BYOK ํค๋ง ์์ผ๋ฉด AI๊ฐ ์ฝ๋ ํธ์ง๊น์ง ํจ)
๐ก ๋ฐฐ์ด ์ : Docker๋ "ํ ๋ฒ ๋ง๋ค๋ฉด ์ด๋์๋ ๋๊ฐ์ด"๊ฐ ํต์ฌ. ๋ฐฐํฌ์ ํ๊ฒฝ ์ฐจ์ด ๋ฌธ์ ๋ฅผ ํต์งธ๋ก ์์ ์ค์.
2๏ธโฃ ๋ก์ปฌ์์ ๋จผ์ ๊ฒ์ฆ โ ๊ทธ๋ฆฌ๊ณ ๋ง๋ ๋ฒ๊ทธ๋ค
์๋ฒ์ ์ฌ๋ฆฌ๊ธฐ ์ ์ ๋ด ๋ ธํธ๋ถ์ Docker์์ ๋จผ์ ๋์๋ดค์ด์. ์ฌ๊ธฐ์ ์ง์ง ๋ฌธ์ ๋ค์ ์ก์์ฃ .
๐ ๋ฌธ์ โ : ๋ฐฑ์๋๊ฐ DB์ ์ฐ๊ฒฐ ๋ชป ํจ (Access denied for user 'root')
- ์ฆ์: ๋ฐฑ์๋๊ฐ ์๊พธ ์ฌ์์, DB ์ ์ ์คํจ.
- ์ถ์ : ๋ถ๋ช
์ค์ ์
alpha์ ์ ์ธ๋ฐ ๋ฐํ์์root๋ก ์ ์. ํธ์คํธ๋db๊ฐ ์๋๋ผlocalhost๋ก ํ๋ฆผ. - ์ง์ง ์์ธ(์ค์!):
application-local.properties(๋ด ๋ก์ปฌ ์ ์ฉ ์ค์ โ ๋ก์ปฌ DB๋ root/๋น๋ฒ, ๊ฒ๋ค๊ฐ ์ค์ ์ด๋ฉ์ผ๊น์ง ์ ํ์์)๊ฐ Docker ์ด๋ฏธ์ง ์์ ๊ฐ์ด ๋ค์ด๊ฐ ๋ฒ๋ ค์, ์๋ฒ์ฉ ์ค์ ์ ๋ฎ์ด์ฐ๊ณ ์์์ด์. - ํด๊ฒฐ:
.dockerignore์ ๊ทธ ํ์ผ์ ์ถ๊ฐํด ์ด๋ฏธ์ง์์ ๋ฐฐ์ . - ๐ก ์ด๊ฑด ๋ณด์ ๋ฌธ์ ์ด๊ธฐ๋ ํด์. ๋ก์ปฌ ๋น๋ฒยท์ด๋ฉ์ผ์ด ๋ฐฐํฌ๋ฌผ์ ์์ด ๋ค์ด๊ฐ๋ฉด ์ ๋๋๊น. ํ ๋ฐฉ์ ๊ธฐ๋ฅ+๋ณด์ ๋ ๋ค ํด๊ฒฐ.
๐ ๋ฌธ์ โก: ํ์๊ฐ์ ์ด 500 ์๋ฌ (CORS)
- ์์ธ: "์๋ฌด ์ถ์ฒ๋ ํ์ฉ(
*)" + "์ฟ ํค ์ธ์ฆ ํ์ฉ"์ ๋์์ ์ผ๋ฉด ์ ๋๋ค๊ณ ๋ธ๋ผ์ฐ์ ๊ท์น์ด ๋ง์์. - ํด๊ฒฐ:
*์ผ ๋allowedOriginPatterns๋ฐฉ์์ ์ฐ๋๋ก ์ฝ๋ ์์ . (์ฟ ํค๋ SameSite=Lax๋ผ CSRF๋ ๋ฐ๋ก ๋ฐฉ์ด๋จ)
๐ก ๋ฐฐ์ด ์ : ๋ก์ปฌ์์ ๋จผ์ ๋๋ ค๋ณด๋ฉด ์ด๋ฐ ๋ฒ๊ทธ๋ฅผ ์๋ฒ ์ฌ๋ฆฌ๊ธฐ ์ ์ ์ก์ ์ ์์ด์. "๋ก์ปฌ ๊ฒ์ฆ โ ์๋ฒ ๋ฐฐํฌ" ์์๊ฐ ์ค์.
3๏ธโฃ AWS EC2์ ์ฌ๋ฆฌ๊ธฐ โ "๋จ์ ์ปดํจํฐ(ํด๋ผ์ฐ๋)"์ ์ ์
EC2 = AWS๊ฐ ๋น๋ ค์ฃผ๋ 24์๊ฐ ์ผ์ง ์ปดํจํฐ(์๋ฒ).
SSH โ ๋ด PC์์ ๊ทธ ์๋ฒ๋ก ์๊ฒฉ ์ ์
ssh -i "C:\...\who-a.pem" ec2-user@<์๋ฒIP>
who-a.pem= ์๋ฒ ๋ฌธ ์ฌ๋ ์ด์ ํ์ผ(์ธ์คํด์ค ๋ง๋ค ๋ ๋ฐ์)ec2-user= ์๋ฒ์ ๋ก๊ทธ์ธ ์ด๋ฆ(Amazon Linux ๊ธฐ๋ณธ๊ฐ)- ์ ์๋๋ฉด ํ๋กฌํํธ๊ฐ
[ec2-user@...]$๋ก ๋ฐ๋ = ์ด์ ๋ถํฐ ๋ช ๋ น์ "์๋ฒ ์์์" ์คํ
๐ ๋ง๋ ๊ฒ: ์๋์ฐ์์
.pem๊ถํ์ด ๋๋ฌด ์ด๋ ค์ SSH๊ฐ ๊ฑฐ๋ถ โicacls๋ก "๋๋ง ์ฝ๊ธฐ"๋ก ์ ๊ทธ๋ ํด๊ฒฐ.
์๋ฒ์์ ํ ์ผ (์์๋๋ก)
- ์ ์๋น์ค ์ ์ง (ํฌํธ 80 ๋น์ฐ๊ธฐ) + ์ค์ ๋ฉ๋ชจ๋ฆฌ (๋น๋ ์ค ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ๋ฐฉ์ง)
- Docker ์ค์น
- ์ฝ๋ ๋ฐ๊ธฐ (
git clone) โ ๋น๊ณต๊ฐ repo๋ผ GitHub ํ ํฐ(PAT) ํ์ .env๋ง๋ค๊ธฐ โ ๋น๋ฐํค๋ค์openssl rand๋ก ์๋ ์์ฑdocker compose up -d --buildโ ๋์๋ฝ 4๊ฐ ๋น๋+๊ธฐ๋
๐ ๋ง๋ ๊ฒ:
compose build requires buildx 0.17+โ ์๋ฒ์ ๋น๋ ๋๊ตฌ(buildx)๊ฐ ๊ตฌ๋ฒ์ โ ์ต์ buildx ๋ฐ์ ํด๊ฒฐ.
โ
๊ฒฐ๊ณผ: http://<์๋ฒIP> ๋ก ์ฌ์ดํธ๊ฐ ๋ด์ด์!
4๏ธโฃ "๋ก๊ทธ์ธ์ด ์ ๋ผ!" โ HTTP(๋น๋ณด์ ์ฃผ์) ํน์ ์ ํจ์ 2๊ฐ
์ฌ์ดํธ๋ ๋ด๋๋ฐ ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ํฌ๋์. ์์ธ์ด http://(๋ณด์ ์ ๋ ์ฃผ์) ๋ผ์ ์๊ธฐ๋ ๊ฒ๋ค์ด์์ด์.
๐ ํจ์ โ : crypto.randomUUID is not a function
- ์ด ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฅ์ HTTPS๋ localhost์์๋ง ์กด์ฌํด์.
http://๊ณต์ธIP์์ ์์ด์ ํธ์ถ ์ฆ์ ํ์ด์ง๊ฐ ํฐ์ง. - ํด๊ฒฐ: ์์ผ๋ฉด ๋์ฒด๋ก ์ฑ์์ฃผ๋ ํด๋ฆฌํ์ ์ง์
์ (
main.jsx)์ ์ถ๊ฐ.
๐ ํจ์ โก: Missing required parameter client_id (๊ตฌ๊ธ)
- ๊ตฌ๊ธ ๋ก๊ทธ์ธ ํค๊ฐ ๋น๋์ ์์ด์, ๊ตฌ๊ธ OAuth ์ด๊ธฐํ๊ฐ ๋ ๋ ์ค ํฐ์ง.
- ํด๊ฒฐ: ํค ์์ผ๋ฉด ํฌ๋์๋ง ๋ง๊ณ (๋๋ฏธ๊ฐ) ์์ ๋ฒํผ์ ์จ๊น โ ์ด๋ฉ์ผ ๊ฐ์ ๋ง ๊น๋ํ ๋ ธ์ถ.
๐ก ๋ฐฐ์ด ์ : "๋ก์ปฌ(localhost)์์ ๋๋๋ฐ ๋ฐฐํฌ์์ ์ ๋๋" ๊ฑด ๋ณดํต HTTPSยทํ๊ฒฝ๋ณ์ ์ฐจ์ด ๋๋ฌธ. ์ด๊ฒ ๋ฐฐํฌ์ ๋จ๊ณจ ํจ์ ์ด์์.
โ ์ฌ๊ธฐ๊น์ง: ์ด๋ฉ์ผ ํ์๊ฐ์ ยท๋ก๊ทธ์ธ ์ ์ ์๋!
5๏ธโฃ ๋๋ฉ์ธ + HTTPS โ ์ง์ง ์ฃผ์ + ์๋ฌผ์ ๐
http://์ซ์IP๋ ๋ชป์๊ธฐ๊ณ , ๊ตฌ๊ธ ๋ก๊ทธ์ธ๋ ์ ๋ฐ์์ค์(๊ตฌ๊ธ์ https://๋๋ฉ์ธ๋ง ํ์ฉ). ๊ทธ๋์:
โ Elastic IP โ ์๋ฒ IP๋ฅผ "์๊ตฌ ๊ณ ์ "
- EC2์ IP๋ ์๋ฒ๋ฅผ ๊ป๋ค ์ผ๋ฉด ๋ฐ๋์ด์. ๋๋ฉ์ธ์ ๋ถ์ฌ๋ ์ฌ์์ํ๋ฉด ๊นจ์ง.
- AWS์์ Elastic IP(๊ณ ์ IP) ๋ฅผ ํ ๋น โ ์ธ์คํด์ค์ ์ฐ๊ฒฐ โ IP๊ฐ ์๊ตฌ ๊ณ ์ .
โก ๋๋ฉ์ธ ๊ตฌ๋งค + DNS ์ฐ๊ฒฐ (Cloudflare)
quant-alphahelix.com๊ตฌ๋งค โ Cloudflare์ ๋ฑ๋ก- DNS A ๋ ์ฝ๋: ๋๋ฉ์ธ โ Elastic IP (์ด๊ฒ "์ ํ๋ฒํธ๋ถ": ๋๋ฉ์ธ ์ ๋ ฅํ๋ฉด ์ด IP๋ก ๋ณด๋ด์ค)
- ํ๋ก์ ON(์ฃผํฉ ๊ตฌ๋ฆ): ํธ๋ํฝ์ด Cloudflare๋ฅผ ๊ฑฐ์ณ๊ฐ โ ๋ณด์ยท์บ์ฑยท๋ฌด๋ฃ HTTPS ์ ๊ณต
โข HTTPS ์ผ๊ธฐ (Cloudflare Flexible)
- Cloudflare SSL/TLS ๋ชจ๋๋ฅผ Flexible๋ก.
- โ ๋ฐฉ๋ฌธ์โCloudflare๋ HTTPS(์๋ฌผ์ ), Cloudflareโ์ฐ๋ฆฌ์๋ฒ๋ HTTP. ์๋ฒ์ ์ธ์ฆ์ ์ค์น 0์ผ๋ก https ์์ฑ.
๐ก ์ฉ์ด: DNS = ๋๋ฉ์ธโIP ์ ํ๋ฒํธ๋ถ ยท SSL/TLS = ํต์ ์ํธํ(์๋ฌผ์ ) ยท ํ๋ก์ = ์ค๊ฐ์์ ๋์ ๋ฐ์์ฃผ๋ ๋ฌธ์ง๊ธฐ.
โ
https://quant-alphahelix.com ์ผ๋ก ์๋ฌผ์ ๐ ๋ฌ๊ณ ์ ์!
6๏ธโฃ ๊ตฌ๊ธ ๋ก๊ทธ์ธ ์ผ๊ธฐ
์ด์ https ๋๋ฉ์ธ์ด ์๊ฒผ์ผ๋ ๊ตฌ๊ธ์ด ๋ฐ์์ค์.
- ๊ตฌ๊ธ ํด๋ผ์ฐ๋ ์ฝ์ โ OAuth ๋์ ํ๋ฉด + OAuth ํด๋ผ์ด์ธํธ ID ๋ฐ๊ธ
- ์น์ธ๋ JavaScript ์๋ณธ์
https://quant-alphahelix.com๋ฑ๋ก (โ "์ด ์ฃผ์์์ ์ค๋ ๊ตฌ๊ธ ๋ก๊ทธ์ธ๋ง ํ๋ฝ") - ๋ฐ๊ธ๋ ํด๋ผ์ด์ธํธ ID(
...apps.googleusercontent.com)๋ฅผ ๋น๋์ ์ฃผ์- frontend Dockerfile์ด
VITE_GOOGLE_CLIENT_ID๋น๋ ์ธ์๋ฅผ ๋ฐ๊ฒ ์์ โ.env์ ํค ๋ฃ๊ณ ์ฌ๋น๋
- frontend Dockerfile์ด
- โ ๊ตฌ๊ธ ๋ฒํผ์ด ๋ํ๋๊ณ , ์ง์ง ๊ตฌ๊ธ ๋ก๊ทธ์ธ ์๋!
๐ก OAuth = "๊ตฌ๊ธํํ ๋ก๊ทธ์ธ ๋์ ์ํค๊ณ , ๊ตฌ๊ธ์ด '์ด ์ฌ๋ ๋ง์' ํ์ธํด์ฃผ๋" ๋ฐฉ์. ํค(client_id)๋ก ์ฐ๋ฆฌ ์ฑ์ ์๋ณํด์.
7๏ธโฃ CI/CD ์๋๋ฐฐํฌ โ git push ํ๋๋ฉด ๋ ๐ค
๋งค๋ฒ ์๋ฒ ๋ค์ด๊ฐ์ git pull + ๋น๋ ํ๋ ์์์
์ ๋ก๋ด์ด ๋์ :
- CI/CD = ์ฝ๋ ์ฌ๋ฆฌ๋ฉด ์๋์ผ๋ก ๋น๋ยท๊ฒ์ฌยท๋ฐฐํฌ๊น์ง ํด์ฃผ๋ ์ปจ๋ฒ ์ด์ด๋ฒจํธ
- GitHub Actions = GitHub์ด ๊ณต์ง๋ก ์ฃผ๋ ๊ทธ ๋ก๋ด.
.github/workflows/deploy.yml์ "ํ ์ผ"์ ์ ์ด๋ - ์ฐ๋ฆฌ ๋ก๋ด์ ์ผ: "flow_finish์ push ๋ค์ด์ค๋ฉด โ ์์ ์ปดํจํฐ๊ฐ EC2์ SSH ์ ์ โ
git pull+docker ์ฌ๋น๋" - ํ์ํ ๊ฒ: GitHub Secrets 3๊ฐ (
EC2_HOSTยทEC2_USERยทEC2_SSH_KEY)์ ์๋ฒ ์ ์์ ๋ณด ๋ฑ๋ก
โ
์ด์ git push ํ๋๋ฉด ์๋ฒ๊ฐ ์์์ ์ต์ ํ๋ผ์.
๐ ํต์ฌ ์ฉ์ด ์ฌ์ (ํ ์ค ์ ๋ฆฌ)
| ์ฉ์ด | ํ ์ค ์ค๋ช |
|---|---|
| Docker | ํ๋ก๊ทธ๋จ+ํ๊ฒฝ์ ๋์๋ฝ(์ด๋ฏธ์ง)์ ๋ด์ ์ด๋์๋ ๋๊ฐ์ด ์คํ |
| ์ด๋ฏธ์ง / ์ปจํ ์ด๋ | ๋์๋ฝ / ๋ฐ์ ๋จน๋ ์ค(์คํ ์ํ) |
| ๋ณผ๋ฅจ(Volume) | ์ปจํ ์ด๋๊ฐ ์ฃฝ์ด๋ ๋ฐ์ดํฐ(DB ๋ฑ)๋ฅผ ๋ณด์กดํ๋ ์ ์ฅ๊ณต๊ฐ |
| EC2 | AWS๊ฐ ๋น๋ ค์ฃผ๋ 24์๊ฐ ์๋ฒ |
| Elastic IP | ์ฌ์์ํด๋ ์ ๋ฐ๋๋ ๊ณ ์ IP |
| SSH | ๋ด PC์์ ์๋ฒ๋ก ์๊ฒฉ ์ ์(์ด์ =.pem) |
| DNS / A๋ ์ฝ๋ | ๋๋ฉ์ธโIP ์ ํ๋ฒํธ๋ถ |
| HTTPS / SSL | ํต์ ์ํธํ(๋ธ๋ผ์ฐ์ ์๋ฌผ์ ๐) |
| ํ๋ก์(Cloudflare) | ํธ๋ํฝ์ ์ค๊ฐ์์ ๋ฐ์ ๋ณด์ยทHTTPSยท์บ์ฑ ์ ๊ณต |
| OAuth | ๊ตฌ๊ธ/๊นํ ๊ฐ์ ์ธ๋ถ ๊ณ์ ์ผ๋ก ๋ก๊ทธ์ธํ๋ ๋ฐฉ์ |
| PAT | GitHub ๋น๊ณต๊ฐ ์ ๊ทผ์ฉ ํ ํฐ(๋น๋ฒ ๋์ฉ) |
| CI/CD | pushํ๋ฉด ์๋ ๋น๋ยท๋ฐฐํฌํด์ฃผ๋ ์๋ํ |
| ๋ฒ์คํฐ๋ธ(t3) | ํ์ ์ ์ ๋ ฅ, ์ ๊น๋ง ๊ณ ์ฑ๋ฅ. ์ค๋ ๋ฌด๊ฑฐ์ฐ๋ฉด ๋๋ ค์ง(ํฌ๋ ๋ง ์์ง) |
๐ฏ ํ ์ค ํ๊ณ
์ฒ์์ "๋ก์ปฌ์์ ๋๋ ๊ฑธ ๊ทธ๋ฅ ์ฌ๋ฆฌ๋ฉด ๋๊ฒ ์ง" ์์ง๋ง, ์ค์ ๋ก
ํ๊ฒฝ ์ฐจ์ด(Docker) โ ์ํฌ๋ฆฟ ๋์ถ(.dockerignore) โ HTTP ํจ์ (cryptoยทOAuth) โ ๊ณ ์ IPยท๋๋ฉ์ธยทHTTPS โ ์ธ๋ถ๋ก๊ทธ์ธ โ ์๋ํ
์์๋ก ํ๋์ฉ ํ์ด์ผ ํ์ด์. ๊ฐ ๋จ๊ณ๋ "์ ํ์ํ๊ฐ"๋ฅผ ์๋ฉด ์ ๋ฌด์์์. ๋งํ๋ ์๋ฌ๋ ๋๋ถ๋ถ ๋ก๊ทธ ํ ์ค์ ๋ต์ด ์๊ณ ์.
์ด์ ์ฐ๋ฆฌ ์๋น์ค๋ ์ง์ง ์ธํฐ๋ท์ ์ด์์์ต๋๋ค. ๐โจ
'๐ฉโ๐ปDeveloper ๐ก' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| ์๋ ์์คํ ์ค๊ณ (0) | 2026.06.20 |
|---|---|
| ํค-๊ฐ ์ ์ฅ์ ์ค๊ณ (0) | 2026.06.20 |
| ah/backend (0) | 2026.06.02 |
| ํ๋ก์ ํธ2 ์ฌ๋ฅ ๋ฐ ํ๋ฆฌ๋์ ๋งค์นญ ํ๋ซํผ ๊ธฐํ๋ถํฐ ์ค๊ณ ๋ฐ ๊ฐ๋ฐ (0) | 2026.03.08 |
| ํ์ค์ ์ผ๋ก ์ด์ง ๊ฐ๋ฅํด. (0) | 2026.02.02 |
