3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerコンテナで動くFlaskアプリケーションと自宅のMySQLデータベースを接続する方法

Last updated at Posted at 2024-10-18

はじめに

今回は、FlaskアプリケーションをDockerコンテナを用いて構築し、自宅のMySQLデータベースにデータを保存して表示するWebアプリケーションを作成します。

FlaskはPythonでのWebアプリケーション開発に適した軽量フレームワークであり、MySQLは一般的に使用されるリレーショナルデータベース管理システムです。

Dockerを使うことで、Flaskアプリケーションの環境を簡単に構築・管理できます。また、今回は自宅のMySQLサーバーを使用することで、既存のデータベースや設定をそのまま利用可能にします。

この記事では、プロジェクトの構成から各ファイルの作成手順、さらにアプリケーションの動作確認までの手順を詳細に説明します。

知識整理

今回、必要な知識は以下になります。
Docker
アプリケーションとその依存関係をコンテナ化して、どの環境でも同じように動かせる仮想化技術です。開発環境と本番環境の整合性が取りやすくなります。

Dockerfile
Dockerイメージを作るための設定ファイルです。ベースイメージや依存パッケージのインストール、アプリの起動方法などを記述し、これをもとにイメージを作成します。

Docker Compose
複数のコンテナを一括で管理するツールです。今回は、自宅のMySQLに接続するため、MySQLの設定は省略し、Flaskアプリケーションのみの管理を行います。

Flask
Pythonで書かれたシンプルで軽量なWebフレームワークです。小規模なアプリやAPIの構築に向いており、ルーティングやテンプレートエンジンの機能を提供します。

MySQL
広く使用されているリレーショナルデータベース管理システム(RDBMS)です。自宅のMySQLサーバーを利用してデータの保存・検索・管理を行います。

自宅環境にMySQLデータベースを構築する手順については、過去の記事で詳細に記載していますので、興味のある方は参考にしてください。

プロジェクト構成

今回作成するFlaskアプリケーションのディレクトリ構成は以下のとおりです。

/flask-app/
├── Dockerfile         # Flask用のDockerイメージを構築する設定ファイル
├── docker-compose.yml # Flaskコンテナをまとめて管理する設定ファイル
├── requirements.txt   # FlaskなどのPythonライブラリの依存関係を記述
├── app.py             # Flaskアプリケーションのメインファイル
└── /templates/        # HTMLテンプレートを格納するディレクトリ
    └── index.html

各ファイルの作成手順

1. Dockerfileの作成

以下の内容でDockerfileを作成します。このファイルにより、Pythonベースのイメージを使用してFlaskアプリケーションを実行するコンテナを構築します。

# ベースイメージとして公式のPythonイメージを使用
FROM python:3.9-slim

# 作業ディレクトリを設定
WORKDIR /app

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    build-essential \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# ローカルのrequirements.txtをコンテナにコピー
COPY requirements.txt .

# Pythonの依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのソースコードをコンテナにコピー
COPY . .

# 環境変数の設定(Flaskアプリを起動するため)
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

# コンテナのポート5000を公開
EXPOSE 5000

# Flaskアプリケーションを起動
CMD ["flask", "run"]

2. docker-compose.ymlの作成

自宅のMySQLサーバーに接続するFlaskアプリケーションを定義するdocker-compose.ymlファイルを作成します。

docker-compose.yml
version: '3'  # Docker Composeのバージョン

services:
  web:  # Flaskアプリケーション
    build: .  # Dockerfileからビルド
    ports:
      - "5001:5000"  # ホストの5001をコンテナの5000にマッピング
    environment:
      - FLASK_ENV=development  # デバッグモードを有効化

私の環境では、Flaskを使った個人開発を行っており、すでに5000番ポートが使用中です。そのため、コンテナ内ではポート5000でFlaskを動作させつつ、ホスト側からはポート5001でアクセスできるように設定しました。

3. requirements.txtの作成

Flaskアプリケーションの依存関係を管理するrequirements.txtを作成します。FlaskとMySQL用のライブラリをインストールするため、以下の内容を記載します。

requirements.txt
Flask==2.3.2
mysql-connector-python==8.0.33

4. app.pyの作成

Flaskアプリケーションのメインファイルであるapp.pyを作成し、以下の内容を記述します。このファイルでは、自宅のMySQLに接続し、データを挿入および取得して表示します。

app.py
from flask import Flask, render_template, request, redirect
import mysql.connector

app = Flask(__name__)

def get_db_connection():
    return mysql.connector.connect(
        host='YOUR_MYSQL_HOST',  # 自宅のMySQLサーバーのホスト名またはIPアドレス
        user='YOUR_USER',  # MySQLのユーザー名
        password='YOUR_PASSWORD',  # MySQLのパスワード
        database='flask_db'  # 接続するデータベース名
    )

@app.route('/')
def home():
    connection = get_db_connection()
    cursor = connection.cursor()
    cursor.execute("SELECT message FROM greetings")
    messages = cursor.fetchall()
    cursor.close()
    connection.close()
    return render_template('index.html', messages=messages)

@app.route('/add', methods=['POST'])
def add_message():
    message = request.form['message']
    connection = get_db_connection()
    cursor = connection.cursor()
    cursor.execute("INSERT INTO greetings (message) VALUES (%s)", (message,))
    connection.commit()
    cursor.close()
    connection.close()
    return redirect('/')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

YOUR_MYSQL_HOST, YOUR_USER, YOUR_PASSWORD を自宅のMySQLサーバーに合わせて設定してください。

5. templates/index.htmlの作成

HTMLテンプレートを保存するtemplatesディレクトリを作成し、その中にindex.htmlを配置します。以下はそのサンプルです。

templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>今日もお疲れ様!!</title>
</head>
<body>
    <h1>今日は金曜日!明日から夢の週末ですね!</h1>
    <form action="/add" method="post">
        <input type="text" name="message" placeholder="Enter your message" required>
        <button type="submit">Add Message</button>
    </form>
    <h2>Messages:</h2>
    <ul>
        {% for message in messages %}
        <li>{{ message[0] }}</li>
        {% endfor %}
    </ul>
</body>
</html>

6. MySQLテーブルの初期設定

ここでは、rootユーザーで自宅環境のMySQLにログインして、必要な設定を行います。

sudo mysql -u root -p

パスワードを入力すると、MySQLにログインできます。

まず、flask_dbという名前のデータベースが存在しない場合は、以下のコマンドで作成してください。

CREATE DATABASE flask_db;

次に、greetingsというテーブルを作成し、データを保存できるようにします。

USE flask_db;
CREATE TABLE greetings (
    id INT AUTO_INCREMENT PRIMARY KEY,
    message VARCHAR(255) NOT NULL
);

実際のターミナル画面は以下のようになります。

スクリーンショット 2024-10-18 20.46.37.png

Dockerのビルドと実行

プロジェクトの準備が整ったら、Dockerイメージをビルドし、docker-composeを使ってFlaskアプリケーションのコンテナを起動します。以下のコマンドを実行してください。

docker-compose up --build

ビルド中の実行画面は以下のようになります。

スクリーンショット 2024-10-18 20.48.13.png

私の環境では、以下のエラーが発生しました。

エラーの例:

web-1  | Traceback (most recent call last):
web-1  |   File "/usr/local/lib/python3.11/site-packages/pymysql/connections.py", line 649, in connect
web-1  |     sock = socket.create_connection(
web-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^

ファイアウォールの設定を確認したところ、ポート3306(MySQLのデフォルトポート)が開放されていないことがわかりました。 MySQLに外部から接続できるようにするためには、このポートを開放する必要があります。

ポート3306を開放し、設定を反映させるには、以下のコマンドを実行します。

firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all

設定が適用されたら、再度上記のコマンドを実行し、ポートが開放されていることを確認してください。portsセクションに3306/tcpが含まれていれば成功です。

アプリケーションの動作確認

Flaskアプリケーションが起動したら、ブラウザで「http://localhost:5001」にアクセスします。

スクリーンショット 2024-10-19 3.00.14.png

テキストボックスにメッセージを入力して送信すると、メッセージが自宅のMySQLに保存され、ページに表示されます。

スクリーンショット 2024-10-19 3.01.11.png

まとめ

今回の手順では、Dockerを用いてFlaskアプリケーションをコンテナ化し、自宅のMySQLデータベースに接続しました。

これにより、開発環境を統一しつつ、既存のデータベースを活かした開発が可能になりました。

Dockerの利点を活かし、他のサービスとの連携や拡張もスムーズに行えます。今回の検証はかなり、苦戦しました!(笑)

関連記事

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?