コンテナー化データベースの利用

Using a local containerized database offers flexibility and ease of setup, letting you mirror production environments closely without the overhead of traditional database installations. Docker simplifies this process, enabling you to deploy, manage, and scale databases in isolated containers with just a few commands.

このガイドでは以下について学びます。

  • ローカルでのコンテナー化データベースの実行
  • コンテナー化データベースへのシェルアクセス
  • ホストからのコンテナー化データベースへの接続
  • 別コンテナーからのコンテナー化データベースへの接続
  • ボリューム内のデータベースデータの保存
  • カスタマイズしたデータベースイメージのビルド
  • Docker Compose を利用したデータベース実行

このガイドでは例として MySQL イメージを用います。 ただしその考え方は他のデータベースイメージにも適用することができます。

前提条件

このガイドの作業を進めるには Docker をすでにインストールしていることが必要です。 Docker のインストールについては Docker の入手 を参照してください。

ローカルでのコンテナー化データベースの実行

MySQL、PostgreSQL、MongoDB といった人気のデータベースシステムについては、そのほとんどが Docker Hub 上に Docker 公式イメージがあります。 そういったイメージはベストプラクティスを実現するものとして提供されており、最新機能やセキュリティアップデートが行われたものを利用することができます。 作業を進めるには Docker Hub にアクセスして、利用したいデータベースを検索します。 検索された各ページには、そのコンテナーを起動する手順、カスタマイズ方法、必要に応じたデータベース設定方法が詳細に示されています。 このガイドに示す MySQ についての情報は Docker Hub の MySQL イメージ ページを参照してください。

データベースコンテナーを起動するには Docker Desktop GUI か CLI を利用します。


CLI を使ってコンテナーを起動するには、端末から以下のコマンドを実行します。

$ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest

このコマンドは以下を行ないます。

  • --name my-mysql はコンテナーに対して my-mysql という名前をつけることで参照しやすくします。
  • -e MYSQL_ROOT_PASSWORD=my-secret-pw は MySQL の root パスワードを my-secret-pw に設定します。 my-secret-pw の部分は、環境に応じたセキュアなパスワードに置き換えてください。
  • -e MYSQL_DATABASE=mydb の利用は任意であり、mydb という名前のデータベースを生成します。 mydb という名前は適宜変更してください。
  • -d はコンテナーをデタッチモードで起動します。 これはつまりバックグラウンドで起動することです。
  • mysql:latest は、MySQL イメージの最新バージョンを利用することを指示します。

コンテナーが起動しているかどうかは、端末から docker ps を実行して確認します。

GUI を使う場合、コンテナーの起動は以下のようにします。

  1. Docker Desktop Dashboard において、画面最上段のグローバル検索欄を選びます。

  2. 検索欄に mysql を入力します。 Images (イメージ) タブが選択されていない場合は選択します。

  3. msyql イメージ上にマウスカーソルを移動させて Run (実行) を選びます。 Run a new container (新規コンテナーの実行) 画面が開きます。

  4. Optional settings (オプション設定) を展開します。

  5. オプションの設定において以下を指定します。

    • Container name (コンテナー名): my-mysql
    • Environment variables (環境変数):
      • MYSQL_ROOT_PASSWORD: my-secret-pw
      • MYSQL_DATABASE: mydb
    オプション設定画面にてオプションを設定
  6. Run (実行) を選びます。

  7. Docker Dashboard Dashboard の Container (コンテナー) 画面を開いて、対象コンテナーが起動していることを確認します。


コンテナー化データベースへのシェルアクセス

Docker コンテナー内部でデータベースを起動したら、データベースの管理、コマンド実行、管理タスクの実現のため、データベースにアクセスするシェルの実行が必要になってきます。 Docker ではこれを行う簡単な方法として docker exec コマンドを提供しています。 またグラフィカルインターフェースを好むのであれば Docker Desktop GUI を利用することもできます。

データベースコンテナーをまだ起動していない場合は ローカルでのコンテナー化データベースの実行 を参照してください。


CLI を使って MySQL コンテナーの画面にアクセスするには、以下のような docker exec コマンドを実行します。

$ docker exec -it my-mysql bash

このコマンドは以下を行ないます。

  • docker exec は、起動しているコンテナー内においてコマンド実行を行うために利用します。
  • -it はアクセスするターミナルを対話モードとします。 そうすることでコマンド入力を行えるようにします。
  • my-mysql は MySQL コンテナー名です。 コンテナー実行時に別の名前としていた場合は、その名前に書き換えてください。
  • bash はコンテナー内部で実行するコマンドです。 これによって bash シェルが開くので、コンテナー内のファイルシステムやインストール済アプリケーションとの対話的処理を行うことができます。

このコマンドの実行により、MySQL コンテナー内での bash シェルへのアクセスが可能となります。 そこから MySQL サーバーを直接管理できます。 exit を実行すれば、元のターミナル画面に戻ります。

  1. Docker Desktop Dashboard を開いて Containers (コンテナー) 画面を選びます。
  2. 対象コンテナーの Actions (動作) カラムにおいて Show container actions (コンテナー動作の確認) を選択します。 そして Open in terminal (端末を開く) を選びます。

この端末画面内において、MySQL コンテナー内部のシェルにアクセスすることができます。 そこから MySQL サーバーを直接管理できます。


コンテナーの端末にアクセスできたら、あとはコンテナー内で利用可能なツール類は何でも利用できます。 以下に示す例では、コンテナー内の mysql を使ってデータベースの一覧を表示しています。

# mysql -u root -p
Enter password: my-secret-pw

mysql> SHOW DATABASES;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

ホストからのコンテナー化データベースへの接続

コンテナー化したデータベースにホストから接続するには、コンテナー内部のポートとホストマシン上のポートをマッピングする必要があります。 そのプロセスを実現することで、コンテナー内にあるデータベースはホストマシンのネットワークからアクセス可能となります。 MySQL の場合、デフォルトのポートは 3306 です。 このポートを公開すれば、ホストマシン上にあるさまざまなデータベース管理ツールやアプリケーションが MySQL データベースとやり取りできるようになります。

作業を進めるにあたっては、本ガイドを通じて実行させてきた以前のコンテナーは削除してください。 コンテナーを停止させ削除するには、以下のいずれかを行います。

  • 端末から docker remove --force my-mysql を実行して my-mysql という名前のコンテナーを削除します。
  • または Docker Desktop Dashboard の Containers (コンテナー) 画面にて、対象コンテナーの横にある Delete (削除) アイコンをクリックします。

そこで Docker Desktop GUI または CUI を使って、ポートマッピングを行ったコンテナーを起動します。


端末から以下のコマンドを実行します。

$ docker run -p 3307:3306 --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -d mysql:latest

このコマンドにおいて -p 3307:3306 は、ホスト上のポート 3307 をコンテナー内のポート 3306 にマッピングします。

このポートマッピングを確認するため、以下のコマンドを実行します。

$ docker ps

その出力結果は以下のようになるはずです。

CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
6eb776cfd73c   mysql:latest   "docker-entrypoint.s…"   17 minutes ago   Up 17 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp   my-mysql

GUI を使ってコンテナーを起動するには以下を行います。

  1. Docker Desktop Dashboard において、画面最上段のグローバル検索欄を選びます。

  2. 検索欄に mysql を入力します。 Images (イメージ) タブが選択されていない場合は選択します。

  3. msyql イメージ上にマウスカーソルを移動させて Run (実行) を選びます。 Run a new container (新規コンテナーの実行) 画面が開きます。

  4. Optional settings (オプション設定) を展開します。

  5. オプションの設定において以下を指定します。

    • Container name (コンテナー名): my-mysql
    • ポート 3306/tcp に対応する Host port (ホストポート): 3307
    • Environment variables (環境変数):
      • MYSQL_ROOT_PASSWORD:my-secret-pw
      • MYSQL_DATABASE:mydb
    オプション設定画面にてオプションを設定
  6. Run (実行) を選びます。

  7. Containers (コンテナー) 画面において、Port(s) (ポート) カラムにおいてマッピングされているポートを確認します。 my-mysql コンテナーに対して 3307:3306 となっているはずです。


この時点においてホスト上で動作するアプリケーションは、コンテナー内の MySQL サービスに localhost:3307 としてアクセスできます。

別コンテナーからのコンテナー化データベースへの接続

コンテナー化したデータベースに別のコンテナーから接続するというのは、マイクロサービスアーキテクチャーにおいて、あるいは開発作業中においてはごく普通に活用する状況です。 Docker のネットワーク機能はその接続をきわめて簡単に実現できるようになっています。 その際にホストネットワークに対してデータベースを公開する必要はありません。 データベースコンテナーとそれにアクセスするコンテナーを同一の Docker ネットワーク上に置きさえすれば実現できます。

作業を進めるにあたっては、本ガイドを通じて実行させてきた以前のコンテナーは削除してください。 コンテナーを停止させ削除するには、以下のいずれかを行います。

  • 端末から docker remove --force my-mysql を実行して my-mysql という名前のコンテナーを削除します。
  • または Docker Desktop Dashboard の Containers (コンテナー) 画面にて、対象コンテナーの横にある Delete (削除) アイコンをクリックします。

ネットワークを生成し、その上にコンテナーを起動するには以下とします。

  1. 以下のコマンドを実行して、my-network という名前の Docker ネットワークを生成します。

    $ docker network create my-network
    
  2. データベースコンテナーを実行し、その際に --network オプションを使ってネットワークを指定します。 これによりコンテナーは my-network というネットワーク上で実行されます。

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb --network my-network -d mysql:latest
    
  3. 他のコンテナーを実行する際にも --network オプションを使ってネットワークを指定します。 この例においては phpMyAdmin コンテナーを起動し、それがデータベースにアクセスできるようにしています。

    1. phpMyAdmin コンテナーを起動します。 --network オプションを使ってネットワークを指定します。 -p オプションは、ホストマシンからコンテナーへアクセスするためのものです。 -e オプションは、このイメージにおいて必要な環境変数を指定するものです。

      $ docker run --name my-phpmyadmin -d --network my-network -p 8080:80 -e PMA_HOST=my-mysql phpmyadmin
      
  4. 両コンテナーが通信できていることを確認します。 この例においては phpMyAdmin にアクセスすることで、それがデータベースに接続していることが確認できます。

    1. http://localhost:8080 を開いて phpMyAdmin コンテナーにアクセスします。
    2. ユーザー名を root、パスワードを my-secret-pw としてログインします。 MySQL サーバーに接続されるはずであり、データベースが一覧表示されます。

この時点において、コンテナーネットワークである my-network 上に稼働するアプリケーションは、どんなものであっても my-mysql:3306 を通じてコンテナー内の MySQL サービスにアクセス可能となりました。

ボリューム内のデータベースデータの保存

コンテナーが再起動したり削除されたりしても、データベースのデータを維持させるためには Docker ボリューム内にデータベースデータを置く必要があります。 Docker ボリュームというものは、コンテナーの書き込みレイヤーよりも外部にデータベースファイルを保存するものです。 そうしておけばデータを失うことなく、コンテナーのアップグレード、ベースイメージの切り替え、データの共有が可能になります。 データベースコンテナーに対してボリュームを割り当てる操作は、Docker CLI か Docker Desktop GUI を使って行います。

作業を進めるにあたっては、本ガイドを通じて実行させてきた以前のコンテナーは削除してください。 コンテナーを停止させ削除するには、以下のいずれかを行います。

  • 端末から docker remove --force my-mysql を実行して my-mysql という名前のコンテナーを削除します。
  • または Docker Desktop Dashboard の Containers (コンテナー) 画面にて、対象コンテナーの横にある Delete (削除) アイコンをクリックします。

そこで Docker Desktop GUI または CUI を使って、ボリュームを使ったコンテナーを起動します。


ボリュームをアタッチしたデータベースコンテナーを起動するには、docker run コマンドに -v オプションを含めます。 そこで指定するのはボリューム名と、コンテナー内部にデータベースデータが保存されているパスです。

ボリュームがまだ存在していない場合、Docker は自動的に生成します。

ボリュームをアタッチしたデータベースコンテナーを起動して、そのデータが保持されていることを確認するには以下を行います。

  1. ボリュームをアタッチしたコンテナーを起動します。

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=mydb -v my-db-volume:/var/lib/mysql -d mysql:latest
    

    このコマンドは my-db-volume という名前のボリュームを、コンテナー内の /var/lib/mysql ディレクトリにマウントします。

  2. データベース内に何かデータを生成します。 ここでは docker exec コマンドを使い、コンテナー内にて mysql を実行してテーブルを生成します。

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
    

    このコマンドはコンテナー内にて mysql ツールを利用してテーブルを生成します。 テーブル名は mytable であり column_name というカラムを一つ持ちます。 そして value という値をインサートします。

  3. コンテナーを停止し削除します。 ボリュームがなかったとしたら、コンテナーの削除とともに生成したテーブルも無くなります。

    $ docker remove --force my-mysql
    
  4. ボリュームをアタッチした新たなコンテナーを起動します。 今回は環境変数を指定する必要はありません。 ボリューム内に設定が保存されているからです。

    $ docker run --name my-mysql -v my-db-volume:/var/lib/mysql -d mysql:latest
    
  5. 先に生成したテーブルが存在していることを確認します。 再度 docker exec コマンドを使って、コンテナー内にて mysql を実行します。

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
    

    このコマンドはコンテナー内にて mysql ツールを使い、テーブル mytable から全レコードを一覧取得するものです。

    その出力結果は以下のようなものになるはずです。

    column_name
    value
    

ボリュームをアタッチしたデータベースコンテナーを起動して、データが保持されていることを確認するには以下を行います。

  1. ボリュームをアタッチしたコンテナーを起動します。

    1. Docker Desktop Dashboard において、画面最上段のグローバル検索欄を選びます。

    2. 検索欄に mysql を入力します。 Images (イメージ) タブが選択されていない場合は選択します。

    3. msyql イメージ上にマウスカーソルを移動させて Run (実行) を選びます。 Run a new container (新規コンテナーの実行) 画面が開きます。

    4. Optional settings (オプション設定) を展開します。

    5. オプションの設定において以下を指定します。

      • Container name (コンテナー名): my-mysql
      • Environment variables (環境変数):
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • Volumes (ボリューム):
        • my-db-volume:/var/lib/mysql
      オプション設定画面にてオプションを設定

      ここでのボリューム名は my-db-volume です。 これがコンテナー内の /var/lib/mysql にマウントされます。

    6. Run (実行) を選びます。

  2. データベース内に何かデータを生成します。

    1. Containers (コンテナー) 画面にて、対象コンテナーの横にある Show container actions (コンテナー動作の確認) アイコンを選択します。 そして Open in terminal (端末を開く) を選びます。

    2. コンテナーの端末から以下のコマンドを実行して、テーブルを追加します。

      # mysql -u root -pmy-secret-pw -e "CREATE TABLE IF NOT EXISTS mydb.mytable (column_name VARCHAR(255)); INSERT INTO mydb.mytable (column_name) VALUES ('value');"
      

    このコマンドはコンテナー内にて mysql ツールを利用してテーブルを生成します。 テーブル名は mytable であり column_name というカラムを一つ持ちます。 そして value という値をインサートします。

  3. Containers (コンテナー) 画面にて、対象コンテナーの横にある Delete (削除) アイコンを選択します。 そして Delete forever (完全に削除) を選びます。 ボリュームがなかったとしたら、コンテナーの削除とともに生成したテーブルも無くなります。

  4. ボリュームをアタッチした新たなコンテナーを起動します。

    1. Docker Desktop Dashboard において、画面最上段のグローバル検索欄を選びます。

    2. 検索欄に mysql を入力します。 Images (イメージ) タブが選択されていない場合は選択します。

    3. msyql イメージ上にマウスカーソルを移動させて Run (実行) を選びます。 Run a new container (新規コンテナーの実行) 画面が開きます。

    4. Optional settings (オプション設定) を展開します。

    5. オプションの設定において以下を指定します。

      • Container name (コンテナー名): my-mysql
      • Environment variables (環境変数):
        • MYSQL_ROOT_PASSWORD:my-secret-pw
        • MYSQL_DATABASE:mydb
      • Volumes (ボリューム):
        • my-db-volume:/var/lib/mysql
      オプション設定画面にてオプションを設定
    6. Run (実行) を選びます。

  5. 先に生成したテーブルが存在していることを確認します。

    1. Containers (コンテナー) 画面にて、対象コンテナーの横にある Show container actions (コンテナー動作の確認) アイコンを選択します。 そして Open in terminal (端末を開く) を選びます。

    2. コンテナーの端末から以下のコマンドを実行して、先に生成したテーブルが存在していることを確認します。

      # mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.mytable;"
      

      このコマンドはコンテナー内にて mysql ツールを使い、テーブル mytable から全レコードを一覧取得するものです。

      その出力結果は以下のようなものになるはずです。

      column_name
      value
      

この時点においてany MySQL container that mounts the my-db-volume will be able to access and save persisted data.

Build a customized database image

Customizing your database image lets you include additional configuration, scripts, or tools alongside the base database server. This is particularly useful for creating a Docker image that matches your specific development or production environment needs. The following example outlines how to build and run a custom MySQL image that includes a table initialization script.

Before you begin, you must remove any containers you previously ran for this guide. To stop and remove a container, either:

  • In a terminal, run docker remove --force my-mysql to remove the container named my-mysql.
  • Or, in the Docker Desktop Dashboard, select the Delete icon next to your container in the Containers view.

To build and run your custom image:

  1. Create a Dockerfile.

    1. Create a file named Dockerfile in your project directory. For this example, you can create the Dockerfile in an empty directory of your choice. This file will define how to build your custom MySQL image.

    2. Add the following content to the Dockerfile.

      # syntax=docker/dockerfile:1
      
      # Use the base image mysql:latest
      FROM mysql:latest
      
      # Set environment variables
      ENV MYSQL_DATABASE mydb
      
      # Copy custom scripts or configuration files from your host to the container
      COPY ./scripts/ /docker-entrypoint-initdb.d/

      In this Dockerfile, you've set the environment variable for the MySQL database name. You can also use the COPY instruction to add custom configuration files or scripts into the container. In this example, files from your host's ./scripts/ directory are copied into the container's /docker-entrypoint-initdb.d/ directory. In this directory, .sh, .sql, and .sql.gz scripts are executed when the container is started for the first time. For more details about Dockerfiles, see the Dockerfile reference.

    3. Create a script file to initialize a table in the database. In the directory where your Dockerfile is located, create a subdirectory named scripts, and then create a file named create_table.sql with the following content.

    CREATE TABLE IF NOT EXISTS mydb.myothertable (
      column_name VARCHAR(255)
    );
    
    INSERT INTO mydb.myothertable (column_name) VALUES ('other_value');

    You should now have the following directory structure.

    ├── your-project-directory/
    │ ├── scripts/
    │ │ └── create_table.sql
    │ └── Dockerfile
  2. Build your image.

    1. In a terminal, change directory to the directory where your Dockerfile is located.

    2. Run the following command to build the image.

      $ docker build -t my-custom-mysql .
      

      In this command, -t my-custom-mysql tags (names) your new image as my-custom-mysql. The period (.) at the end of the command specifies the current directory as the context for the build, where Docker looks for the Dockerfile and any other files needed for the build.

  3. Run your image as you did in Run a local containerized database. This time, specify your image's name instead of mysql:latest. Also, you no longer need to specify the MYSQL_DATABASE environment variable as it's now defined by your Dockerfile.

    $ docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d my-custom-mysql
    
  4. Verify that your container is running with the following command.

    $ docker ps
    

    You should see output like the following.

    CONTAINER ID   IMAGE              COMMAND                  CREATED        STATUS          PORTS                 NAMES
    f74dcfdb0e59   my-custom-mysql   "docker-entrypoint.s…"    2 hours ago    Up 51 minutes   3306/tcp, 33060/tcp   my-mysql
    
  5. Verify that your initialization script was ran. Run the following command in a terminal to show the contents of the myothertable table.

    $ docker exec my-mysql mysql -u root -pmy-secret-pw -e "SELECT * FROM mydb.myothertable;"
    

    You should see output like the following.

    column_name
    other_value
    

Any container ran using your my-custom-mysql image will have the table initialized when first started.

Use Docker Compose to run a database

Docker Compose is a tool for defining and running multi-container Docker applications. With a single command, you can configure all your application's services (like databases, web apps, etc.) and manage them. In this example, you'll create a Compose file and use it to run a MySQL database container and a phpMyAdmin container.

To run your containers with Docker Compose:

  1. Create a Docker Compose file.

    1. Create a file named compose.yaml in your project directory. This file will define the services, networks, and volumes.

    2. Add the following content to the compose.yaml file.

      services:
        db:
          image: mysql:latest
          environment:
            MYSQL_ROOT_PASSWORD: my-secret-pw
            MYSQL_DATABASE: mydb
          ports:
            - 3307:3306
          volumes:
            - my-db-volume:/var/lib/mysql
      
        phpmyadmin:
          image: phpmyadmin/phpmyadmin:latest
          environment:
            PMA_HOST: db
            PMA_PORT: 3306
            MYSQL_ROOT_PASSWORD: my-secret-pw
          ports:
            - 8080:80
          depends_on:
            - db
      
      volumes:
        my-db-volume:

      For the database service:

      • db is the name of the service.
      • image: mysql:latest specifies that the service uses the latest MySQL image from Docker Hub.
      • environment lists the environment variables used by MySQL to initialize the database, such as the root password and the database name.
      • ports maps port 3307 on the host to port 3306 in the container, allowing you to connect to the database from your host machine.
      • volumes mounts my-db-volume to /var/lib/mysql inside the container to persist database data.

      In addition to the database service, there is a phpMyAdmin service. By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by the service's name. Therefore, in the PMA_HOST environment variable, you can specify the service name, db, in order to connect to the database service. For more details about Compose, see the Compose file reference.

  2. Run Docker Compose.

    1. Open a terminal and change directory to the directory where your compose.yaml file is located.

    2. Run Docker Compose using the following command.

      $ docker compose up
      

      You can now access phpMyAdmin at http://localhost:8080 and connect to your database using root as the username and my-secret-pw as the password.

    3. To stop the containers, press ctrl+c in the terminal.

Now, with Docker Compose you can start your database and app, mount volumes, configure networking, and more, all with a single command.

Summary

This guide introduced you to the essentials of using containerized databases, specifically focusing on MySQL, to enhance flexibility, ease of setup, and consistency across your development environments. The use-cases covered in this guide not only streamline your development workflows but also prepare you for more advanced database management and deployment scenarios, ensuring your data-driven applications remain robust and scalable.

Related information: