Conoha VPSでPythonアプリを公開したい!簡単なwebサイトを実装したい!っていう人はPython+Flaskを利用すると思います。そこで、今回はFlaskの公開でプラスアルファMySQLもセットで実装しちゃおうと思います
Nginxを設定する方法だけを知りたい人は
NginxとはWebサーバ・ソフトウェアだけどuWSGIってなに?
uWSGI 英語圏だとユーウィズィーって発音してました。さて、これを何に使うかというと、PythonのフレームワークであるFlaskやDjangoとwebサーバー間の通信処理をしてくれるツールです。なくてもPythonアプリは動くのですが、かかったり、処理が多くなるとuWSGIがないと処理しきれなくなってしまいます。簡単に言えば、PythonのFlaskやDjangoが高負荷でも問題なく処理してくれるツールだと思えばいい感じですね
あとから、負荷対策するよりも、初心者のうちに負荷対策の知識をやっといたほうが、らくだと思いますのでこの設定も行っていきます。
Flaskってなに?動的なサイトを簡単に作れるPythonのフレームワーク
詳しい説明は省きますが、FlaskはJinja2というテンプレートエンジンを使って、動的なウェブページを作成することができます。
例えば、LinkedInやReddit、Pinterestなどのサイトが一部をFlaskを利用しています。同じようなデザインのページを1つのデザインで使いまわして表示させたりできます。
たとえば、ニュースサイトでTOPページと記事の詳細ページのテンプレートを作成し、詳細ページはデータベースからタイトルとニュース内容を記事に表示させるといった感じです。
この構成だとTOPページと記事詳細ページだけの2つのデザインを作ればあとは自動更新で何百といったニュースの記事でも表示が可能です。
私はこの本1冊で勉強できました
データベースはMySQL オープンソースで入門テキストでよく採用される
Flaskは動的サイトに便利なので、動的な内容丹必要な情報をどこに保存するか?ってなりますよね。だからデータベース保存します。私は最初はテキストファイルに保存して、それを読み込んだりしてました。でもせっかくConoha VPSを借りたので、DBを使っていきましょう
データベースを管理するツールRDBMのMySQLはほとんどの人が名前を聞いたことあると思います。超メジャーでOracle者のサービス。データベースの入門の本とか、だいたいMySQLが使われているから、メジャーなやつから覚えていく。SQLの書き方などで使った本はこれ。めっちゃわかりやすい
全体のプロジェクトフォルダの概要
プロジェクトファイル名はFLASK_APP2としていますが、これは1つ目に作ったやつを念のため予備で取っておいているためなので、特にファイル名には意味はありません。ご自由にどうぞ
フォルダ構成
docker-composeでMySQLとFlaskとNginxの基本設定をする
Docker composeを使って、MySQLとNginxとFlaskの基本設定を行うためのDocker-composeのymlファイル構成
services:
flask:
build: ./flask
container_name: flask
restart: always
expose:
- 8080
nginx:
build: ./nginx
container_name: nginx
restart: always
ports:
- "80:80"
# volumes:
# # Mount the nginx configuration file webサーバ共通で使う予定
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf
mysql:
image: mysql:5.7
container_name: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ルートパスワード
MYSQL_DATABASE: DB名
MYSQL_USER: ユーザー名
MYSQL_PASSWORD: ユーザーパスワード
ports:
- "3306:3306"
volumes:
# Mount the mysql data directory mysqlフォルダ作り、dataフォルダを作る理由は、今後my.cnfなど作った場合に拡張して管理しやすいようにするため
- ./mysql/data:/var/lib/mysql
Docker compose で mysqlのコンテナを作成すると、docker composeを終了させた場合、mysql内のデータも破棄されてしまいます。だから、データは別に保存する必要があるので、外部にファイルを保存できるボリュームマウントを使ってConohaVPSのクライアント側に保存をしてあげます。そのために
プロジェクトフォルダの配下に mysqlのフォルダを作り、その中にdataを保存するためのフォルダを作っています。
データの保存元 ./mysql/data
dockerコンテナ内のコピーする先 :/var/lib/mysql
volumes:
- ./mysql/data:/var/lib/mysql
flaskフォルダ内app中にPythonのコンテナを作る
FlaskはPythonのフレームワークなので、Flask以外でPythonを使う想定ではないので、flaskフォルダのappフォルダ中でPythonのコンテナを作成します
# ベースイメージの指定
FROM python:3.9
# 作業ディレクトリの設定
WORKDIR /app
ADD . /app
# 必要なパッケージのインストール
RUN pip install --no-cache-dir -r requirements.txt
# アプリケーションの実行
CMD ["uwsgi", "app.ini"]
このDockerfileは、Python 3.9をベースにしたDockerコンテナを構築するための指示書です。以下に、その内容を詳しく解説します。
ベースイメージの指定
dockerfileコードをコピーするFROM python:3.9
FROM
指令はベースイメージを指定します。この場合、Python 3.9がインストールされた公式のDockerイメージをベースにしています。
作業ディレクトリの設定
dockerfileコードをコピーするWORKDIR /app
WORKDIR
指令は作業ディレクトリを指定します。このディレクトリはコンテナ内での相対パスの基準となります。この場合、/app
ディレクトリを作業ディレクトリとして設定しています。
ファイルの追加
dockerfileコードをコピーするADD . /app
ADD
指令は、ホストマシンのファイルをコンテナにコピーします。この場合、現在のディレクトリの内容をコンテナ内の/app
ディレクトリにコピーします。
必要なパッケージのインストール
dockerfileコードをコピーするRUN pip install --no-cache-dir -r requirements.txt
RUN
指令はコンテナ内でコマンドを実行します。この場合、pip
を使って、requirements.txt
に記載されたPythonパッケージをインストールします。--no-cache-dir
オプションは、キャッシュを使用せずにインストールするため、不要なファイルが残らず、コンテナのサイズが小さくなります。
アプリケーションの実行
dockerfileコードをコピーするCMD ["uwsgi", "app.ini"]
CMD
指令はコンテナが起動されたときに実行されるデフォルトのコマンドを指定します。この場合、uwsgi
を使ってapp.ini
設定ファイルに従ってアプリケーションを起動します。
全体の流れ
- Python 3.9の公式Dockerイメージを基に新しいイメージを作成。
- コンテナの作業ディレクトリを
/app
に設定。 - 現在のディレクトリの全てのファイルをコンテナ内の
/app
ディレクトリにコピー。 requirements.txt
に記載された必要なPythonパッケージをインストール。- コンテナ起動時に
uwsgi
を使ってアプリケーションを起動。
このDockerfileは、PythonベースのWebアプリケーションをuWSGI
を使用してデプロイするための標準的な設定を含んでいます。
requirements.txtファイルを作成して書くパッケージを設定
pip コマンドでインストールしたいやつを設定、今回はFlask関連とMySQLのデータベースにアクセスしたいので以下を設定
requirements.txtファイル
mysql-connector-python==8.0.28
uwsgi==2.0.19.1
blinker==1.8.1
click==8.1.7
colorama==0.4.6
Flask==3.0.3
itsdangerous==2.2.0
Jinja2==3.1.3
MarkupSafe==2.1.5
Werkzeug==3.0.2
Nginxの設定ファイル
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass flask:8080;
}
}
}
この構成は、Nginxの設定ファイルの一部です。Nginxをリバースプロキシサーバーとして使用し、uwsgi
サーバーで実行されているFlaskアプリケーションにリクエストを転送するための設定を示しています。以下にその役割と詳細を説明します。
Nginx設定ファイルの構成
1. events
ブロック
nginxコードをコピーするevents {
worker_connections 1024;
}
- worker_connections 1024:
- Nginxのワーカープロセスが同時に処理できる接続数を設定します。この例では、1つのワーカープロセスが1024の接続を処理できるように設定されています。
2. http
ブロック
nginxコードをコピーするhttp {
server {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass flask:8080;
}
}
}
- http:
- HTTPトラフィックを処理するための設定ブロックです。
3. server
ブロック
nginxコードをコピーするserver {
listen 80;
location / {
include uwsgi_params;
uwsgi_pass flask:8080;
}
}
- server:
- HTTPリクエストを受け取るためのサーバーブロックを定義します。
- listen 80:
- NginxがHTTPリクエストを待ち受けるポート番号を指定します。この場合、標準のHTTPポートである80番ポートをリッスンします。
4. location
ブロック
nginxコードをコピーするlocation / {
include uwsgi_params;
uwsgi_pass flask:8080;
}
- location /:
- ルートURL(
/
)に対するリクエストを処理する設定を定義します。
- ルートURL(
- include uwsgi_params:
- 標準の
uwsgi
パラメータをインクルードします。これには、uwsgi
のプロトコルに必要な基本的な設定が含まれています。
- 標準の
- uwsgi_pass flask:8080:
uwsgi
サーバーにリクエストを転送します。この例では、flask
というホスト名(通常はDockerコンテナの名前)で動作しているuwsgi
サーバーの8080ポートにリクエストを送ります。
全体の流れ
- Nginxは、ポート80で受信したHTTPリクエストを処理します。
- **ルートURL(/)**にマッチするリクエストは、
uwsgi
サーバーに転送されます。 uwsgi
サーバーは、Flaskアプリケーションを実行しているコンテナ内の8080ポートで待ち受けています。- **
include uwsgi_params
**は、リクエストを適切なuwsgi
フォーマットに変換するために必要な設定をNginxに提供します。
この設定により、Nginxはフロントエンドのリバースプロキシとして機能し、Flaskアプリケーションへのリクエストをuwsgi
経由で適切にルーティングします。
uWSGIの設定ファイル
uwsgi.iniはflaskフォルダ内のdockerfileで定義しています。このDockerfileでは、uwsgi
はpip
を使ってインストールされています。CMD ["uwsgi", "app.ini"]
は、pip
でインストールされたuwsgi
コマンドをデフォルトで使用して、app.ini
設定ファイルに従ってアプリケーションを起動しています。
[uwsgi]
wsgi-file = run.py
callable = app
socket = :8080
master = true
processes = 4
threads = 2
chmod-socket = 660
vacuum = true
die-on-term = true
MySQLサーバにアクセスする方法
docker-composeのymlファイルがあるフォルダで以下を実行すれば、MySQLサーバにアクセスできます
docker-compose exec mysql mysql -u ユーザー名 -p -h localhost -P 3306
設定ファイルやシェルスクリプトを使用して、MySQLサーバーにアクセスするショートカットを作成
まず、シェルスクリプトファイル(例:mysql_access.sh
)を作成します。
#!/bin/bash
docker-compose exec mysql mysql -u ユーザー名 -p -h localhost -P 3306
次に、このファイルに実行権限を与えます。
chmod +x mysql_access.sh
./mysql_access.sh
FlaskアプリのHello Worldの簡単なファイル
__init__.pyとapp.pyの両方のファイル作成します。
view.py 表示に関してのファイル
from app import app
@app.route('/')
def index():
return "Hello Flask!"
__init__.py
from flask import Flask
app = Flask(__name__)
from app import views