MENU
  • ホームHOME
  • スマートホームSmart Home
    • スマートリモコン
    • スマートライト
    • スマートロック
    • スマートカメラ
    • スマートセンサー
    • スマートスピーカー
    • IoT家電
    • ロボット掃除機
  • ガジェットGadgets
    • iPhone & iPad
    • アップルウォッチ
    • パソコン関連
    • 充電器/モバイルバッテリー
    • キーボードマウス
    • アプリソフト関連
    • カメラ
    • オーディオその他
  • 生活家電&インテリアAppliances
    • Wi-Fiルーター
    • PCモニター
    • デスク関連
    • モバイル&光回線
    • その他家電
  • ライフLife Style
    • ニュース
    • ライフハック
    • 便利なサービス
    • プログラミング
    • コラム
    • ブログ運営
  • 勉強アプリEducation
    • ビジネス資格
      • ビジネスマネジャー検定
      • MCPC IoT検定 中級対応
      • MCPCモバイルシステム技術
    • DIGI Radio
      (特設サイト)
      • 一陸技アプリ
      • 一陸特アプリ
      • 二陸特アプリ
      • 工事担任者(総合通信)アプリ
    • クラウド系アプリ
      • AWS SAAアプリ
      • AZ-900勉強アプリ
      • AI-900勉強アプリ
    • 宅建学習サイト
  • まとめ記事Summary
  • お問合せContact
    • 勉強アプリ専用フィードバックフォーム
ガジェット&お得なサービス情報をお届けするブログメディア「デジライン」
DIGILINE (デジライン)
  • ホームHOME
  • スマートホームSmart Home
    • スマートリモコン
    • スマートライト
    • スマートロック
    • スマートカメラ
    • スマートセンサー
    • スマートスピーカー
    • IoT家電
    • ロボット掃除機
  • ガジェットGadgets
    • iPhone & iPad
    • アップルウォッチ
    • パソコン関連
    • 充電器/モバイルバッテリー
    • キーボードマウス
    • アプリソフト関連
    • カメラ
    • オーディオその他
  • 生活家電&インテリアAppliances
    • Wi-Fiルーター
    • PCモニター
    • デスク関連
    • モバイル&光回線
    • その他家電
  • ライフLife Style
    • ニュース
    • ライフハック
    • 便利なサービス
    • プログラミング
    • コラム
    • ブログ運営
  • 勉強アプリEducation
    • ビジネス資格
      • ビジネスマネジャー検定
      • MCPC IoT検定 中級対応
      • MCPCモバイルシステム技術
    • DIGI Radio
      (特設サイト)
      • 一陸技アプリ
      • 一陸特アプリ
      • 二陸特アプリ
      • 工事担任者(総合通信)アプリ
    • クラウド系アプリ
      • AWS SAAアプリ
      • AZ-900勉強アプリ
      • AI-900勉強アプリ
    • 宅建学習サイト
  • まとめ記事Summary
  • お問合せContact
    • 勉強アプリ専用フィードバックフォーム
DIGILINE (デジライン)
  • ホームHOME
  • スマートホームSmart Home
    • スマートリモコン
    • スマートライト
    • スマートロック
    • スマートカメラ
    • スマートセンサー
    • スマートスピーカー
    • IoT家電
    • ロボット掃除機
  • ガジェットGadgets
    • iPhone & iPad
    • アップルウォッチ
    • パソコン関連
    • 充電器/モバイルバッテリー
    • キーボードマウス
    • アプリソフト関連
    • カメラ
    • オーディオその他
  • 生活家電&インテリアAppliances
    • Wi-Fiルーター
    • PCモニター
    • デスク関連
    • モバイル&光回線
    • その他家電
  • ライフLife Style
    • ニュース
    • ライフハック
    • 便利なサービス
    • プログラミング
    • コラム
    • ブログ運営
  • 勉強アプリEducation
    • ビジネス資格
      • ビジネスマネジャー検定
      • MCPC IoT検定 中級対応
      • MCPCモバイルシステム技術
    • DIGI Radio
      (特設サイト)
      • 一陸技アプリ
      • 一陸特アプリ
      • 二陸特アプリ
      • 工事担任者(総合通信)アプリ
    • クラウド系アプリ
      • AWS SAAアプリ
      • AZ-900勉強アプリ
      • AI-900勉強アプリ
    • 宅建学習サイト
  • まとめ記事Summary
  • お問合せContact
    • 勉強アプリ専用フィードバックフォーム
\ ポイント最大11倍! /
  1. ホーム
  2. ライフ
  3. プログラミング
  4. カラフルボックスでFastAPIを動かすまでに踏んだ地雷すべて

カラフルボックスでFastAPIを動かすまでに踏んだ地雷すべて

2026 1/07
プロモーションを含みます
プログラミング


Python の Web フレームワークである FastAPI は、手軽に高性能な API を構築できることから人気が高まっています。

しかし、安価な共用レンタルサーバーで FastAPI を公開しようとすると想像以上にハードルが高く、多くの落とし穴にはまります。

私もよく使っているWordpress用のVPSとして有名なのが「カラフルボックス (ColorfulBox)」なんですが、このサーバ機能(cPanel)でPython Appを動作させることができるのですが、これが意外と難しいというかクセがあるんですよね。

元々そんな構成での動作を想定してないと言われてしまえば、それでおしまいなんですが、やはり個人開発者としては”どうにかする”というのが醍醐味ですよね。

ということで、今回はカラフルボックスの共用サーバー環境に FastAPI をデプロイするまでに遭遇したエラーや設定ミスをすべてまとめました。

同じように挑戦する方の参考になれば幸いです。

環境概要

  • サーバー: ColorfulBox 共用サーバー (cPanel 環境 / LiteSpeed + Passenger)
  • アプリケーション: FastAPI (Python 3.11)
  • デプロイ方法: GitHub Actions からサーバーに SSH で git pull → Python 依存アップデート → アプリ起動
  • 公開ポート: FastAPI はローカルでポート 8080 に起動し、Web サーバーがリバースプロキシとして /api/ パスや /docs 等を中継する

ColorfulBox の「Python アプリケーション」機能は Passenger (mod_passenger) を使い、passenger_wsgi.py をエントリーポイントとして Python アプリを起動します。

FastAPI を通常どおり uvicorn で起動するときとは違う点が多く、uvicorn が起動しない、.htaccess のリライトルールで API にアクセスできない などのトラブルが発生しました。

1. 初期設定と基本構成

まずは cPanel の「Setup Python App」で Python アプリを作成し、仮想環境と起動スクリプトを準備します。

FastAPI は WSGI アプリではなく ASGI アプリなので、Passenger だけでは起動できません。

代わりに uvicorn をバックグラウンドで起動し、Passenger は単なる「ブートストラップ」的な挨拶を返すだけにします。

項目入力例説明
Application rootpublic_html/DOMAIN/app

Fast APIのmain.pyがある場所
FastAPI プロジェクトのルートディレクトリ。ColorfulBox/cPanel のホームディレクトリからのパスを指定します。お使いの環境に合わせてパスを読み替えてください。
Application URLDOMAIN

ドメイン移行は任意
事前に設定しておいたアプリケーション用サブドメインを選択します。
Application startup filepassenger_wsgi.pyWSGI エントリーポイントが定義されているファイル名を入力します。今回の構成では passenger_wsgi.py です。
Application Entry pointapplicationpassenger_wsgi.py 内で定義した WSGI callable 名を入力します。サンプルでは application 関数を返すように定義してあります。

passenger_wsgi.py の最終的な形は次のようになりました。

"""WSGI entrypoint for cPanel/Passenger.

Uvicorn は別プロセスで起動するため、このファイルは単に生存確認用のレスポンスを返します。
"""

def application(environ, start_response):
    start_response("200 OK", [("Content-Type", "text/plain")])
    return [b"passenger ok"]

当初はこの passenger_wsgi.py 内で uvicorn を起動しようとしましたが、デプロイ時に旧プロセスを止められなかったり、2 重起動してポート競合を起こすなど問題が多かったため、最終的には GitHub Actions 側で起動・停止を制御 する方式に落ち着きました。

環境変数の設定(必要に応じて)

  • OPENAI_API_KEY や SUPABASE_URL など、FastAPI アプリが必要とする設定を「Environment variables」に追加してください。
  • cPanel の変数名と値を入力するフォームから追加できます。

2. .htaccess の落とし穴

WordPress やフロントエンドアプリと同居させるために、public_html/DOMAIN/ 直下に React の SPA や静的ファイルが置かれていました。

そのため、.htaccess で以下のようなルールを設定していました。

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  # 静的ファイルが存在する場合はそのまま配信
  RewriteCond %{REQUEST_FILENAME} -f [OR]
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^ - [L]
  # それ以外のリクエストは uvicorn へ転送
  RewriteRule ^api/(.*)$ http://127.0.0.1:8080/api/$1 [P,L]
  # SPA 用にその他のパスは /index.html へ
  RewriteRule ^ /index.html [L]
</IfModule>

ここでつまずいた点は以下です。

  • RewriteRule ^ /index.html が API エンドポイント /docs などを上書きしてしまい、FastAPI のドキュメントが 404 になる。API へのパスより前に SPA のリダイレクトを書いてしまうと必ず /index.html が返ってしまいました。
  • LiteSpeed + mod_rewrite では大文字小文字や先頭スラッシュの扱いが Apache と微妙に異なり、意図したとおりに動かないことがある。今回は /api/ というプレフィックスを決め打ちし、他は静的ファイルと見なすようにしました。

結論としては、API 用のパスを必ず最上位にマッチさせることと、SPA のリダイレクトはそれ以外のパスだけに適用することが重要です。

3. uvicorn が起動しない!

最初は passenger_wsgi.py 内で subprocess.Popen を使って uvicorn を起動するコードを採用しました。

以下のような内容です。

from pathlib import Path
import subprocess, os, socket

BASE_DIR = Path(__file__).resolve().parent
BACKEND_DIR = BASE_DIR / "backend"
TMP_DIR = BASE_DIR / "tmp"
UVICORN = "/home/user/virtualenv/…/bin/uvicorn"
HOST, PORT = "127.0.0.1", 8080

# 既にリッスンしているか確認し、していなければ uvicorn を起動
if not is_listening(HOST, PORT):
    TMP_DIR.mkdir(parents=True, exist_ok=True)
    p = subprocess.Popen([UVICORN, "main:app", "--host", HOST, "--port", str(PORT)],
                         cwd=str(BACKEND_DIR),
                         stdout=subprocess.DEVNULL,
                         stderr=subprocess.DEVNULL,
                         start_new_session=True)
    (TMP_DIR / "uvicorn.pid").write_text(str(p.pid))

この方法は一見うまく動きますが、デプロイのたびに Passenger がプロセスを fork するため、古い uvicorn が残ったまま新しい uvicorn が起動してポートが重複するケースが頻発しました。

また、開発中に手作業で kill する必要があり、CI/CD の自動化から遠ざかっていました。

解決策: デプロイ時にだけ uvicorn を起動

最終的に、uvicorn の起動・停止はすべて GitHub Actions 上のスクリプトで処理し、Passenger は「起動していることを前提」に単に 200 OK を返すだけにしました。こうすることで:

  • デプロイ時に確実に古いプロセスを停止できる。
  • 起動コマンドやポート設定を Actions で一元管理できる。
  • Passenger のプロセス管理と uvicorn のプロセス管理が分離できる。

後述する deploy.yml を参照してください。

4. GitHub Actions での自動デプロイとプロセス管理

デプロイは GitHub の main ブランチへ push したときに自動実行されます。

あわせて読みたい
カラフルボックスのサーバを GitHub Actions で自動デプロイする手順まとめ WordPress プラグインやテーマをカラフルボックス上で運用していて、ローカル → GitHub → サーバへのデプロイを手動 SSH + git pullでやっていると、 だんだん面倒にな…

CI のジョブはサーバーに SSH してリポジトリを更新し、依存パッケージをインストールし、必要なら uvicorn を再起動します。以下が最終的な deploy.yml のスクリプトです(一部省略)。

name: Deploy to ColorfulBox via git pull

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Prepare SSH key
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_KEY }}" > ~/.ssh/id_xxxxx
          chmod 600 ~/.ssh/id_xxxxx
          ssh-keyscan -p "${{ secrets.SSH_PORT }}" "${{ secrets.SSH_HOST }}" >> ~/.ssh/known_hosts

      - name: Deploy on server
        run: |
          ssh -p "${{ secrets.SSH_PORT }}" "${{ secrets.SSH_USER }}"@"${{ secrets.SSH_HOST }}" << 'EOF'
            set -e
            APP_DIR=/home/USER/public_html/DOMAIN/app/
            PIDFILE=$APP_DIR/tmp/uvicorn.pid

            cd "$APP_DIR"
            git fetch origin
            git reset --hard origin/main
            git clean -fd

            # Python 依存の更新
            VENV_BIN=/home/USER/virtualenv/public_html/DOMAIN/app/3.11/bin
            "$VENV_BIN/pip" install --upgrade pip
            "$VENV_BIN/pip" install -r requirements.txt

            # 既存 uvicorn プロセスの停止
            stop_pid() {
              _pid="$1"
              if [ -n "$_pid" ] && kill -0 "$_pid" 2>/dev/null; then
                kill "$_pid" || true
                sleep 1
                if kill -0 "$_pid" 2>/dev/null; then
                  kill -9 "$_pid" || true
                fi
              fi
            }

            if [ -f "$PIDFILE" ]; then
              PID=$(cat "$PIDFILE" || true)
              stop_pid "$PID"
              rm -f "$PIDFILE"
            else
              PIDS=$(pgrep -f "uvicorn main:app.*--host 127\.0\.0\.1.*--port 8080" || true)
              if [ -n "$PIDS" ]; then
                for PID in $PIDS; do
                  stop_pid "$PID"
                done
              fi
            fi

            # uvicorn をバックグラウンドで起動
            mkdir -p "$APP_DIR/tmp"
            cd "$APP_DIR/backend"
            nohup "$VENV_BIN/python" -m uvicorn main:app --host 127.0.0.1 --port 8080 \
              >> "$APP_DIR/tmp/uvicorn.out.log" 2>> "$APP_DIR/tmp/uvicorn.err.log" &
            echo $! > "$PIDFILE"

            # 起動確認 (ローカル) – 最大 40 秒待つ
            for i in $(seq 1 40); do
              if curl -fsS http://127.0.0.1:8080/health >/dev/null; then
                echo "uvicorn health ok"
                break
              fi
              echo "uvicorn not ready (attempt $i)"
              sleep 1
            done

            # 公開エンドポイントの確認 – Web サーバー側のプロキシ設定によっては時間がかかる
            for i in $(seq 1 20); do
              if curl -fsS https://DOMAIN/health >/dev/null; then
                echo "public health ok"
                break
              fi
              echo "public health not ready (attempt $i)"
              sleep 2
            done
          EOF

主なポイントは次のとおりです。

  • git reset –hard + git clean -fd でサーバー側の作業ディレクトリをリセットしています。これは乗っ取り対策と不要ファイルの残存による衝突を防ぐために重要です。
  • 依存パッケージは常に pip install -r requirements.txt で更新します。ColorfulBox の仮想環境は Python バージョン毎に異なるパスにあるため VENV_BIN をハードコードしています。
  • プロセス管理は PIDFILE があればそれを優先し、ない場合は pgrep で uvicorn main:app を検索して全て kill します。これで二重起動やゾンビ化したプロセスを排除します。
  • nohup で uvicorn をバックグラウンド起動し、PID を書き出します。標準出力・標準エラーは tmp ディレクトリにログとして保存し、デバッグに利用できます。
  • 起動直後に /health エンドポイントへ curl して正常に起動しているか確認し、さらに公開 URL 経由でも確認しています。

これにより、デプロイ後は常に新しい uvicorn プロセスが 8080 で待ち受けており、Passenger がリクエストを適切に転送してくれます。

5. よく踏んだその他の地雷

Passenger と環境変数の自動書き換え

ColorfulBox の cPanel では、「Setup Python App」で設定した環境変数が自動的に .htaccess や passenger_wsgi.py に埋め込まれます。

知らないうちにエントリポイントや環境変数が書き換えられてしまい、「変更したはずのファイルが元に戻っている」という現象がありました。

重要な設定ファイルは Git 管理下に置き、cPanel からは編集しないようにすると安心です。

Git の強制上書き

deploy.yml で git pull を行っていた際、サーバー側で手作業で編集したファイル (passenger_wsgi.py など) が競合して merge に失敗し、自動デプロイが止まってしまうことがありました。

そのため、git reset –hard origin/main で常にリモートを優先するようにしています。

サーバー側を手動編集する場合は必ずローカルリポジトリに戻しましょう。

cron で uvicorn を監視する必要はない

当初は uvicorn を永続化させるために cron で定期的に curl /health を叩いて、生存確認に失敗したら再起動するバッチスクリプトを検討しました。

しかし、Passenger は各リクエストごとに passenger_wsgi.py をロードし直すため、ロードのタイミングで uvicorn が停止していれば再起動が必要になってしまいます。

GitHub Actions での起動をしっかり行うことで cron の監視が不要になりました。

万が一 uvicorn が落ちたら WordPress から 503 が返るため、手動で再デプロイすれば解決します。

6. まとめと教訓

ColorfulBox の共用サーバー上で FastAPI を稼働させるまでに、数々の罠にはまりました。まとめると次のような教訓があります。

  • Passenger では ASGI を直接扱えないので、uvicorn などでプロセスを起動する必要がある。
  • .htaccess のリライトルールは API ルートを最優先し、SPA 用リダイレクトは後ろに書く。
  • passenger_wsgi.py で uvicorn を起動すると複数プロセスが残るため、デプロイ側で起動・停止を制御する方法が安定する。
  • GitHub Actions を使う場合は git reset –hard + git clean で競合を防ぎ、依存更新とプロセス再起動を一連の作業に組み込む。
  • 共用サーバーでは cPanel の自動書き換えや環境変数の扱いに注意し、重要ファイルは Git 管理下で上書きを防ぐ。

この記事が同じような構成で FastAPI をホスティングしたい人の助けとなれば幸いです。

カラフルボックスに限らず、Passenger 環境で ASGI アプリを動かす際には「誰がどこで uvicorn を起動し、どこで停止するのか」を整理することが成功の鍵です。

プログラミング

この記事が気に入ったら
いいね または フォローしてね!

Follow @digiline_ Follow Me
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Takaのアバター Taka

AI業務自動化エンジニア / IoTコンサルタント / ガジェットブロガー

AIとIoTの技術を組み合わせ、スマートホーム構築・業務自動化・ガジェット活用を中心に情報発信と技術支援を行っています。
最新デバイスの検証やレビューだけでなく、実際に生活に組み込み、効率的でストレスのない暮らしを実現するための具体的なノウハウを提供しています。

自宅を“テックハブ”として運用しながら、AIエージェント、IoTデバイス、クラウドサービスを連携させた実験的な取り組みも継続中。
技術の進化を生活に落とし込み、「明日から使えるスマートな暮らし」を読者のみなさんと一緒に作っていくことを目指しています。

関連記事

  • カラフルボックスのサーバを GitHub Actions で自動デプロイする手順まとめ
    2026年1月7日
  • 【2026年1月版 最新価格】Amazon スマイルSALEでおすすめのガジェット&セール製品|お得に買える攻略方法も紹介。
    2026年1月1日
  • 【徹底比較】楽天モバイル従業員紹介 vs 三木谷紹介キャンペーンどっちがお得?
    2025年12月26日
  • 愛犬の「歩く辛さ」を軽減:シニア犬の移動を支える犬用モビリティ製品最前線
    2025年11月23日
  • TS-464メモリ増設:メモリ16GBでUIは爆速、読み込み速度はそのまま
    2025年11月1日
  • 【レビュー】QNAP TS-464|パワフルNASだからパソコン&スマホのバックアップ先はこれ1つで十分
    2025年11月1日
  • GPT‑4.1 mini と GPT‑5 mini/nano のコスト・性能比較
    2025年10月25日
  • クリックが効かないMX Master 3sを自分で直してみた【スイッチ交換記録】
    2025年10月21日

コメント

コメントする コメントをキャンセル

人気記事
  • IKEA TRADRI(トロードフリ)のリモコン/センサーが反応しない!?電球がペアリングできないときの復旧方法
    ライフハック
  • iPhoneの電池の減りが異常に早いのでバッテリー交換しに行ったら断れた話。AppleCare+未加入の人は注意しよう!
    便利なサービス
  • セゾンカードの携行品保険ならスマホもパソコンも保証!月300円のスマホ補償付きお買い物安心プラン[Y]がコスパ最強!
    保険のこと
  • iPhoneのフィールドテストモード。隠しコマンドを入れたらこうなるなんて!?【専門家が解説】
    ライフハック
  • Apple Watch (アップルウォッチ)向けの保険としてapplecare+はいらないよ
    保険のこと
新着記事
  • カラフルボックスでFastAPIを動かすまでに踏んだ地雷すべて
    2026年1月7日
  • 【徹底比較】楽天モバイル従業員紹介 vs 三木谷紹介キャンペーンどっちがお得?
    2025年12月26日
  • 愛犬の「歩く辛さ」を軽減:シニア犬の移動を支える犬用モビリティ製品最前線
    2025年11月23日
  • カラフルボックスのサーバを GitHub Actions で自動デプロイする手順まとめ
    2025年11月19日
  • TS-464メモリ増設:メモリ16GBでUIは爆速、読み込み速度はそのまま
    2025年10月31日
目次
DIGILINEオススメのサービス
TAKA
メディア監修
AI業務自動化エンジニア / IoTコンサルタント / ガジェットブロガー

AIとIoTの技術を組み合わせ、スマートホーム構築・業務自動化・ガジェット活用を中心に情報発信と技術支援を行っています。
最新デバイスの検証やレビューだけでなく、実際に生活に組み込み、効率的でストレスのない暮らしを実現するための具体的なノウハウを提供しています。

自宅を“テックハブ”として運用しながら、AIエージェント、IoTデバイス、クラウドサービスを連携させた実験的な取り組みも継続中。
技術の進化を生活に落とし込み、「明日から使えるスマートな暮らし」を読者のみなさんと一緒に作っていくことを目指しています。
新着記事
  • カラフルボックスでFastAPIを動かすまでに踏んだ地雷すべて
  • 【徹底比較】楽天モバイル従業員紹介 vs 三木谷紹介キャンペーンどっちがお得?
  • 愛犬の「歩く辛さ」を軽減:シニア犬の移動を支える犬用モビリティ製品最前線
  • カラフルボックスのサーバを GitHub Actions で自動デプロイする手順まとめ
記事を探す
メーカーで探す
+style Aiseesoft Amazon Anker Apple Aqara BenQ(ベンキュー) BLUETTI Bose Buffalo Coomooy DJI EaseUS FlexiSpot(フレキシースポット) Garmin(ガーミン) Google GoPro Hysure IKEA Insta360 iRobot j5create Logicool MiniTool MOFT(モフト) MovPilot MUJI Narwal Nature QNAP Qrio(キュリオ) Quntis Rakuten Satechi(サテチ) SwitchBot(スイッチボット) tile TP-Link(ティーピーリンク) Tranya UGREEN Ulanzi Ulike VOLTME Zenosyne お得情報 まとめ
  • DIGI LINE(デジライン)について
  • お仕事の依頼
  • 特定商取引法に関する表記
  • 免責事項/プライバシーポリシー
  • お問合せ

© DIGILINE (デジライン)

目次