7.3 KiB
Sammo Core2026 Docker deployment
이 저장소는 새 호스트에서 .env 하나로 Core2026 Gateway, PostgreSQL, Redis,
Caddy와 Git/PM2 release-controller를 기동하기 위한 공개 배포 골격입니다. 게임
profile은 관리자 화면에서 각각 다른 branch 또는 commit을 선택해 DB 유지 배포,
DB 초기화 배포와 rollback을 수행합니다.
빠른 시작
Docker Engine과 Compose plugin이 설치된 Linux 호스트에서 다음을 실행합니다.
cp .env.example .env
# .env의 domain, Core2026 URL, Kakao key와 모든 비밀값을 교체합니다.
./scripts/check.sh
docker compose up -d --build --wait
docker compose ps
DNS의 DOMAIN A/AAAA record가 호스트를 가리키고 80/443 TCP 및 443 UDP가
열려 있으면 Caddy가 인증서를 자동 발급합니다. Kakao Developers에는
https://DOMAIN/gateway/oauth/callback을 redirect URI로 등록합니다. 첫 기동은
Core2026 clone, frozen-lockfile install, build와 Gateway migration 때문에 수 분이
걸릴 수 있습니다.
외부 reverse proxy가 TLS를 종료하고 이 stack의 HTTP port로 전달한다면
PUBLIC_SCHEME=https, CADDY_SITE_ADDRESS=http://DOMAIN을 함께 설정합니다.
예를 들어 host 14999로 전달할 때는 HTTP_PORT=14999로 두고, 사용하지 않는
HTTPS_PORT는 충돌하지 않는 별도 host port로 지정합니다. 외부 proxy는 원래
Host header를 보존해야 합니다.
runtime은 기본적으로 memory/swap 각각 4 GiB, CPU 4개, PID 256개 상한을
가집니다. 호스트 용량에 맞춰 RUNTIME_*_LIMIT을 조정할 수 있지만 0 또는
무제한으로 두지 않습니다. PM2 process/restart 수가 예상보다 증가하면 로그 수집보다
runtime 중지가 우선입니다.
초기 빌드와 profile worktree 빌드는 기본 Node heap 1536 MiB,
RAYON_NUM_THREADS=1 안에서 실행됩니다. RUNTIME_NODE_OPTIONS의 heap 상한은
5122048 MiB, 4만 허용됩니다. 이는 빌드 중
container hard limit에 먼저 닿는 것을 막고 실행 process에도 같은 상한을
적용합니다.RUNTIME_RAYON_NUM_THREADS는 1
scripts/check.sh는 example placeholder, 짧은 비밀값, 잘못된 domain/email,
repository credential 조합을 실제 값 출력 없이 거부합니다. 최소 길이는 DB·Redis
password 24자, game/bootstrap token 32자, 최초 관리자 password 16자입니다.
배포 전 무작위 값은 예를 들어 openssl rand -base64 36으로 생성합니다.
INITIAL_ADMIN_*은 사용자 table이 비어 있을 때만 superuser를 한 번 생성합니다.
그 뒤 /gateway/admin/server-operations에서 che, kwe, pwe, twe, nya,
pya, hwe마다 source branch/commit을 독립 선택합니다. DB 유지 배포는 현
시즌을 보존하고, DB 초기화 배포는 scenario를 다시 seed합니다. Gateway 자체의
배포와 이전 commit rollback은 같은 화면의 별도 release 영역에서 처리됩니다.
이미지 서비스 연동에는 서버 간 접근 URL IMAGE_SERVICE_URL, 브라우저 공개 URL
IMAGE_PUBLIC_URL과 서로 다른 두 secret 파일이 필요합니다. 업로드 secret은
Gateway 전용 아이콘과 game-api 편집기 첨부에만 사용하고, sync secret은 Gitea
webhook 누락 시 docker compose exec runtime pnpm sync:image로 현재 이미지
branch의 fast-forward를 요청할 때만 사용합니다. 두 파일은 runtime에 read-only로
mount되며 원문은 환경 변수나 브라우저 bundle에 들어가지 않습니다.
데이터와 복구 경계
- PostgreSQL, Redis, Core clone/worktree, PM2 상태, Caddy 인증서와 user icon은
named volume 또는
data/image에 보존됩니다. /image/*는 앱 artifact가 아니며data/image/의 별도 운영 자산을 제공합니다.- 일반
docker compose down은 volume을 보존합니다.down --volumes는 DB와 release 상태를 삭제하는 파괴적 명령이므로 backup 없이 실행하지 않습니다. - 앱 rollback은 Prisma migration을 되돌리지 않습니다. 이전 앱과 새 schema의 호환성을 배포 전에 확인합니다.
- Core2026 저장소가 비공개라면 credential을 Git에 추가하지 않습니다. HTTPS는
.env의CORE_REPOSITORY_USERNAME과 read-onlyCORE_REPOSITORY_TOKEN을 함께 설정합니다. URL에 credential을 포함하지 않으며 runtime은 0600 파일로 옮긴 뒤 원래 env를 제거하고GIT_ASKPASS로만 전달합니다. - SSH deploy key를 사용할 때는
CORE_SSH_PRIVATE_KEY_BASE64와CORE_SSH_KNOWN_HOSTS_BASE64를 함께 설정합니다. 각각base64 -w0로 인코딩한 read-only key와 검증한 known_hosts 내용입니다. HTTPS와 SSH mode를 동시에 설정할 수 없습니다. 원래 base64 env는 파일 생성 직후 제거됩니다. 생성된 credential/key 파일은 runtime volume에서 0600으로 관리되고 해당 mode를 해제한 다음 기동하면 제거됩니다.
상태 확인과 로그:
docker compose ps
docker compose logs --tail=200 runtime caddy
docker compose exec runtime pnpm --filter @sammo-ts/release-controller status
개발 bind 모드
로컬 Core2026 checkout을 container에 bind하고 DB/Redis/Caddy는 같은 구성으로
사용할 수 있습니다. .env에 CORE_DEV_PATH=/absolute/path/to/core2026,
host 사용자의 DEV_UID/DEV_GID, PUBLIC_SCHEME=http, DOMAIN=localhost를
추가한 뒤 실행합니다. 기본 UID/GID는 1000:1000입니다.
docker compose -f compose.yaml -f compose.dev.yaml up -d --build
docker compose exec runtime pnpm --filter @sammo-ts/gateway-api dev
docker compose exec runtime pnpm --filter @sammo-ts/gateway-frontend dev --host 0.0.0.0
개발 override의 runtime은 의존성과 Prisma client를 준비한 뒤 대기합니다. 필요한 watch process를 별도 shell에서 실행합니다. 운영 release-controller를 시험하려면 override 없이 production mode를 사용해야 하며, bind checkout의 Git metadata에 container worktree 경로를 등록하지 않도록 주의합니다.
compose.dev.yaml은 RUNTIME_MODE=development와 모든 service의
restart: no를 literal로 고정합니다. .env의 RUNTIME_MODE로 이를 덮어쓸 수
없습니다. production PM2 검증에 개발 override를 섞지 않습니다. 개발 runtime에도
기본 4 GiB/4 CPU/256 PID 상한이 있으며 DEV_RUNTIME_*_LIMIT으로 더 낮출 수
있습니다.
운영 entrypoint와 PM2를 검증할 때는 개발 override 대신 전용 smoke override를
사용합니다. 이 override는 clone mode를 유지하면서 모든 service를 restart: no로
고정하고 runtime 상한을 최대 4 GiB/4 CPU/256 PID로 제한합니다.
docker compose -f compose.yaml -f compose.smoke.yaml up -d --build --wait
검증 shell에는 EXIT/INT/TERM trap과 전체 timeout을 두고, 정상·실패 어느 경우든
docker compose stop으로 끝냅니다. down --volumes는 사용하지 않습니다.
설정 검증
.env를 채운 뒤 실제 값을 출력하지 않는 검사를 실행합니다.
./scripts/check.sh
검사는 production/development Compose model과 Caddyfile 구문을 확인합니다.
다른 env 파일은 ENV_FILE=/path/to/file ./scripts/check.sh로 검사합니다.
docker compose config 전체 출력에는 펼쳐진 비밀값이 포함될 수 있으므로 CI
artifact나 이슈에 그대로 첨부하지 않습니다.