angple-backend

module
v0.0.0-...-500fbbb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: MIT

README ยถ

Angple Backend

Go Version Fiber License

๋‹ค๋ชจ์•™(damoang.net) ์ปค๋ฎค๋‹ˆํ‹ฐ ์ฐจ์„ธ๋Œ€ ๋ฐฑ์—”๋“œ API ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด PHP ์‹œ์Šคํ…œ์„ Go๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜์—ฌ 800ms โ†’ 50ms ์ดํ•˜์˜ ์‘๋‹ต ์†๋„๋ฅผ ๋ชฉํ‘œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.


๐Ÿš€ Quick Start

๋ฐฉ๋ฒ• 1: Docker All-in-One (๊ถŒ์žฅ โญ)

MySQL + Redis + API๋ฅผ ํ•œ ๋ฒˆ์— ์‹คํ–‰ํ•˜๋Š” ์™„์ „ํ•œ ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ:

# ์ „์ฒด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์‹œ์ž‘
make dev-docker

# ๋กœ๊ทธ ํ™•์ธ
make dev-docker-logs

# ์ค‘์ง€
make dev-docker-down

์ž๋™ ์‹คํ–‰ ํ•ญ๋ชฉ:

  • MySQL (ํฌํŠธ 3306)
  • Redis (ํฌํŠธ 6379)
  • API ์„œ๋ฒ„ (ํฌํŠธ 8081)
๋ฐฉ๋ฒ• 2: ๋กœ์ปฌ ์ง์ ‘ ์‹คํ–‰
# 1. MySQL + Redis๋งŒ ์‹คํ–‰
docker-compose up -d

# 2. ํ™˜๊ฒฝ ์„ค์ •
cp .env.example .env

# 3. API ์„œ๋ฒ„ ์‹คํ–‰
make dev
# ๋˜๋Š”
go run cmd/api/main.go

์„œ๋ฒ„ ํ™•์ธ:

curl http://localhost:8081/health
# {"status":"ok","time":1734163200}

๐Ÿ“– ์ƒ์„ธ ๊ฐ€์ด๋“œ: ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •


โœจ ์ฃผ์š” ๊ธฐ๋Šฅ

โœ… ๊ตฌํ˜„ ์™„๋ฃŒ (Production Ready)
๊ธฐ๋Šฅ ์„ค๋ช… ์—”๋“œํฌ์ธํŠธ
์ธ์ฆ JWT + ๋ ˆ๊ฑฐ์‹œ SSO ํ†ตํ•ฉ /api/v2/auth/*
๊ฒŒ์‹œ๊ธ€ CRUD, ๊ฒ€์ƒ‰, ํŽ˜์ด์ง€๋„ค์ด์…˜ /api/v2/boards/{id}/posts
๋Œ“๊ธ€ ๊ณ„์ธตํ˜• ๋Œ“๊ธ€ ์‹œ์Šคํ…œ /api/v2/boards/{id}/posts/{id}/comments
๋ฉ”๋‰ด ๋™์  ๋ฉ”๋‰ด ๊ด€๋ฆฌ (ํ—ค๋”/์‚ฌ์ด๋“œ๋ฐ”) /api/v2/menus/*
์ถ”์ฒœ๊ธ€ ์บ์‹œ ๊ธฐ๋ฐ˜ ์ถ”์ฒœ ๊ฒŒ์‹œ๋ฌผ /api/v2/recommended/{period}
๐Ÿšง ๊ฐœ๋ฐœ ์˜ˆ์ • (Roadmap)
  • ํŒŒ์ผ ์—…๋กœ๋“œ (์ด๋ฏธ์ง€ ๋ฆฌ์‚ฌ์ด์ง•)
  • ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ (WebSocket)
  • ํ†ตํ•ฉ ๊ฒ€์ƒ‰ (ElasticSearch)
  • ํˆฌํ‘œ/์„ค๋ฌธ ์‹œ์Šคํ…œ
  • ๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ

๐Ÿ“‹ ์ „์ฒด ๋กœ๋“œ๋งต: docs/api-roadmap.csv


๐Ÿ“ก API ๋ฌธ์„œ

Swagger UI (์ถ”์ฒœ โญ)
# Swagger UI ์‹คํ–‰
docker run -p 8082:8080 \
  -e SWAGGER_JSON=/docs/swagger.yaml \
  -v $(pwd)/docs:/docs \
  swaggerapi/swagger-ui

# ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ‘์†
open http://localhost:8082
์ฃผ์š” ์—”๋“œํฌ์ธํŠธ
๐Ÿ“Œ ์ธ์ฆ (Authentication)
๋ฉ”์„œ๋“œ ๊ฒฝ๋กœ ์ธ์ฆ ์„ค๋ช…
POST /api/v2/auth/login โŒ ๋กœ๊ทธ์ธ (JWT ๋ฐœ๊ธ‰)
POST /api/v2/auth/refresh โŒ ํ† ํฐ ์žฌ๋ฐœ๊ธ‰
GET /api/v2/auth/me ๐Ÿช Cookie ํ˜„์žฌ ์‚ฌ์šฉ์ž (SSO)
GET /api/v2/auth/profile โœ… JWT ์‚ฌ์šฉ์ž ํ”„๋กœํ•„

๋กœ๊ทธ์ธ ์˜ˆ์ œ:

curl -X POST http://localhost:8081/api/v2/auth/login \
  -H "Content-Type: application/json" \
  -d '{"user_id":"testuser","password":"password123"}'
๐Ÿ“ ๊ฒŒ์‹œ๊ธ€ (Posts)
๋ฉ”์„œ๋“œ ๊ฒฝ๋กœ ์ธ์ฆ ์„ค๋ช…
GET /api/v2/boards/{board_id}/posts โŒ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก
GET /api/v2/boards/{board_id}/posts/search โŒ ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰
GET /api/v2/boards/{board_id}/posts/{id} โŒ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ
POST /api/v2/boards/{board_id}/posts โœ… ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ
PUT /api/v2/boards/{board_id}/posts/{id} โœ… ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •
DELETE /api/v2/boards/{board_id}/posts/{id} โœ… ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ์˜ˆ์ œ:

curl -X POST http://localhost:8081/api/v2/boards/free/posts \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{"title":"์ œ๋ชฉ","content":"๋‚ด์šฉ"}'
๐Ÿ’ฌ ๋Œ“๊ธ€ (Comments)
๋ฉ”์„œ๋“œ ๊ฒฝ๋กœ ์ธ์ฆ ์„ค๋ช…
GET /api/v2/boards/{board_id}/posts/{post_id}/comments โŒ ๋Œ“๊ธ€ ๋ชฉ๋ก
POST /api/v2/boards/{board_id}/posts/{post_id}/comments โœ… ๋Œ“๊ธ€ ์ž‘์„ฑ
PUT /api/v2/boards/{board_id}/posts/{post_id}/comments/{id} โœ… ๋Œ“๊ธ€ ์ˆ˜์ •
DELETE /api/v2/boards/{board_id}/posts/{post_id}/comments/{id} โœ… ๋Œ“๊ธ€ ์‚ญ์ œ
๐Ÿ“‚ ๋ฉ”๋‰ด (Menus)
๋ฉ”์„œ๋“œ ๊ฒฝ๋กœ ์ธ์ฆ ์„ค๋ช…
GET /api/v2/menus โŒ ์ „์ฒด ๋ฉ”๋‰ด
GET /api/v2/menus/sidebar โŒ ์‚ฌ์ด๋“œ๋ฐ” ๋ฉ”๋‰ด
GET /api/v2/menus/header โŒ ํ—ค๋” ๋ฉ”๋‰ด
โญ ์ถ”์ฒœ ๊ฒŒ์‹œ๋ฌผ (Recommended)
๋ฉ”์„œ๋“œ ๊ฒฝ๋กœ ์ธ์ฆ ์„ค๋ช…
GET /api/v2/recommended/{period} โŒ ์ถ”์ฒœ ๊ฒŒ์‹œ๋ฌผ (daily/weekly/monthly)

๐Ÿ›  ๊ธฐ์ˆ  ์Šคํƒ

Backend
  • Go 1.23+ - ๊ณ ์„ฑ๋Šฅ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ
  • Fiber v2 - Express ์Šคํƒ€์ผ ๋น ๋ฅธ HTTP ํ”„๋ ˆ์ž„์›Œํฌ
  • GORM - Go ORM with MySQL
  • golang-jwt/jwt v5 - JWT ์ธ์ฆ
Infrastructure
  • MySQL 8.0 - ๊ธฐ์กด ๊ทธ๋ˆ„๋ณด๋“œ DB (100GB+) ํ˜ธํ™˜
  • Redis 7+ - ์บ์‹ฑ ๋ฐ ์„ธ์…˜
  • Docker Compose - ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ
Architecture
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚         Handler (Presentation)              โ”‚  โ† HTTP ์š”์ฒญ/์‘๋‹ต
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         Service (Business Logic)            โ”‚  โ† ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         Repository (Data Access)            โ”‚  โ† ๋ฐ์ดํ„ฐ ์ ‘๊ทผ
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚         Domain (Models & DTOs)              โ”‚  โ† ๋„๋ฉ”์ธ ๋ชจ๋ธ
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ— ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

angple-backend/
โ”œโ”€โ”€ .docker/
โ”‚   โ””โ”€โ”€ mysql/init/         # MySQL ์ดˆ๊ธฐํ™” ์Šคํฌ๋ฆฝํŠธ (๋ฉ”๋‰ด seed ๋“ฑ)
โ”œโ”€โ”€ cmd/
โ”‚   โ””โ”€โ”€ api/                # API ์„œ๋ฒ„ ์—”ํŠธ๋ฆฌํฌ์ธํŠธ
โ”œโ”€โ”€ internal/
โ”‚   โ”œโ”€โ”€ handler/            # HTTP ํ•ธ๋“ค๋Ÿฌ
โ”‚   โ”œโ”€โ”€ service/            # ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
โ”‚   โ”œโ”€โ”€ repository/         # ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๋ ˆ์ด์–ด
โ”‚   โ”œโ”€โ”€ domain/             # ๋„๋ฉ”์ธ ๋ชจ๋ธ
โ”‚   โ”œโ”€โ”€ middleware/         # JWT, CORS, Cookie Auth
โ”‚   โ”œโ”€โ”€ common/             # ๊ณตํ†ต ์‘๋‹ต/์—๋Ÿฌ
โ”‚   โ”œโ”€โ”€ routes/             # ๋ผ์šฐํŠธ ์„ค์ •
โ”‚   โ””โ”€โ”€ config/             # ์„ค์ • ๊ด€๋ฆฌ
โ”œโ”€โ”€ pkg/
โ”‚   โ”œโ”€โ”€ jwt/                # JWT ์œ ํ‹ธ๋ฆฌํ‹ฐ
โ”‚   โ”œโ”€โ”€ auth/               # ๋ ˆ๊ฑฐ์‹œ ์ธ์ฆ ํ˜ธํ™˜
โ”‚   โ”œโ”€โ”€ logger/             # ๋กœ๊ฑฐ
โ”‚   โ””โ”€โ”€ redis/              # Redis ํด๋ผ์ด์–ธํŠธ
โ”œโ”€โ”€ configs/                # YAML ์„ค์ • ํŒŒ์ผ
โ”œโ”€โ”€ docs/                   # API ๋ฌธ์„œ (Swagger, Roadmap)
โ”œโ”€โ”€ docker-compose.yml      # MySQL + Redis ํ™˜๊ฒฝ
โ””โ”€โ”€ .env.example            # ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์˜ˆ์‹œ

๐Ÿ’ป ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •

ํ•„์ˆ˜ ์š”๊ตฌ์‚ฌํ•ญ
  • Go 1.23+
  • Docker & Docker Compose
  • Git
์ €์žฅ์†Œ ํด๋ก 
git clone https://github.com/damoang/angple-backend.git
cd angple-backend

๐Ÿ“ฆ Option 1: Docker All-in-One (๊ถŒ์žฅ โญ)

๋กœ์ปฌ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ์™„์ „ํ•œ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ Docker๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. MySQL, Redis, API ์„œ๋ฒ„๊ฐ€ ๋ชจ๋‘ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

1๋‹จ๊ณ„: ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์‹œ์ž‘
make dev-docker

์ด ๋ช…๋ น์–ด๋Š” ๋‹ค์Œ์„ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:

  • MySQL 8.0 (ํฌํŠธ 3306)
  • Redis 7 (ํฌํŠธ 6379)
  • API ์„œ๋ฒ„ (ํฌํŠธ 8081)
2๋‹จ๊ณ„: ์„œ๋ฒ„ ํ™•์ธ
# Health check
curl http://localhost:8081/health

# ๋ฉ”๋‰ด API ํ…Œ์ŠคํŠธ
curl http://localhost:8081/api/v2/menus/sidebar
์œ ์šฉํ•œ ๋ช…๋ น์–ด
# ๋กœ๊ทธ ํ™•์ธ
make dev-docker-logs

# ํ™˜๊ฒฝ ์ค‘์ง€
make dev-docker-down

# ์žฌ๋นŒ๋“œ (์ฝ”๋“œ ๋ณ€๊ฒฝ ํ›„)
make dev-docker-rebuild
ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (์„ ํƒ)

๊ธฐ๋ณธ ์„ค์ •(configs/config.docker.yaml)์œผ๋กœ ๋ฐ”๋กœ ์‹คํ–‰๋˜์ง€๋งŒ, ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ํ•„์š”ํ•˜๋ฉด docker-compose.dev.yml์˜ environment ์„น์…˜์„ ์ˆ˜์ •ํ•˜์„ธ์š”.

๊ธฐ๋ณธ ์„ค์ •:

  • Database: mysql:3306 (Docker ๋„คํŠธ์›Œํฌ ๋‚ด๋ถ€)
  • JWT Secret: dev-secret-key-2024-please-change-in-production
  • CORS: http://localhost:5173,http://localhost:5174,http://localhost:3000

๐Ÿ”ง Option 2: ๋กœ์ปฌ ์ง์ ‘ ์‹คํ–‰

API ์„œ๋ฒ„๋งŒ ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜๊ณ  MySQL/Redis๋Š” Docker๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

1๋‹จ๊ณ„: MySQL + Redis ์‹œ์ž‘
# MySQL + Redis ์ปจํ…Œ์ด๋„ˆ๋งŒ ์‹คํ–‰
docker-compose up -d

# ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ
docker-compose ps

Docker ๊ตฌ์„ฑ:

  • MySQL 8.0: ํฌํŠธ 3307 โ†’ 3306
  • Redis 7: ํฌํŠธ 6379
2๋‹จ๊ณ„: ํ™˜๊ฒฝ ์„ค์ •
# .env ํŒŒ์ผ ์ƒ์„ฑ
cp .env.example .env

.env ์ฃผ์š” ์„ค์ •:

# Environment
APP_ENV=local

# Database (Docker MySQL)
DB_HOST=localhost
DB_PORT=3307
DB_USER=angple_user
DB_PASSWORD=angple_pass_2024
DB_NAME=angple_db

# Redis
REDIS_HOST=localhost
REDIS_PORT=6379

# JWT
JWT_SECRET=your-development-secret-key
DAMOANG_JWT_SECRET=your-legacy-sso-secret

# API
API_PORT=8081
3๋‹จ๊ณ„: ์˜์กด์„ฑ ์„ค์น˜ ๋ฐ ์‹คํ–‰
# Go ๋ชจ๋“ˆ ๋‹ค์šด๋กœ๋“œ
go mod download

# API ์„œ๋ฒ„ ์‹คํ–‰
make dev
# ๋˜๋Š”
APP_ENV=local go run cmd/api/main.go
4๋‹จ๊ณ„: ์‹คํ–‰ ํ™•์ธ
# Health Check
curl http://localhost:8081/health

# ๋ฉ”๋‰ด API ํ…Œ์ŠคํŠธ
curl http://localhost:8081/api/v2/menus/sidebar
5๋‹จ๊ณ„: ๋นŒ๋“œ (์„ ํƒ)
# ๋ฐ”์ด๋„ˆ๋ฆฌ ๋นŒ๋“œ
make build-api
# ๋˜๋Š”
go build -o bin/api cmd/api/main.go

# ์‹คํ–‰
./bin/api

๐ŸŒ ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๊ฐ€์ด๋“œ

ํ”„๋กœ์ ํŠธ๋Š” ํ™˜๊ฒฝ๋ณ„๋กœ ๋‹ค๋ฅธ ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ™˜๊ฒฝ APP_ENV ์„ค์ • ํŒŒ์ผ ์šฉ๋„
Docker ๊ฐœ๋ฐœ docker configs/config.docker.yaml Docker Compose ๋กœ์ปฌ ๊ฐœ๋ฐœ
๋กœ์ปฌ ๊ฐœ๋ฐœ local configs/config.local.yaml ์ง์ ‘ ์‹คํ–‰ ๋กœ์ปฌ ๊ฐœ๋ฐœ
์šด์˜ prod configs/config.prod.yaml ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ
Docker ๊ฐœ๋ฐœ ํ™˜๊ฒฝ (config.docker.yaml)
server:
  env: docker

database:
  host: mysql  # Docker ์„œ๋น„์Šค๋ช…
  port: 3306
  user: damoang_user
  password: dev_pass_2024

redis:
  host: redis  # Docker ์„œ๋น„์Šค๋ช…
  port: 6379

cors:
  allow_origins: "http://localhost:5173, http://localhost:5174"
์šด์˜ ํ™˜๊ฒฝ (config.prod.yaml)

โš ๏ธ ์ค‘์š”: ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

server:
  env: prod
  mode: production

database:
  host: ""  # ํ™˜๊ฒฝ ๋ณ€์ˆ˜: DB_HOST ํ•„์ˆ˜!
  password: ""  # ํ™˜๊ฒฝ ๋ณ€์ˆ˜: DB_PASSWORD ํ•„์ˆ˜!

jwt:
  secret: ""  # ํ™˜๊ฒฝ ๋ณ€์ˆ˜: JWT_SECRET ํ•„์ˆ˜!
  damoang_secret: ""  # ํ™˜๊ฒฝ ๋ณ€์ˆ˜: DAMOANG_JWT_SECRET ํ•„์ˆ˜!

ํ•„์ˆ˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜:

export DB_HOST=your-production-db-host
export DB_PASSWORD=your-secure-password
export REDIS_HOST=your-redis-host
export JWT_SECRET=your-jwt-secret-key
export DAMOANG_JWT_SECRET=your-damoang-jwt-secret
export CORS_ALLOW_ORIGINS=https://damoang.net

๐Ÿš€ ์šด์˜ ํ™˜๊ฒฝ ๋ฐฐํฌ (Standalone)

์ „์ฒด ์Šคํƒ(MySQL, Redis, API, Gateway, Web, Admin)์„ ๋‹จ์ผ compose๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋น ๋ฅธ ์‹œ์ž‘
git clone https://github.com/damoang/angple-backend.git
cd angple-backend
cp .env.example .env   # ํ•„์ˆ˜ ๊ฐ’ ์ˆ˜์ •
docker compose -f docker-compose.standalone.yml up -d
ํ•„์ˆ˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (.env)
๋ณ€์ˆ˜ ์„ค๋ช… ํ•„์ˆ˜
DB_PASSWORD MySQL ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ O
MYSQL_ROOT_PASSWORD MySQL root ๋น„๋ฐ€๋ฒˆํ˜ธ O
JWT_SECRET JWT ์„œ๋ช… ํ‚ค (32์ž ์ด์ƒ) O
ANGPLE_VERSION Docker ์ด๋ฏธ์ง€ ํƒœ๊ทธ - (๊ธฐ๋ณธ: latest)
CORS_ALLOW_ORIGINS ํ—ˆ์šฉ Origin ๋ชฉ๋ก -
LARAVEL_BACKEND_URL ๋ ˆ๊ฑฐ์‹œ PHP ๋ฐฑ์—”๋“œ URL -
DAMOANG_JWT_SECRET ๋ ˆ๊ฑฐ์‹œ SSO ์‹œํฌ๋ฆฟ -
์„œ๋น„์Šค ํฌํŠธ
์„œ๋น„์Šค ๊ธฐ๋ณธ ํฌํŠธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜
Gateway 8080 GATEWAY_PORT
API 8081 API_PORT
Web 3010 WEB_PORT
Admin 3011 ADMIN_PORT
์„œ๋ฒ„๋ณ„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• (docker-compose.override.yml)

๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ(Nginx Proxy Manager ๋“ฑ)๋‚˜ ๋ ˆ๊ฑฐ์‹œ DB ์—ฐ๋™ ๋“ฑ ์„œ๋ฒ„ ๊ณ ์œ  ์„ค์ •์€ docker-compose.override.yml์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ Docker Compose๊ฐ€ ์ž๋™์œผ๋กœ mergeํ•ฉ๋‹ˆ๋‹ค.

# docker-compose.override.yml ์˜ˆ์‹œ
services:
  api:
    networks:
      - proxy-network
      - legacy-db
    environment:
      DB_HOST: legacy-mysql
      DB_NAME: legacy_db
      DB_USER: root
      DB_PASSWORD: legacy-password
  gateway:
    networks:
      - proxy-network
  web:
    networks:
      - proxy-network

networks:
  proxy-network:
    external: true
  legacy-db:
    external: true
    name: existing_mysql_network
Health Check
curl http://localhost:8081/health   # API
curl http://localhost:8080/health   # Gateway
curl http://localhost:3010          # Web
curl http://localhost:3011          # Admin

๐Ÿ”„ CI/CD (GitHub Actions)

๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ

main ๋ธŒ๋žœ์น˜์— pushํ•˜๋ฉด ์ž๋™์œผ๋กœ:

  1. Go ํ…Œ์ŠคํŠธ ์‹คํ–‰
  2. API + Gateway Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ (linux/amd64, linux/arm64)
  3. GHCR(ghcr.io)์— push
  4. SSH๋กœ ์„œ๋ฒ„์— ์ ‘์†ํ•˜์—ฌ ์ด๋ฏธ์ง€ pull & ์žฌ์‹œ์ž‘
main push โ†’ test โ†’ build (multi-arch) โ†’ GHCR push โ†’ SSH deploy

์›Œํฌํ”Œ๋กœ์šฐ: .github/workflows/ghcr-deploy.yml

์šด์˜ ํ™˜๊ฒฝ ๋ฐฐํฌ (์ˆ˜๋™)

์›Œํฌํ”Œ๋กœ์šฐ: .github/workflows/deploy-prod.yml

GitHub Actions์—์„œ ์ˆ˜๋™ ํŠธ๋ฆฌ๊ฑฐํ•˜์—ฌ ์šด์˜ ์„œ๋ฒ„์— ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ” ์ธ์ฆ ์‹œ์Šคํ…œ

JWT ํ† ํฐ
  • Access Token: 15๋ถ„ (์งง์€ ์ˆ˜๋ช…์œผ๋กœ ๋ณด์•ˆ ๊ฐ•ํ™”)
  • Refresh Token: 7์ผ (ํ† ํฐ ์žฌ๋ฐœ๊ธ‰์šฉ)
๋ ˆ๊ฑฐ์‹œ ํ†ตํ•ฉ
  1. Damoang SSO: ๊ธฐ์กด PHP ์‹œ์Šคํ…œ์˜ damoang_jwt ์ฟ ํ‚ค ๊ฒ€์ฆ
  2. ๊ทธ๋ˆ„๋ณด๋“œ ๋น„๋ฐ€๋ฒˆํ˜ธ: 1๊ฐ€์ง€ ํฌ๋งท ํ˜ธํ™˜
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” PBKDF2 ๊ธฐ๋ฐ˜ SHA256 ํ•ด์‹œ์ด๋‹ค. ๋ฐ˜๋ณตํšŸ์ˆ˜ 12000, Salt 24 Byte
  3. ๊ทธ๋ˆ„๋ณด๋“œ ID : ์†Œ์…œ๋กœ๊ทธ์ธ ์•„์ด๋”” adler32(md5(์†Œ์…œ์œ ๋‹ˆํฌํ‚ค)) ๋กœ ๊ฐ์‹ธ์„œ ๊ฑฐ์นœ๋‹ค.
๊ฐœ๋ฐœ ํ™˜๊ฒฝ Mock ์ธ์ฆ
// local, dev ํ™˜๊ฒฝ์—์„œ๋Š” ์ž๋™ ๋กœ๊ทธ์ธ
User ID: "dev_user"
User Name: "๊ฐœ๋ฐœ์ž"
Level: 10 (๊ด€๋ฆฌ์ž)

๐Ÿ—„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

๊ทธ๋ˆ„๋ณด๋“œ ํ˜ธํ™˜์„ฑ

๊ธฐ์กด ๊ทธ๋ˆ„๋ณด๋“œ 5.x ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ 100% ํ˜ธํ™˜:

  • ํ…Œ์ด๋ธ” ์ ‘๋‘์‚ฌ: g5_
  • ๋™์  ๊ฒŒ์‹œํŒ: g5_write_{board_id} (์˜ˆ: g5_write_free)
  • ๋Œ“๊ธ€ ๊ตฌ์กฐ: ๊ฒŒ์‹œ๊ธ€ ํ…Œ์ด๋ธ”์— wr_is_comment = 1๋กœ ์ €์žฅ
์ฃผ์š” ํ…Œ์ด๋ธ”
g5_member                # ํšŒ์› ์ •๋ณด
g5_write_{board_id}      # ๊ฒŒ์‹œํŒ๋ณ„ ๊ฒŒ์‹œ๊ธ€/๋Œ“๊ธ€
g5_board                 # ๊ฒŒ์‹œํŒ ์„ค์ •
g5_group                 # ๊ฒŒ์‹œํŒ ๊ทธ๋ฃน
menus                    # ๋ฉ”๋‰ด ์‹œ์Šคํ…œ (์‹ ๊ทœ)
Docker MySQL ์ดˆ๊ธฐํ™”

.docker/mysql/init/ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ž๋™ ์‹คํ–‰:

  • 01-schema.sql: ๋ฉ”๋‰ด ํ…Œ์ด๋ธ” ์ƒ์„ฑ
  • 02-seed-menus.sql: ๊ธฐ๋ณธ ๋ฉ”๋‰ด 29๊ฐœ ์‚ฝ์ž…

๐Ÿงช ํ…Œ์ŠคํŠธ

# ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰
go test ./...

# ์ปค๋ฒ„๋ฆฌ์ง€ ํฌํ•จ
go test -cover ./...

# ํŠน์ • ํŒจํ‚ค์ง€
go test ./internal/service/...

# ํŠน์ • ํ•จ์ˆ˜
go test -run TestAuthService ./internal/service/

โ— ์ž์ฃผ ๋ฌป๋Š” ๋ฌธ์ œ

Port 8081 already in use

์›์ธ: ์ด์ „ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š์Œ

ํ•ด๊ฒฐ:

# ํ”„๋กœ์„ธ์Šค ํ™•์ธ ๋ฐ ์ข…๋ฃŒ
lsof -ti :8081 | xargs kill -9

# ๋˜๋Š”
pkill -f "go run cmd/api/main.go"
CORS error (Access-Control-Allow-Origin)

์›์ธ: ํ”„๋ก ํŠธ์—”๋“œ origin์ด ํ—ˆ์šฉ ๋ชฉ๋ก์— ์—†์Œ

ํ•ด๊ฒฐ:

# configs/config.dev.yaml
cors:
  allow_origins: "http://localhost:5173, http://localhost:5174"

๋˜๋Š” .env:

CORS_ALLOW_ORIGINS="http://localhost:5173, http://localhost:5174"
Database connection failed

์›์ธ: MySQL ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์Œ

ํ•ด๊ฒฐ:

# Docker ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ
docker-compose ps

# MySQL ๋กœ๊ทธ ํ™•์ธ
docker-compose logs mysql

# ์žฌ์‹œ์ž‘
docker-compose down
docker-compose up -d
DAMOANG_JWT_SECRET required

์›์ธ: ํ•„์ˆ˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋ˆ„๋ฝ

ํ•ด๊ฒฐ:

# .env ํŒŒ์ผ์— ์ถ”๊ฐ€
DAMOANG_JWT_SECRET=your-legacy-sso-secret-key

๐Ÿ“Š ์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ

๋ชฉํ‘œ ์ง€ํ‘œ
์ง€ํ‘œ ๊ธฐ์กด PHP Go ๋ชฉํ‘œ ํ˜„์žฌ ์ƒํƒœ
์‘๋‹ต ์‹œ๊ฐ„ (P95) ~800ms < 50ms ์ธก์ • ์˜ˆ์ •
์ฒ˜๋ฆฌ๋Ÿ‰ (RPS) ~1,000 > 10,000 ์ธก์ • ์˜ˆ์ •
๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ~512MB ~128MB ์ธก์ • ์˜ˆ์ •
๋™์‹œ ์ ‘์† 7์ฒœ~2๋งŒ 5๋งŒ+ ์ธก์ • ์˜ˆ์ •

๐Ÿค ๊ธฐ์—ฌํ•˜๊ธฐ

๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ๋‹ค์Œ ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ์ฃผ์„ธ์š”:

  1. ์ด ์ €์žฅ์†Œ๋ฅผ Fork ํ•ฉ๋‹ˆ๋‹ค
  2. Feature ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค (git checkout -b feature/amazing-feature)
  3. ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค (git commit -m 'Add amazing feature')
  4. ๋ธŒ๋žœ์น˜์— Push ํ•ฉ๋‹ˆ๋‹ค (git push origin feature/amazing-feature)
  5. Pull Request๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค
์ฝ”๋”ฉ ์ปจ๋ฒค์…˜
  • Go ํ‘œ์ค€ ํฌ๋งท ์‚ฌ์šฉ (gofmt, goimports)
  • ํ•จ์ˆ˜/๋ฉ”์„œ๋“œ์— ์ฃผ์„ ์ž‘์„ฑ
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํฌํ•จ
  • Clean Architecture ํŒจํ„ด ์ค€์ˆ˜
์šฐ์„ ์ˆœ์œ„ ์ž‘์—…

ํ˜„์žฌ ๋„์›€์ด ํ•„์š”ํ•œ ์ž‘์—…๋“ค:

  • ๋ฉ”๋‰ด ๊ด€๋ฆฌ ์‹œ์Šคํ…œ โœ…
  • ์ถ”์ฒœ API (ํŒŒ์ผ ๊ธฐ๋ฐ˜) โœ…
  • ๋น„์ถ”์ฒœ API
  • ํŒŒ์ผ ์—…๋กœ๋“œ ์‹œ์Šคํ…œ (์ด๋ฏธ์ง€ ๋ณ€ํ™˜)
  • ํšŒ์› ํ”„๋กœํ•„ API
  • ์Šคํฌ๋žฉ ๊ธฐ๋Šฅ
  • ์•Œ๋ฆผ ์‹œ์Šคํ…œ (WebSocket)
  • ํ†ตํ•ฉ ๊ฒ€์ƒ‰ (ElasticSearch)

๐Ÿ“‹ ์ƒ์„ธ ๋กœ๋“œ๋งต: docs/api-roadmap.csv


๐Ÿ“š ๊ด€๋ จ ๋ฌธ์„œ

  • CLAUDE.md: AI ๊ฐœ๋ฐœ ๋„๊ตฌ์šฉ ํ”„๋กœ์ ํŠธ ๊ฐ€์ด๋“œ
  • docs/swagger.yaml: OpenAPI 3.0 ์ŠคํŽ™
  • docs/api-roadmap.csv: API ๊ฐœ๋ฐœ ๋กœ๋“œ๋งต
  • Wiki: ์•„ํ‚คํ…์ฒ˜ ์ƒ์„ธ ์„ค๋ช…

๐Ÿ“ ๋ผ์ด์„ ์Šค

์ด ํ”„๋กœ์ ํŠธ๋Š” MIT ๋ผ์ด์„ ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ LICENSE ํŒŒ์ผ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.


๐Ÿ“ง ๋ฌธ์˜


Made with โค๏ธ by SDK Co., Ltd.

Test auto deploy Mon Jan 26 06:57:02 PM KST 2026

Directories ยถ

Path Synopsis
cmd
ad-free-setup command
Ad-Free ๋ฉค๋ฒ„์‹ญ ์šด์˜ DB ์…‹์—… โ€” navertest ๊ณ„์ • + ๋ฉค๋ฒ„์‹ญ ๋ถ€์—ฌ.
Ad-Free ๋ฉค๋ฒ„์‹ญ ์šด์˜ DB ์…‹์—… โ€” navertest ๊ณ„์ • + ๋ฉค๋ฒ„์‹ญ ๋ถ€์—ฌ.
api command
fix-utf8 command
gateway command
generate_token command
janggi-ws command
Command omok-ws ๋Š” ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ WebSocket ์„œ๋ฒ„๋‹ค.
Command omok-ws ๋Š” ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ WebSocket ์„œ๋ฒ„๋‹ค.
member-activity command
migrate command
migrate-nariya command
omok-ws command
Command omok-ws ๋Š” ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ WebSocket ์„œ๋ฒ„๋‹ค.
Command omok-ws ๋Š” ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ WebSocket ์„œ๋ฒ„๋‹ค.
Package docs Code generated by swaggo/swag.
Package docs Code generated by swaggo/swag.
internal
janggi
Package janggi ๋Š” ์žฅ๊ธฐ ๊ทœ์น™ ์—”์ง„์ด๋‹ค.
Package janggi ๋Š” ์žฅ๊ธฐ ๊ทœ์น™ ์—”์ง„์ด๋‹ค.
janggi_srv
Package omok ์€ ์‹ค์‹œ๊ฐ„ ์žฅ๊ธฐ ๋Œ€์ „ ์„œ๋ฒ„๋‹ค.
Package omok ์€ ์‹ค์‹œ๊ฐ„ ์žฅ๊ธฐ ๋Œ€์ „ ์„œ๋ฒ„๋‹ค.
omok
Package omok ์€ ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ ์„œ๋ฒ„๋‹ค.
Package omok ์€ ์‹ค์‹œ๊ฐ„ ์˜ค๋ชฉ ๋Œ€์ „ ์„œ๋ฒ„๋‹ค.
service
Package service โ€” newgroup(์†Œ๋ชจ์ž„ ๊ฐœ์„ค ์‹ ์ฒญ) ์•ˆ๋‚ด ์ž๋™ ๋Œ“๊ธ€.
Package service โ€” newgroup(์†Œ๋ชจ์ž„ ๊ฐœ์„ค ์‹ ์ฒญ) ์•ˆ๋‚ด ์ž๋™ ๋Œ“๊ธ€.
ws
pkg
jwt
redis
Package redis โ€” JSON-typed cache helpers built on top of go-redis client.
Package redis โ€” JSON-typed cache helpers built on top of go-redis client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL