다모앙(damoang.net) 커뮤니티 차세대 백엔드 API 서버입니다. 기존 PHP 시스템을 Go로 마이그레이션하여 800ms → 50ms 이하의 응답 속도를 목표로 합니다.
MySQL + Redis + API를 한 번에 실행하는 완전한 로컬 개발 환경:
# 전체 개발 환경 시작
make dev-docker
# 로그 확인
make dev-docker-logs
# 중지
make dev-docker-down자동 실행 항목:
- MySQL (포트 3306)
- Redis (포트 6379)
- API 서버 (포트 8081)
# 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}📖 상세 가이드: 개발 환경 설정
| 기능 | 설명 | 엔드포인트 |
|---|---|---|
| 인증 | 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} |
- 파일 업로드 (이미지 리사이징)
- 실시간 알림 (WebSocket)
- 통합 검색 (ElasticSearch)
- 투표/설문 시스템
- 관리자 대시보드
📋 전체 로드맵: docs/api-roadmap.csv
# 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) |
- Go 1.23+ - 고성능 동시성 처리
- Fiber v2 - Express 스타일 빠른 HTTP 프레임워크
- GORM - Go ORM with MySQL
- golang-jwt/jwt v5 - JWT 인증
- MySQL 8.0 - 기존 그누보드 DB (100GB+) 호환
- Redis 7+ - 캐싱 및 세션
- Docker Compose - 로컬 개발 환경
┌─────────────────────────────────────────────┐
│ 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로컬 개발을 위한 완전한 개발 환경을 Docker로 제공합니다. MySQL, Redis, API 서버가 모두 자동으로 실행됩니다.
make dev-docker이 명령어는 다음을 자동으로 실행합니다:
- MySQL 8.0 (포트 3306)
- Redis 7 (포트 6379)
- API 서버 (포트 8081)
# 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
API 서버만 로컬에서 실행하고 MySQL/Redis는 Docker로 실행하는 방법입니다.
# MySQL + Redis 컨테이너만 실행
docker-compose up -d
# 컨테이너 상태 확인
docker-compose psDocker 구성:
- MySQL 8.0: 포트 3307 → 3306
- Redis 7: 포트 6379
# .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# Go 모듈 다운로드
go mod download
# API 서버 실행
make dev
# 또는
APP_ENV=local go run cmd/api/main.go# Health Check
curl http://localhost:8081/health
# 메뉴 API 테스트
curl http://localhost:8081/api/v2/menus/sidebar# 바이너리 빌드
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 |
프로덕션 환경 |
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"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전체 스택(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| 변수 | 설명 | 필수 |
|---|---|---|
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 |
리버스 프록시(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_networkcurl http://localhost:8081/health # API
curl http://localhost:8080/health # Gateway
curl http://localhost:3010 # Web
curl http://localhost:3011 # Adminmain 브랜치에 push하면 자동으로:
- Go 테스트 실행
- API + Gateway Docker 이미지 빌드 (linux/amd64, linux/arm64)
- GHCR(ghcr.io)에 push
- SSH로 서버에 접속하여 이미지 pull & 재시작
main push → test → build (multi-arch) → GHCR push → SSH deploy
워크플로우: .github/workflows/ghcr-deploy.yml
워크플로우: .github/workflows/deploy-prod.yml
GitHub Actions에서 수동 트리거하여 운영 서버에 배포합니다.
- Access Token: 15분 (짧은 수명으로 보안 강화)
- Refresh Token: 7일 (토큰 재발급용)
- Damoang SSO: 기존 PHP 시스템의
damoang_jwt쿠키 검증 - 그누보드 비밀번호: 1가지 포맷 호환
- 비밀번호는 PBKDF2 기반 SHA256 해시이다. 반복횟수 12000, Salt 24 Byte
- 그누보드 ID : 소셜로그인 아이디 adler32(md5(소셜유니크키)) 로 감싸서 거친다.
// 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/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 -dDAMOANG_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만+ | 측정 예정 |
기여를 환영합니다! 다음 절차를 따라주세요:
- 이 저장소를 Fork 합니다
- Feature 브랜치를 생성합니다 (
git checkout -b feature/amazing-feature) - 변경사항을 커밋합니다 (
git commit -m 'Add amazing feature') - 브랜치에 Push 합니다 (
git push origin feature/amazing-feature) - 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.