Python学習11日目です。
今日は、Flaskの開発サーバで動作させていたhtml変換サービスを、Gunicorn + Nginxで動作させる設定を行っていきます。
Nginxインストール
WebサーバーであるNginxを公式サイトの最新リポジトリを使用してインストールします。
前提条件パッケージのインストール
Nginxをインストールするために必要なパッケージをインストールします。
$ sudo apt update $ sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
署名鍵のインポート
Nginxの署名鍵をインポートします。
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
リポジトリ追加
Nginxのリポジトリを追加します。
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \ | sudo tee /etc/apt/sources.list.d/nginx.list
インストール
Nginxのインストールを行います。
$ sudo apt update $ sudo apt install nginx
より詳しいインストールの説明を下記のページで説明しているので、よろしければ参考にしてみてください。

Gunicornインストール
Flaskアプリケーションを動かすためのWSGIサーバー「Gunicorn」をインストールします。
インストール作業は、Pythonの仮想環境内で行います。
$ cd ~/project/html_converter $ source .venv/bin/activate (html_converter) $ uv pip install gunicorn
Gunicornでの動作確認
インストール後、以下のコマンドでGunicornを起動して動作確認を行います。
(html_converter) $ gunicorn --workers 3 --bind 127.0.0.1:8000 app:app [2025-07-16 23:06:29 +0900] [33013] [INFO] Starting gunicorn 23.0.0 [2025-07-16 23:06:29 +0900] [33013] [INFO] Listening at: http://127.0.0.1:8000 (33013) [2025-07-16 23:06:29 +0900] [33013] [INFO] Using worker: sync [2025-07-16 23:06:29 +0900] [33014] [INFO] Booting worker with pid: 33014 [2025-07-16 23:06:29 +0900] [33015] [INFO] Booting worker with pid: 33015 [2025-07-16 23:06:29 +0900] [33016] [INFO] Booting worker with pid: 33016
ログに表示されているように、Webブラウザで「http://127.0.0.1:8000」にアクセスしてHTML変換サービスの画面が表示されることを確認します。
ここまでは、前回の時計サービスを作成した際にも行ったので、問題なく作業を完了することが出来ました。
【Nginx + Gunicorn】UNIXソケットとTCPソケットの違いと選び方
NginxとGunicornを連携させる設定には、主にUNIXドメインソケットとTCPソケットという2つの通信方法があります。
以前、時計サービスを作成した際はTCPソケットを使用しましたが、今回は勉強のためにUNIXドメインソケットを使ってみたいと思います。
これまでは「ソケットはファイル」「TCPはネットワーク」という漠然としたイメージで使っていましたが、この機会に両者の違いと、どのような場合にどちらを選ぶべきかを詳しく学んでいくことにします。
UNIXドメインソケット通信とは
UNIXドメインソケット通信は、同じサーバー上で動作するプロセス同士が通信するための方法です。
これは、ネットワークを介さず「ソケットファイル」と呼ばれる特殊なファイルを使用してデータのやり取りを行います。
以下が実際のソケットファイルです。
$ ls -l html_converter.sock srwxrwxrwx 1 tamohiko tamohiko 0 7月 17 19:15 html_converter.sock $ file html_converter.sock html_converter.sock: socket
メリット
- 高性能:
TCPソケット通信に比べてネットワークを経由しないため、オーバーヘッドが非常に少なくデータ転送速度が高速です。
- 高セキュリティ:
通信がサーバー内部で完結しており、ネットワークポートを公開する必要がないのため、外部からの直接アクセスされる心配がありません。
- 設定の簡素化:
TCPソケット通信とは違い、ポート番号の衝突を気にする必要がありません。
デメリット
- 同一サーバー内でのみ使用可能:
同じサーバー上にある場合のみ通信でき、異なるサーバ間では通信できません。
NginxとGunicornが別のサーバーで稼働している構成では選択できません。 - ファイルパーミッションの管理:
ソケットファイルのパーミッションを適切に設定しないと、Nginxがソケットに接続できなかったり、他のユーザーに不要なアクセスを許してしまったりする可能性があります。
TCPソケット通信とは
TCP/IPプロトコルを使って、IPアドレスとポート番号を使用してネットワーク経由で通信する方法です。
ローカルホスト(127.0.0.1)経由で通信することも、インターネットやLANを介して、異なるサーバー間で通信することも可能です。
メリット
- 高い柔軟性:
異なるサーバー間で通信できるため、NginxとGunicornを別々のマシンに分散させるようなスケーラブルなシステム構成が可能です。
- 簡単な設定:
IPアドレスとポート番号を指定するだけで通信が可能です。
デメリット
- 性能オーバーヘッド:
ネットワークを介するため、UNIXドメインソケットに比べてオーバーヘッドがあり、わずかにパフォーマンスが劣る可能性があります。
- セキュリティリスク:
ポートを公開することになるため、ローカルホスト(127.0.0.1)で通信する場合でも、ファイアウォールによる適切なアクセス制限が不可欠です。
もし誤って外部からアクセス可能な状態でポートを公開してしまうと、Gunicornに直接攻撃されるリスクが生じます。
どちらを選ぶべきか?
UNIXドメインソケット通信とTCPソケット通信の、どちらを選べばよいかの判断基準は以下のとおりです。
- GunicornとNginxが同じサーバー上にある場合
-
特別な理由がない場合は、UNIXドメインソケット通信の方が性能面とセキュリティ面で優れているので利用を推奨します。
複数のサービスをを公開する場合にも、ポート番号を管理する必要がなくなります。 - GunicornとNginxが異なるサーバーに分散している場合
-
この構成の場合は、TCPソケット通信が唯一の選択肢になります。
ただし、Gunicornが待ち受けるポートには、Nginxサーバーからのアクセスのみを許可するよう、厳重なファイアウォール設定が必須です。
Nginx + GunicornをUNIXドメインソケットで連携させる2つの方法
「Nginx + Gunicorn」をUNIXドメインソケットで連携させる設定には、主に2つの方法があります。
- Gunicornにソケット作成を任せる方法:
手軽ですぐに試せるため、開発環境やシンプルな構成に向いています。
- systemdでソケットとGunicornを管理する方法:
より堅牢でセキュアなため、本番環境での運用に最適です。
両方の方法について、具体的な手順とそれぞれのメリット・デメリットを解説していきます。
ソケットファイルの作成場所について
一般的な場所は「プロジェクトディレクトリの直下」や、「/tmp」「/run」「/var/run」といったディレクトリ内で、ソケットのファイル名は、通常「アプリケーション名.sock」のようにします。
Gunicornにソケット作成を任せる方法では、プロジェクトディレクトリの直下に「html_converter.sock」という名前で作成することにします。
ソケットファイル名: /home/tamohiko/project/html_converter/html_converter.sock
systemdでソケットとGunicornを管理する方法では、「/run」ディレクトリ内にソケットを作成することにします。
ソケットファイル名: /run/tamohiko/project/html_converter/html_converter.sock
Gunicornにソケットの作成をまかせて起動する方法
開発環境などで手軽に試したい場合に最適な方法です。
gunicornコマンドの--bindオプションを使うことで、Gunicorn自身がソケットを作成し起動します。
こちらの場合、ソケットの作成もGunicornが行ってくれるので、「gunicorn」コマンドだけで起動できて、とても手軽に試すことができます。
ただし、ソケットを作成するディレクトリに、Gunicornを実行するユーザーの書き込み権限が必要になります。
gunicorn --workers ワーカー数 --bind unix:ソケットファイル Pythonファイル名:Flaskインスタンス名
- --bind unix:ソケットファイル Gunicornが指定したソケットファイルを作成し接続を待ち受けます。
- unix: UNIXソケットを使用することを示します。
- ソケットファイル Gunicornが作成するソケットファイルの絶対パスを指定します。
- Pythonファイル名 今回の場合「app.py」の場合.pyを抜いた「app」となります。
- Flaskインスタンス名 「app.py」内で、「app = Flask(__name__)」とFlaskのインスタンス名を指定しているので「app」となります。
Gunicorn起動
実際にGunicornを起動させてみます。
コマンドの実行はPythonの仮想環境の中で行います。
(html_converter) $ .venv/bin/gunicorn --workers 3 --bind unix:/home/tamohiko/project/html_converter/html_converter.sock app:app
プロジェクトのディレクトリ直下を確認すると、UNIXドメインソケットが作成されていることを確認できます。
$ ls -l html_converter.sock srwxrwxrwx 1 tamohiko tamohiko 0 7月 17 19:15 html_converter.sock
/etc/hostsを設定
今回は現在開発を行っているノートPCから、「conv.server-memo.net」という名前でWebブラウザでアクセスできるようするために、「/etc/hosts」に以下の設定を追加します。
$ sudo vi /etc/hosts
追加する設定は以下のとおりです。
127.0.0.1 conv.server-memo.net
この設定により、「conv.server-memo.net」は自分自身(127.0.0.1)のことだと名前解決することができるようになります。
Nginx設定
NginxとGunicornを連携させるための基本的な設定を追加します。
リバースプロキシ設定
これらの設定は、Nginxがリクエストを中継する際に失われてしまう「クライアントの元の情報」をバックエンドに伝えるための設定です。
$ sudo vi /etc/nginx/proxy_params
設定内容は以下のとおりです。
proxy_set_header Host $http_$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;
Gunicornとの連携設定
Gunicornと連携させるための設定を行います。
$ sudo vi /etc/nginx/conf.d/html_converter.conf
設定内容は以下のとおりです。
upstream app_server { server unix:/home/tamohiko/project/html_converter/html_converter.sock fail_timeout=0; } server { listen 80; server_name conv.server-memo.net; index index.html; access_log /var/log/nginx/html_converter.access.log; error_log /var/log/nginx/html_converter.error.log; location / { include proxy_params; proxy_pass http://app_server; } }
upstreamブロックで、転送先となるバックエンドサーバを設定しています。
「server unix:/home/tamohiko/project/html_converter/html_converter.sock fail_timeout=0;」部分で、接続させたいソケットファイルを指定します。
「fail_timeout=0」は、Nginxがバックエンドサーバーを「ダウンしている」と見なす機能を無効化し、接続失敗後も即座に次のリクエストで再試行させるための設定です。
この設定がない場合は、Nginxは接続に失敗したサーバーを一定時間(デフォルト10秒)「故障中」と判断し、その間リクエストを送るのをやめます。
Nginx起動
設定ファイルの作成が完了したら、書式チェックを行ってからNginxを起動します。
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo systemctl start nginx
Nginxが正常に起動しているか確認しておきましょう。
$ sudo systemctl status nginx ● nginx.service - nginx - high performance web server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: en> Active: active (running) since Sat 2025-07-19 23:18:18 JST; 1 day 22h ago Docs: https://nginx.org/en/docs/ Process: 1914 ExecStart=/usr/sbin/nginx -c ${CONFFILE} (code=exited, status> Main PID: 1923 (nginx) Tasks: 5 (limit: 9373) Memory: 2.2M (peak: 6.6M swap: 3.8M swap peak: 4.0M)
起動に問題がなければ、自動起動の設定を行っておきます。
$ sudo systemctl enable nginx
動作確認
Webブラウザで「http://conv.server-memo.net」にアクセスしてHTML変換サービスの画面が表示されて、実際にhtmlを入力して変換されることを確認します。
問題なく動作していることが確認できました。
これで、とりあえずはUnixドメインソケットを使用してGunicornとNginxを連携させることが出来ました。
こちらの方法は、gunicornコマンドを実行するだけでソケットも作成してもらえるので、とても簡単にNginxと連携させることができました。
systemdでソケットの作成とGunicornを管理する方法
gunicornコマンドの「--bind」を使ってソケット作成し、Nginxと連携させることは出来ましたので、次はsystemdでソケットの作成・管理を行う方法を試してみます。
systemdでソケットを管理することには、以下のようなメリットとデメリットがあります。
メリット
- セキュリティの向上
-
systemd (root権限) が先にソケットを作成し、Gunicornを権限の低い一般ユーザー (nginx) で起動できる。
これにより、アプリケーションが乗っ取られた際のリスクを低減することができます。 - 堅牢なサービス管理
-
systemdがGunicornの起動、停止、異常時の自動再起動などを管理してくれるので、非常に安定した運用が可能となります。
- ゼロダウンタイムでの更新
-
ソケットをsystemdが保持してくれるので、Gunicornのアプリケーションを更新・再起動する際に、接続を取りこぼすことなくシームレスに切り替えることができ、ダウンタイムなしでのデプロイが実現しやすくなります。
デメリット
- 設定の複雑さ
-
.socketと.serviceという2つの設定ファイルが必要になり、Gunicorn単体で動かすよりsystemdの学習コストが多くかかります。
- プラットフォーム依存
-
systemdがインストールされているLinux環境でしか使えません。
Gunicorn用のsystemd設定ファイルの作成
systemdでGunicornを管理するために、.socketと.serviceという2つの設定ファイルを作成します。
この2つは、拡張子を除いて必ず同じファイル名にしてください。
- .socketファイル: UNIXドメインソケットの作成と管理を担当します。
- .serviceファイル: ソケットへのアクセスを契機にして、Gunicornアプリケーションを起動・管理します。
この仕組みにより、OS起動時にはソケットだけが待機状態となり、最初のアクセスがあった時にsystemdがGunicornを自動で起動してくれます (ソケットアクティベーション)。
ソケットファイル (.socket) の作成
ソケット自体の設定ファイルを以下の名前で作成します。
$ sudo vi /etc/systemd/system/html_converter.socket
設定内容は下記のとおりです。
[Unit] Description=html_converter socket [Socket] ListenStream=/run/html_converter/html_converter.sock SocketUser=nginx SocketGroup=nginx SocketMode=0660 [Install] WantedBy=sockets.target
- ListenStream:
作成するソケットファイルの絶対パス
今回は「/run/html_converter/html_converter.sock」としています。 - SocketUser/SocketGroup:
ソケットファイルを所有するユーザーとグループ。
Nginxの実行ユーザに合わせて設定します。 - SocketMode:
ソケットファイルのパーミッション。
0660は、所有ユーザーとグループに読み書きを許可します。
Nginxの実行ユーザ・グループの調べ方は下記のページで説明しているので、良ければ参考してみてください。

サービスファイル (.service) の作成
Gunicornをサービスとして起動するための設定ファイルを作成します。
$ sudo vi /etc/systemd/system/html_converter.service
[Unit] Description=html_converter service with Gunicorn After=network.target Requires=html_converter.socket [Service] User=nginx Group=nginx WorkingDirectory=/home/tamohiko/project/html_converter ExecStart=/home/tamohiko/project/html_converter/.venv/bin/gunicorn --workers 3 app:app Restart=on-failure [Install] WantedBy=multi-user.target
ExecStartのgunicornには--bindオプションは不要です。
systemdがソケットを引き渡してくれるため、Gunicornはそれを自動で認識してくれます。
systemdへ設定反映・起動・自動起動設定
作成した「.socket」と「.service」ファイルを、「systemctl daemon-reload」でsystemdに読み込ませて管理できるようにし、ソケットを起動させます。
$ sudo systemctl daemon-reload $ sudo systemctl start html_converter.socket
「systemctl status」コマンドで、ソケットが作成されていることを確認します。
$ sudo systemctl status html_converter.socket ● html_converter.socket - html_converter socket Loaded: loaded (/etc/systemd/system/html_converter.socket; disabled; preset: enabled) Active: active (listening) since Sat 2025-07-19 23:03:46 JST; 13s ago Triggers: ● html_converter.service Listen: /run/html_converter/html_converter.sock (Stream) Tasks: 0 (limit: 9373) Memory: 0B (peak: 256.0K)
「Active: active (listening)」と表示されていればソケットが作成されて、リクエストを待ち受けている状態です。
正常にソケットが作成されることを確認したあとに、ソケットが自動起動するように設定を行います。
$ sudo systemctl enable html_converter.socket Created symlink /etc/systemd/system/sockets.target.wants/html_converter.socket → /etc/systemd/system/html_converter.socket.
.serviceファイルを有効化(enable)しない理由
systemdのソケットアクティベーションでは、「.socket」ファイルと「.service」ファイルが連携して動作します。
そのため、OS起動時に起動(enable)しておく必要があるのは、通信を待ち受ける「.socket」ファイルだけです。
今回作成した「html_converter.service」は、あくまで「html_converter.socket」から呼び出される存在になります。
Nginx設定変更
「/etc/nginx/conf.d/html_converter.conf」のupstreamブロックで指定しているソケットファイルのパスを、systemdが作成・管理するパスに変更します。
変更点はこの一行だけです。
upstream app_server {
server unix:/run/html_converter/html_converter.sock fail_timeout=0;
}
server {
listen 80;
server_name conv.server-memo.net;
index index.html;
access_log /var/log/nginx/html_converter.access.log;
error_log /var/log/nginx/html_converter.error.log;
location / {
include proxy_params;
proxy_pass http://app_server;
}
}
設定ファイルを変更したら、文法チェックを行い、Nginxを再起動して設定を反映させます。
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo systemctl restart nginx
動作確認
Webブラウザで、設定したドメイン名(例: http://conv.server-memo.net)にアクセスし動作確認を行います。
無事HTML変換サービスが動作していることを確認できました。
まとめ
今回は、NginxとGunicornをUNIXドメインソケットで連携させる、以下の2つの方法を実践しました。
それぞれの方法についての比較を簡単にまとめてみました。
- gunicornコマンドの--bindオプションを使う方法
- systemdでソケットとサービスを管理する方法
比較項目 | gunicorn--bind | systemdで管理 |
---|---|---|
手軽さ | ◎ とても簡単 | △ 設定ファイルが必要 |
セキュリティ | ○ 注意が必要 | ◎ 高い(権限分離) |
安定性 | ○ 手動管理 | ◎ 高い(自動起動/再起動) |
おすすめの用途 | 開発環境 | 本番環境 |
gunicornコマンドの--bindオプションを使用する方法は、コマンド1行で起動させることができ、開発段階の動作確認にはとても便利に使えることがわかりました。
一方、ystemdで管理する方法は、.socketと.serviceという2つのファイルの作成が必要で、最初は少し手間がかかります。
しかし、その手間をかけることで得られるセキュリティと安定性の向上は、本番環境での運用においてメリットがあることも学習できました。
結論として、「開発中は手軽なgunicornコマンド」、「本番運用に移行する段階でsystemd管理」という使い分けが良いみたいなので、今後はこの方法で開発を行っていくことにします。
コメント