MENU

XserverレンタルサーバーでPython(Flask)のWEBアプリを動かす

先日、エックスサーバーのレンタルサーバーにPython(Flask)で開発したWebアプリをデプロイしたので、その方法をメモ。

XServer レンタルサーバーではWSGIは使えないので、CGIHandlerを使ってPythonを起動する方法です。

毎回Python起動 → Flask読み込み → アプリ初期化 というオーバーヘッドが発生するので「遅いけど動く」状態です。今回デプロイしたアプリ用途は、少人数で使用する管理用の小さなツール(API呼び出し)だったので十分実用的と判断しました。

今回のデプロイ環境

  • サーバー:XServer レンタルサーバー
  • URL:https://example.com/myapp (ディレクトリ)
  • Python:3.13系
  • フレームワーク:Flask

デプロイには、XServer レンタルサーバーへSSH接続が必要となります。SSH接続については以下の記事を参考にしてください。

目次

ディレクトリ構造の準備

アプリを配置するディレクトリを準備しておきます。

アプリURLを https://example.com/myapp としたいので、該当ドメインのドキュメントルートに myapp ディレクトリを作成します。

SSH接続して以下でも作成できます。

# ドメインのドキュメントルートにアプリ用ディレクトリを作成
$ mkdir -p ~/example.com/public_html/myapp

今回デプロイするPython(Flask)でつくったWebアプリのディレクトリ構造(※一部)

/home/your-server-id/example.com/public_html/myapp/
├── .env                   # 環境変数
├── .htaccess              # Apache設定(※後述)
├── index.cgi              # CGIエントリーポイント(※後述)
├── app.py                 # Flaskアプリ本体
├── config.py              # 設定ファイル
├── その他Pythonファイル
├── requirements.txt       # 必要なパッケージリスト
├── templates/             # HTMLテンプレート
│   └── upload.html
└── temp/                  # 一時ファイル保存用

アプリのファイルたちはFTPクライアントでアップロードします。

# 権限に注意!
chmod 600 .env

SSH接続とMinicondaをインストール(初回のみ)

エックスサーバーのレンタルサーバーではroot権限がないため、SSH接続して、ユーザー環境にMinicondaをインストールします。(初回のみの作業です)

SSH接続後、ホームディレクトリで以下を実行します。

# ダウンロード・インストール
$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ bash Miniconda3-latest-Linux-x86_64.sh

# Please, press ENTER to continue
# >>> [Enterキーを押します]

# Do you accept the license terms? [yes|no]
# >>> yes

# Miniconda3 will now be installed into this location:
# /home/hogehoge/miniconda3
#
#   - Press ENTER to confirm the location
#   - Press CTRL-C to abort the installation
#   - Or specify a different location below
#
# [/home/hogehoge/miniconda3] >>> yes(場所を変える場合は適宜対応を)

# You can undo this by running `conda init --reverse $SHELL`? [yes|no]
# [no] >>> yes

インストールが始まります。途中、いくつか聞かれるので以下のとおり。

  • ライセンス規約:yes
  • インストール場所:デフォルトのままEnter
  • 初期化:yes

インストールが終了したら、設定の再読み込みを行います。

# 設定の再読み込み
$ source ~/.bashrc

# 以下のように表示されていればOK
(base)[hogehoge@svXXXX ~]$  

念のため、以下のコマンドで動作しているか確認してみます。バージョンが出力されれば問題ありません。

(base)[hogehoge@svXXXX ~]$ conda --version
conda 25.7.0
(base)[hogehoge@svXXXX ~]$ python --version
Python 3.13.5

仮想環境を作成

配置したいWEBアプリのPythonのバージョンを確認し、仮想環境を作成します。
仮想環境の作成はホームディレクトリ(ルート)で行います。
(ここからは (base)[hogehoge@svXXXX ~]$ を省略します)

conda create -n my_ve_py python=3.13 -y

my_ve_py は仮想環境の名前です(任意)

仮想環境の作成時に以下のようなエラーが出る場合があります。Anacondaの利用規約に同意する必要があるというエラーメッセージです。メッセージ内にあるコマンドをそのまま実行すれば解決します。

CondaToSNonInteractiveError: Terms of Service have not been accepted for the following channels. Please accept or remove them before proceeding:
    - https://repo.anaconda.com/pkgs/main
    - https://repo.anaconda.com/pkgs/r

To accept these channels' Terms of Service, run the following commands:
    conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
    conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r

For information on safely removing channels from your conda configuration,
please see the official documentation:

    https://www.anaconda.com/docs/tools/working-with-conda/channels
# 利用規約に同意
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r

仮想環境をアクティベートし、必要なパッケージのインストールを行います。アプリに必要なパッケージをrequirements.txtにしておくと便利。

# 仮想環境をアクティベート
conda activate my_ve_py

# アプリディレクトリに移動
cd example.com/public_html/myapp

# 必要パッケージのインストール
pip install -r requirements.txt

# パッケージ確認
pip list

エックスサーバー用設定ファイルの作成

WEBアプリ動作時(ユーザーがアクセスしたとき)以下のような流れになるように準備します。

ユーザーがhttps://example.com/myapp/ にアクセス
↓
Apache(エックスサーバー)が index.cgi を実行
↓
index.cgi が仮想環境のPythonを直接呼び出し
↓
Flaskアプリが動作

.htaccess

# CGI実行を有効化
Options +ExecCGI
AddHandler cgi-script .cgi

# HTTPSリダイレクト
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# 静的ファイル以外をindex.cgiに転送
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /myapp/index.cgi/$1 [QSA,L]

# .envファイルへのアクセス拒否
<Files ".env">
    Order allow,deny
    Deny from all
</Files>

13行目のパスはアプリの配置場所に合わせて変更してください。

# 権限を制限
chmod 644 .htaccess

仮想環境のPythonを呼び出すindex.cgi

#!/home/your-server-id/miniconda3/envs/my_ve_py/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import traceback
import textwrap

# アプリディレクトリの絶対パスを指定
app_dir = '/home/your-server-id/example.com/public_html/myapp'
sys.path.insert(0, app_dir)
os.chdir(app_dir)

# 環境変数設定
os.environ['FLASK_ENV'] = 'production'

print("Content-Type: text/html; charset=utf-8\n")

try:
    # Flaskアプリをインポート
    from app import app
    # CGIハンドラーを使用
    from wsgiref.handlers import CGIHandler
    
    # アプリ実行
    CGIHandler().run(app)
    
except Exception as e:
    if os.environ.get("FLASK_ENV") == "development":
        # 開発時
        error_html = textwrap.dedent(f"""
            <html>
            <head><title>Error</title></head>
            <body>
                <h1>Error</h1>
                <p>{e}</p>
                <pre>{traceback.format_exc()}</pre>
            </body>
            </html>
        """)
        print(error_html)
    else:
        # 本番
        print("<html><body><h1>Internal Server Error</h1></body></html>")
        # 詳細はログに出す
        sys.stderr.write(traceback.format_exc())
  • your-server-id:契約サーバーID
  • 1行目のPythonパス:which python で確認したパスを記述
  • 8行目のapp_dir:アプリの実際の絶対パスを指定

index.cgi に実行権限を付与しておきます。

chmod +x index.cgi

アプリ本体app.pyをCGI環境での実行に対応させる

ローカル開発用のコードをコメントアプト

# app.py の最後の部分
if __name__ == '__main__':
    # CGI環境では以下を実行しない
    pass
    # app.run(debug=True, host='0.0.0.0', port=5000)  # コメントアウト

ファイルパスの設定

import os
from dotenv import load_dotenv

# 絶対パスで設定
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
UPLOAD_FOLDER = os.path.join(BASE_DIR, 'temp')

# .envファイルの読み込み
load_dotenv(os.path.join(BASE_DIR, '.env'))

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

これで、ブラウザでアプリURLにアクセスすると、動作確認できます。

デプロイ後のメンテナンス

アプリの更新方法は、

  1. ローカルで修正・テスト
  2. FTPで変更ファイルをアップロード
  3. ブラウザで動作確認

SSH接続は不要で、ファイルを上書きするだけで反映されます。

パッケージの追加がある場合

SSH接続し、仮想環境にてパッケージを追加する必要があります。

# SSH接続

# 仮想環境アクティベート
conda activate my_ve_py

# パッケージ追加
pip install new-package
# または requirements.txt更新後
pip install -r requirements.txt
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次