開発にコンテナを使う¶
事前準備¶
コンテナとしてイメージを実行 で、イメージ構築をし、それコンテナ化アプリケーションとして実行します。
概要¶
この章では、これまでのモジュールで構築したアプリケーションの、ローカル開発環境をセットアップする方法を説明します。イメージの構築には Docker を使い、すべてをとても簡単にする Docker Compose も使います。
ローカルデータベースとコンテナ¶
まず、コンテナでデータベースを実行する方法と、データを保持するためにボリュームとネットワーク機能を使い、アプリケーションがデータベースと通信できるようにする方法を説明します。それから、compose ファイルの中にすべてを入れ込みます。このファイルは1つのコマンドで、ローカル開発環境のセットアップと実行をできるようにします。最後に、コンテナ内で実行しているアプリケーションに、デバッガを接続する方法を説明します。
MySQL をダウンロードし、インストールし、設定し、MySQL データベースをサービスとして実行する代わりに、MySQL 用の Docker 公式イメージを使い、コンテナとして実行できるようになります。
コンテナ内で MySQL を実行する前に、2つのボリュームを作成しておきたいです。これは、Docker が
それでは、ボリュームを作成しましょう。作成するボリュームの1つは MySQL のデータ用で、もう1つは設定ファイル用です。
$ docker volume create mysql
$ docker volume create mysql_config
次は、アプリケーションとデータベースが相互に対話できるようにするためのネットワークを作成します。ネットワークは
$ docker network create mysqlnet
次は、コンテナとして MySQL を実行し、先ほど作成したボリュームとネットワークに接続できるようにします。Docker は Hub からイメージを取得し、ローカルでイメージを実行します。以下のコマンドでは、 -v
はコンテナにボリュームを付けて起動します。詳しい情報は Docker ボリューム をご覧ください。
次は、コンテナとして MongoDB を実行し、先ほど作成したボリュームとネットワークに接続できるようにします。Docker は Hub からイメージを取得し、ローカルでイメージを実行します。
$ docker run --rm -d -v mysql:/var/lib/mysql \
-v mysql_config:/etc/mysql -p 3306:3306 \
--network mysqlnet \
--name mysqldb \
-e MYSQL_ROOT_PASSWORD=p@ssw0rd1 \
mysql
次は、 MySQL データベースが起動して接続できるかどうかを確認します。コンテナ内で実行している MySQL データベースに接続するには、以下のコマンドを実行し、パスワードのプロンプトでは「p@ssw0rd1」を入力します。
$ docker exec -ti mysqldb mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.23 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
アプリケーションをデータベースに接続¶
先ほどのコマンドは、 mysqldb
コンテナに対して「mysql」コマンドを実行し MySQL データベースログインしました。 MySQL 双方向ターミナルを終了するには CTRL-D を押します。
次は、 イメージ構築 の章で作成したサンプルアプリケーションを更新します。Python アプリのディレクトリ構成をみるには、 ディレクトリ構成 をご覧ください。
それでは、MySQL を実行していますので、 app.py
を更新してデータベースとして MySQL を使うようにします。また、サーバに対する手順もいくつか追加しましょう。1つはレコードを取得し、1つはレコードを挿入します。
import mysql.connector
import json
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Docker!'
@app.route('/widgets')
def get_widgets():
mydb = mysql.connector.connect(
host="mysqldb",
user="root",
password="p@ssw0rd1",
database="inventory"
)
cursor = mydb.cursor()
cursor.execute("SELECT * FROM widgets")
row_headers=[x[0] for x in cursor.description] #this will extract row headers
results = cursor.fetchall()
json_data=[]
for result in results:
json_data.append(dict(zip(row_headers,result)))
cursor.close()
return json.dumps(json_data)
@app.route('/initdb')
def db_init():
mydb = mysql.connector.connect(
host="mysqldb",
user="root",
password="p@ssw0rd1"
)
cursor = mydb.cursor()
cursor.execute("DROP DATABASE IF EXISTS inventory")
cursor.execute("CREATE DATABASE inventory")
cursor.close()
mydb = mysql.connector.connect(
host="mysqldb",
user="root",
password="p@ssw0rd1",
database="inventory"
)
cursor = mydb.cursor()
cursor.execute("DROP TABLE IF EXISTS widgets")
cursor.execute("CREATE TABLE widgets (name VARCHAR(255), description VARCHAR(255))")
cursor.close()
return 'init database'
if __name__ == "__main__":
app.run(host ='0.0.0.0')
MySQL モジュールを追加し、データベースサーバに接続するようコードを更新し、データベースとテーブルを作成します。また、 widgets の保存と widgets の取得という2つの手順を追加しました。次は、変更を含むイメージを再構築する必要があります。
まず、 pip
を使ってアプリケーションに mysql-connector-python
モジュールを追加しましょう。
$ pip3 install mysql-connector-python
$ pip3 freeze | grep mysql-connector-python >> requirements.txt
それから、イメージを構築できます。
$ docker build --tag python-docker-dev .
次はコンテナにデータベースネットワークを追加し、コンテナを実行します。これにより、データベースのコンテナ名を使ってアクセスできるようになります。
$ docker run \
--rm -d \
--network mysqlnet \
--name rest-server \
-p 8000:5000 \
python-docker-dev
アプリケーションがデータベースに接続し、メモを追加できるかテストしましょう。
$ curl http://localhost:8000/initdb
$ curl http://localhost:8000/widgets
サービスからは以下の JSON を受け取るでしょう。
[]
Compose を使ってローカルで開発¶
このセクションでは、 python-docker と MySQL データベースを1つのコマンドで起動するための Compose ファイル を作成します。また、 python-docker-dev アプリケーションをデバッグモードで起動するための Compose ファイルも作成しますので、実行中のプロセスにデバッガを接続できるようになります。
IDE のメモ機能やテキストエディタで python-docker
を開き、 docker-compose.dev.yml
という名前の新しいファイルを作成します。ファイル内に以下の命令をコピー&ペーストします。
version: '3.8'
services:
web:
build:
context: .
ports:
- 8000:5000
volumes:
- ./:/app
mysqldb:
image: mysql
ports:
- 3306:3306
environment:
- MYSQL_ROOT_PASSWORD=p@ssw0rd1
volumes:
- mysql:/var/lib/mysql
- mysql_config:/etc/mysql
volumes:
mysql:
mysql_config:
この Compose ファイルは docker run
コマンドに一切パラメータを渡す必要がないため、とても便利です。Compose ファイル内で宣言的にパラメータを指定します。
ポート 8000
を公開していますので、コンテナ内の dev ウェブサーバに到達できます。また、ローカルのソースコードを実行中のコンテナにマッピングしていますので、テキストエディタで変更できるだけなく、それらの変更をコンテナに取り込めます。
Compose ファイルを使う上で、もう1つの素晴らしい機能は、サービス名を使ってサービスの名前解決をできるようになります。そのため、接続文字列として「mysqldb」が使えるようになります。「mysqld」という名前を使えるのは、 MySQL サービスに対して Compose ファイル内でそのように名付けたからです。
次は、アプリケーションを起動し、適切に動作しているか確認しましょう。
$ docker-compose -f docker-compose.dev.yml up --build
--build
フラグを渡したため、 Docker はイメージをコンパイルした後、イメージを起動します。
それから、API エンドポイントをテストしましょう。新しいターミナルを開き、 curl コマンドを使いサーバに対する GET リクエストを作成します。
$ curl http://localhost:8000/initdb
$ curl http://localhost:8000/widgets
次のような反応を受け取るでしょう:
[]
次のステップ¶
この章では、通常のコマンドラインとほとんど同じように使える、一般的な開発用イメージ作成方法を説明しました。また、 Compose ファイルもセットアップし、ソースコードを実行中のコンテナにマップし、デバッグポイントを公開しました。
次の章では、 GitHub Actions を使って CI/CD パイプラインをセットアップする方法を説明します。
フィードバック¶
フィードバックを通し、このトピックの改善を支援ください。考えがあれば、 Docker Docs GitHub リポジトリに issue を作成して教えてください。あるいは、更新の提案のために RP を作成 してください。
参考
- Use containers for development