Newer
Older
PixelPaintWar / docs / 01_Env / ENV_08_研究室サーバデプロイ手順書.txt
========================================================================
研究室サーバデプロイ手順書 (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