先日、エックスサーバーのレンタルサーバーに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にアクセスすると、動作確認できます。
デプロイ後のメンテナンス
アプリの更新方法は、
- ローカルで修正・テスト
- FTPで変更ファイルをアップロード
- ブラウザで動作確認
SSH接続は不要で、ファイルを上書きするだけで反映されます。
パッケージの追加がある場合
SSH接続し、仮想環境にてパッケージを追加する必要があります。
# SSH接続
# 仮想環境アクティベート
conda activate my_ve_py
# パッケージ追加
pip install new-package
# または requirements.txt更新後
pip install -r requirements.txt