======================================================================== 研究室サーバデプロイ手順書 (Lab Server Deployment Guide) ======================================================================== 1. 概要 (Overview) ------------------------------------------------------------------------ 本ドキュメントは,Pixel Paint War を1台の研究室サーバ上に本番デプロイする 手順をまとめたものである. Nginx をリバースプロキシとして使用し,外部公開ポートは 8803 のみとする. フロントエンド(静的ファイル)とバックエンド(Socket.IO)は同一サーバ内で ポートを分けて動作させ,外部デバイスは Nginx 経由でのみ通信する. 1-1. 構成図 [デバイス] ──HTTP(8803)──▶ [Nginx (:8803)] ├── / → 静的ファイル配信(Viteビルド済み) └── /socket.io → proxy_pass http://127.0.0.1:3000 (サーバ内部のみ,外部非公開) ・外部公開ポート: 8803 のみ ・バックエンド(ポート3000)は localhost バインドで外部アクセス不可 ・HTTPS化する場合は Nginx で SSL 終端を行う(6章参照) 2. 前提条件 (Prerequisites) ------------------------------------------------------------------------ 2-1. サーバ環境 ・OS: Linux(Ubuntu 20.04 以上推奨) ・Docker / Docker Compose がインストール済みであること ・Nginx がインストール済みであること ・Git がインストール済みであること ・ポート 8803 がファイアウォールで許可されていること 2-2. 確認コマンド $ docker --version $ docker compose version $ nginx -v $ git --version 3. デプロイ手順 (Deployment Steps) ------------------------------------------------------------------------ 3-1. リポジトリの取得 1. サーバ上で任意のディレクトリにクローンする $ git clone <リポジトリURL> /opt/pixel-paint-war $ cd /opt/pixel-paint-war 2. デプロイ対象のブランチ・タグに切り替える $ git checkout main $ git pull origin main 3-2. フロントエンドのビルド フロントエンドは静的ファイルとしてビルドし,Nginx から配信する. VITE_PROD_SERVER_URL にはデバイスからアクセスする URL を指定する. ■ ローカルネットワーク(HTTP)の場合 $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ bash -c "corepack enable && pnpm install --frozen-lockfile \ && pnpm --filter @repo/shared build \ && VITE_PROD_SERVER_URL=http://<サーバIP>:8803 pnpm --filter client build" ■ ドメイン運用(HTTPS)の場合 $ docker run --rm -v $(pwd):/app -w /app node:20-slim \ bash -c "corepack enable && pnpm install --frozen-lockfile \ && pnpm --filter @repo/shared build \ && VITE_PROD_SERVER_URL=https://yourdomain.example.com:8803 pnpm --filter client build" ※ ビルド成果物は apps/client/dist/ に出力される 3-3. バックエンドの起動(Docker Compose) 本番用の docker-compose.prod.yml を使用してバックエンドを起動する. ポートは localhost バインドとし,Nginx 経由でのみアクセスさせる. 1. docker-compose.prod.yml を以下の内容に編集する services: game-server: build: context: . dockerfile: Dockerfile container_name: pixel-paint-server-prod restart: unless-stopped ports: - "127.0.0.1:3000:3000" environment: - NODE_ENV=production ※ ポイント: ports を "127.0.0.1:3000:3000" にすることで, localhost からのみアクセス可能となり外部に直接公開されない 2. コンテナをビルド・起動する $ docker compose -f docker-compose.prod.yml up -d --build 3. 起動確認 $ docker compose -f docker-compose.prod.yml ps STATUS が「Up」になっていることを確認する 4. ヘルスチェック $ curl http://127.0.0.1:3000 「ok」と返れば正常 3-4. Nginx の設定 Nginx の設定ファイルを作成し,ポート 8803 でリクエストを受け付ける. 1. 設定ファイルを作成する $ sudo vi /etc/nginx/sites-available/pixel-paint-war 2. 以下の内容を記述する server { listen 8803; server_name _; # フロントエンド(静的ファイル配信) root /opt/pixel-paint-war/apps/client/dist; index index.html; location / { try_files $uri $uri/ /index.html; } # バックエンド(Socket.IO → 内部ポート3000へプロキシ) location /socket.io/ { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } 3. シンボリックリンクを作成して有効化する $ sudo ln -s /etc/nginx/sites-available/pixel-paint-war /etc/nginx/sites-enabled/ 4. 設定の文法チェック $ sudo nginx -t 「syntax is ok」「test is successful」と表示されること 5. Nginx を再起動する $ sudo systemctl restart nginx 3-5. 動作確認 1. ブラウザからアクセスする http://<サーバIP>:8803 2. ゲーム画面が表示され,ルーム作成・参加が正常に動作することを確認する 3. バックエンドへの直接アクセスが遮断されていることを確認する $ curl http://<サーバIP>:3000 → 接続拒否またはタイムアウトになること 4. ファイアウォール設定 (Firewall) ------------------------------------------------------------------------ 外部に公開するポートを 8803 のみに制限する. 4-1. ufw を使用する場合 $ sudo ufw allow 8803/tcp $ sudo ufw deny 3000/tcp $ sudo ufw enable $ sudo ufw status 4-2. 確認事項 ・ポート 8803: 外部からアクセス可能であること ・ポート 3000: 外部からアクセス不可であること ・SSH ポート(22): 許可済みであること(ロックアウト防止) 5. 運用コマンド (Operations) ------------------------------------------------------------------------ 5-1. 基本操作 ■ バックエンドの状態確認 $ docker compose -f docker-compose.prod.yml ps ■ ログ確認(リアルタイム) $ docker compose -f docker-compose.prod.yml logs -f ■ バックエンドの停止 $ docker compose -f docker-compose.prod.yml down ■ バックエンドの再起動 $ docker compose -f docker-compose.prod.yml restart ■ Nginx の状態確認 $ sudo systemctl status nginx 5-2. アップデート手順 コードを更新して再デプロイする場合の手順. 1. 最新コードを取得する $ cd /opt/pixel-paint-war $ git pull origin main 2. フロントエンドを再ビルドする(3-2 の手順を再実行) 3. バックエンドを再ビルド・再起動する $ docker compose -f docker-compose.prod.yml up -d --build 4. Nginx を再読み込みする(設定変更がある場合のみ) $ sudo systemctl reload nginx 5-3. キャッシュクリア再ビルド ビルドキャッシュが原因で問題が発生する場合に実行する. $ docker compose -f docker-compose.prod.yml build --no-cache $ docker compose -f docker-compose.prod.yml up -d --force-recreate 6. HTTPS化(任意) (HTTPS Setup) ------------------------------------------------------------------------ ドメインを使用して HTTPS でアクセスさせる場合の追加手順. 6-1. Let's Encrypt で証明書を取得する $ sudo apt install certbot python3-certbot-nginx $ sudo certbot --nginx -d yourdomain.example.com 6-2. Nginx 設定を HTTPS 対応に変更する server { listen 8803 ssl; server_name yourdomain.example.com; ssl_certificate /etc/letsencrypt/live/yourdomain.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.example.com/privkey.pem; root /opt/pixel-paint-war/apps/client/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /socket.io/ { proxy_pass http://127.0.0.1:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } 6-3. 証明書の自動更新を確認する $ sudo certbot renew --dry-run 7. トラブルシューティング (Troubleshooting) ------------------------------------------------------------------------ 7-1. ブラウザでゲーム画面が表示されない ・Nginx のエラーログを確認する $ sudo tail -50 /var/log/nginx/error.log ・静的ファイルのパスが正しいか確認する $ ls /opt/pixel-paint-war/apps/client/dist/index.html 7-2. Socket.IO 接続がエラーになる ・バックエンドコンテナが起動しているか確認する $ docker compose -f docker-compose.prod.yml ps ・ローカルからバックエンドに疎通できるか確認する $ curl http://127.0.0.1:3000 ・Nginx のプロキシ設定で WebSocket ヘッダーが正しいか確認する 7-3. ポート 8803 にアクセスできない ・ファイアウォールでポート 8803 が許可されているか確認する $ sudo ufw status ・Nginx がポート 8803 で listen しているか確認する $ sudo ss -tlnp | grep 8803