본문으로 건너뛰기

셀프호스팅 배포

LinkBoard는 처음부터 Docker Compose로 설계되어 있고 Kubernetes/클라우드 전용 매니페스트는 없습니다. 단일 서버(VM)에 Docker Compose + 리버스 프록시로 배포하는 것이 현재 구조에 가장 맞는 경로입니다.

현재 상태 요약

아직 구현되지 않은 부분은 있는 척 설명하지 않습니다. 실제 서버에 올리기 전 아래 표를 먼저 확인하세요.

구성요소상태
로컬 개발(Docker Compose)✅ 완비
백엔드 프로덕션 실행형태✅ 완비
프론트엔드 프로덕션 실행형태✅ 완비 (Nginx 정적 서빙 + /api,/ws 리버스프록시)
DB 마이그레이션 자동화🟡 CI에서 검증만 함 — 실배포 시 수동 실행 필요
CI(테스트)✅ 완비
CD(자동 배포)⚠️ 미구현
리버스 프록시 / TLS⚠️ 미구현 — 서버 앞단에 직접 구성 필요
EMQX 인증🟡 옵트인 — 기본은 익명 허용, 프로덕션에서는 반드시 활성화 필요
모니터링(Prometheus/Grafana)⚠️ 미구현
백업⚠️ 미구현 — 직접 스크립트/크론 구성 필요

사전 준비

  • Docker Engine + Docker Compose v2가 설치된 서버 (Linux 권장)
  • 도메인 + DNS A 레코드 (리버스 프록시/TLS용)
  • .env 파일을 서버에서 직접 생성 (git에 커밋하지 않습니다)

.env.example 대비 프로덕션에서 반드시 바꿔야 하는 값:

APP_ENV=production
SECRET_KEY=<32자 이상 랜덤값> # 기본값 그대로 쓰면 안 됩니다
POSTGRES_PASSWORD=<강력한 값>
DATABASE_URL=postgresql+asyncpg://linkboard:<위 값>@db:5432/linkboard
EMQX_DASHBOARD_PASSWORD=<기본값에서 반드시 변경>
MQTT_PASSWORD=<백엔드용 MQTT 슈퍼유저 비밀번호>
API_DOCS_ENABLED=false # 프로덕션에서 Swagger/ReDoc 노출 여부(기본 비노출)

배포 절차

git pull origin main
docker compose -f docker-compose.prod.yml build backend frontend
docker compose -f docker-compose.prod.yml up -d
docker compose -f docker-compose.prod.yml exec backend alembic upgrade head # 반드시 기동 후 실행

최초 1회만 seed_admin.py로 SystemAdmin 계정을 생성하고, 평문 비밀번호는 시딩 직후 바로 변경하세요.

리버스 프록시 + TLS (직접 구성 필요)

현재 각 서비스가 포트를 직접 노출할 뿐 HTTPS 종단이 없습니다. 서버 앞단에 Nginx 또는 Caddy를 두고:

  • 443 → frontend(정적) / /api, /ws → backend:8000 프록시
  • Let's Encrypt(certbot) 또는 Caddy 자동 TLS로 인증서 발급
  • EMQX 대시보드(18083)·MQTT(1883)는 필요할 때만 외부에 노출 (가급적 방화벽으로 내부망 한정)

EMQX 인증 활성화 (프로덕션 필수)

개발 기본값은 익명 MQTT 연결을 허용합니다. 프로덕션에서는 반드시 HTTP auth 콜백을 켜야 합니다 — 그렇지 않으면 누구나 인증 없이 MQTT 브로커에 연결해 임의 장치로 텔레메트리를 주입할 수 있습니다. 활성화 절차는 저장소의 infra/emqx/README.md를 참고하세요.

백업 (직접 구성 필요)

Postgres 볼륨(db_data)에 텔레메트리·설정이 전부 있습니다. 최소한의 예시:

docker compose exec -T db pg_dump -U linkboard linkboard | gzip > backup_$(date +%Y%m%d).sql.gz

db_data · emqx_data · redis_data는 named volume이므로 서버 디스크 자체의 백업(또는 볼륨 스냅샷)도 함께 고려하세요.

모니터링

정식 모니터링(Prometheus/Grafana)은 아직 없습니다. 배포 직후에는 GET /health(app/env/version 반환)와 docker compose ps / docker compose logs -f로 수동 확인하세요.