From e5c4d325bf0f3b666dd542eeb49bed2c6ccb9a34 Mon Sep 17 00:00:00 2001 From: jisangs Date: Thu, 9 Jul 2026 10:54:06 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8A=A4=ED=85=8C=EC=9D=B4=EC=A7=80=EC=9A=A9?= =?UTF-8?q?=20=EB=B3=80=EC=88=98=20=EC=88=98=EC=A0=95:=20stage-chocoadmin?= =?UTF-8?q?=20->=20chocoadmin-stage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- docker-compose.stage.yml | 4 ++-- docs/deployment.md | 16 ++++++++-------- docs/phase/phase8.md | 8 ++++---- docs/plan/project-plan.md | 2 +- scripts/deploy-stage.sh | 8 ++++---- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d86f5e9..3f31194 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ Admin panel for the chocomae service (mouse-typing), extracted into a standalone - Upgrade approval sets `AvailableActivateDateTime = NOW() + 1 year`. **Do not change `PlayerCount`** on upgrade. - When approving an extension or upgrade, close all other `Status = 1` requests for the same `MaestroID` by setting them to `Status = 2`, then set the approved request to `Status = 3`. - **Docker containers must set `TZ: Asia/Seoul`** so that date calculations (`setHours(0,0,0,0)`, `formatDate`) match the KST-based existing data in the shared MariaDB. -- **Docker service names must be unique per environment**: Docker registers each `services:` key as a DNS alias in shared networks. The stage service is `stage-chocoadmin` — **never rename it to `chocoadmin`**. Identical names cause DNS round-robin in `proxy-network`; NPM's `set $server "chocoadmin"` will randomly route requests to either container, mixing production and stage traffic. +- **Docker service names must be unique per environment**: Docker registers each `services:` key as a DNS alias in shared networks. The stage service is `chocoadmin-stage` — **never rename it to `chocoadmin`**. Identical names cause DNS round-robin in `proxy-network`; NPM's `set $server "chocoadmin"` will randomly route requests to either container, mixing production and stage traffic. - **Server actions must be module-level named exports**: Inline `action={async () => { "use server"; ... }}` closures get a new action ID on every build. After redeployment the browser sends the stale ID and Next.js responds `Failed to find Server Action`. Always extract to a top-level export in a separate `actions.ts` file (e.g. `app/(admin)/actions.ts`). - **After redeployment, reload NPM nginx**: Run `docker exec npm nginx -s reload` on the NAS to flush the upstream DNS cache. Without this NPM may continue routing to the previous container's IP. - **Extension requests** (`POST /api/maestros/[id]/extension-requests`) require `ActivateStatus = 2` (ACTIVE). Trial (1) and cancelled (100) accounts are rejected with 400. Approval (`PATCH /api/extension-requests/[id]`) re-checks `ActivateStatus` and throws 409 if not ACTIVE (transaction rolls back the atomic claim). diff --git a/docker-compose.stage.yml b/docker-compose.stage.yml index 2b61751..f2a0dac 100644 --- a/docker-compose.stage.yml +++ b/docker-compose.stage.yml @@ -1,12 +1,12 @@ services: # 서비스 이름은 Docker 네트워크 alias로 등록되므로 production(chocoadmin)과 겹치면 안 된다. # 겹치면 Docker DNS가 라운드로빈으로 두 컨테이너에 트래픽을 분산시킨다. - stage-chocoadmin: + chocoadmin-stage: build: context: . dockerfile: Dockerfile image: chocoadmin-stage:latest - container_name: stage-chocoadmin + container_name: chocoadmin-stage expose: - "3000" env_file: diff --git a/docs/deployment.md b/docs/deployment.md index a3fb352..28966a5 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -16,8 +16,8 @@ Stage example: DATABASE_URL="mysql://USER:PASSWORD@mariadb.jisangs.com:30001/chocomae" AUTH_SECRET="replace-with-stage-secret" NEXTAUTH_SECRET="replace-with-stage-secret" -AUTH_URL="https://stage-chocoadmin.jinaju.com" -NEXTAUTH_URL="https://stage-chocoadmin.jinaju.com" +AUTH_URL="https://chocoadmin-stage.jisangs.com" +NEXTAUTH_URL="https://chocoadmin-stage.jisangs.com" ``` Production file path: @@ -53,11 +53,11 @@ openssl rand -base64 32 Both production and stage share the same Git checkout at `/volume1/docker/service/jinaju/chocoadmin`. Pull from there: ```bash -cd /volume1/docker/service/jinaju/stage-chocoadmin +cd /volume1/docker/service/jinaju/chocoadmin-stage git pull --ff-only ``` -Stage uses `docker-compose.stage.yml`, the `stage-chocoadmin` container, and the external Docker network `proxy-network`. +Stage uses `docker-compose.stage.yml`, the `chocoadmin-stage` container, and the external Docker network `proxy-network`. Verify or create the network: @@ -86,7 +86,7 @@ docker exec npm nginx -s reload Nginx Proxy Manager settings: - Scheme: `http` -- Forward Hostname / IP: `stage-chocoadmin` +- Forward Hostname / IP: `chocoadmin-stage` - Forward Port: `3000` - Websockets Support: enabled - SSL: enabled @@ -95,7 +95,7 @@ Nginx Proxy Manager settings: Stage URL: ```text -https://stage-chocoadmin.jinaju.com +https://chocoadmin-stage.jisangs.com ``` After changing `AUTH_URL`, `NEXTAUTH_URL`, or cookie-related settings, clear browser cookies for the stage domain or test in a private window. @@ -198,9 +198,9 @@ Check the network: docker network inspect proxy-network --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}' ``` -Expected: `chocoadmin` and `stage-chocoadmin` appear with different IPs. If `chocoadmin` appears twice, a stale container is using that alias. +Expected: `chocoadmin` and `chocoadmin-stage` appear with different IPs. If `chocoadmin` appears twice, a stale container is using that alias. -Fix: ensure `docker-compose.stage.yml` has `services: stage-chocoadmin:` (not `chocoadmin`), redeploy stage once with `--remove-orphans` to clean up the stale container, then reload NPM. +Fix: ensure `docker-compose.stage.yml` has `services: chocoadmin-stage:` (not `chocoadmin`), redeploy stage once with `--remove-orphans` to clean up the stale container, then reload NPM. ### Failed to find Server Action after redeployment diff --git a/docs/phase/phase8.md b/docs/phase/phase8.md index 28e97a3..5ddea41 100644 --- a/docs/phase/phase8.md +++ b/docs/phase/phase8.md @@ -70,7 +70,7 @@ pnpm db:check 스테이지 도메인에서 비로그인 상태 또는 시크릿 창으로 확인한다. ```bash -curl -I https://stage-chocoadmin.jinaju.com/maestros +curl -I https://chocoadmin-stage.jisangs.com/maestros ``` 기대 결과: @@ -81,7 +81,7 @@ curl -I https://stage-chocoadmin.jinaju.com/maestros 브라우저에서 확인한다. -- `https://stage-chocoadmin.jinaju.com/login` +- `https://chocoadmin-stage.jisangs.com/login` - `/maestros` - `/extension-requests` - `/upgrade-requests` @@ -119,7 +119,7 @@ curl -I https://stage-chocoadmin.jinaju.com/maestros NAS에서 실행한다. ```bash -cd /volume1/docker/service/jinaju/stage-chocoadmin +cd /volume1/docker/service/jisangs/chocoadmin-stage docker compose -f docker-compose.stage.yml restart docker compose -f docker-compose.stage.yml ps docker compose -f docker-compose.stage.yml logs --tail=100 @@ -127,7 +127,7 @@ docker compose -f docker-compose.stage.yml logs --tail=100 기대 결과: -- `stage-chocoadmin` 컨테이너가 `Up` 상태다. +- `chocoadmin-stage` 컨테이너가 `Up` 상태다. - 로그에 Next.js ready 메시지가 출력된다. - 브라우저에서 로그인과 주요 목록 화면이 정상 동작한다. diff --git a/docs/plan/project-plan.md b/docs/plan/project-plan.md index e0b12e0..130aae8 100644 --- a/docs/plan/project-plan.md +++ b/docs/plan/project-plan.md @@ -570,7 +570,7 @@ chocoadmin/ - [x] **포트 충돌 수정** (`docker-compose.yml`) - Gitea가 호스트 3000 포트를 선점 → `ports: "3000:3000"` → `expose: "3000"` 으로 변경 - [x] **Docker DNS alias 충돌 수정** (`docker-compose.stage.yml`) - - `services: chocoadmin:` → `services: stage-chocoadmin:` 으로 변경 + - `services: chocoadmin:` → `services: chocoadmin-stage:` 으로 변경 - 동일 서비스명은 `proxy-network`에서 같은 DNS alias로 등록됨 - NPM의 `set $server "chocoadmin"` 이 두 컨테이너에 라운드로빈 → 트래픽이 production/stage 사이에 무작위 분산 - [x] **NextAuth v5 커스텀 쿠키 이름으로 production/stage 쿠키 분리** diff --git a/scripts/deploy-stage.sh b/scripts/deploy-stage.sh index 0797e4a..c3ac6ad 100755 --- a/scripts/deploy-stage.sh +++ b/scripts/deploy-stage.sh @@ -6,13 +6,13 @@ YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' -DEPLOY_DIR="/volume1/docker/service/jinaju/stage-chocoadmin" +DEPLOY_DIR="/volume1/docker/service/jisangs/chocoadmin-stage" COMPOSE_FILE="docker-compose.stage.yml" -SERVICE="stage-chocoadmin" -URL="https://stage-chocoadmin.jinaju.com" +SERVICE="chocoadmin-stage" +URL="https://chocoadmin-stage.jisangs.com" echo -e "${BLUE}==============================${NC}" -echo -e "${BLUE} stage-chocoadmin 배포${NC}" +echo -e "${BLUE} chocoadmin-stage 배포${NC}" echo -e "${BLUE}==============================${NC}" echo -e "\n${YELLOW}[1/5] 디렉토리 이동${NC}"