概要
Docker Composeでは複数のDockerコンテナを定義してデプロイをすることが可能になるので、アプリからデータベースまで必要な実行環境を簡単に作成できます。
ローカル環境を汚さずに、必要なときにその都度用意できるのが個人的には最も良い点です。
この記事では、JavaアプリケーションとMySQLの実行環境を構築するために、Dockerfileの定義からDocker Composeでコマンド1つでデプロイをするまでの流れを記載します。
環境
- | Version |
---|---|
OS | Amazon Linux 2 x86_64 |
Docker | Docker version 20.10.17, build 100c701 |
Docker | Docker Compose version v2.16.0 |
Java | java 17.0.5 2022-10-18 LTS |
Framework | Spring boot 3.0.4 |
ビルド | Gradle 7.5.1 |
アプリケーションとディレクトリ構成
今回は、Spring bootアプリケーションは以下のRest APIを使用する。
こちら
./searchpostcode/
build/
libs/
searchpostcode-0.0.1-SNAPSHOT.jar #1
mysql/
1_CreateTable.sql #2
2_ImportTable.sql
import.csv
my.conf
Docker-compose.yml #3
- #1:build/libsは、Gradleでビルド済みのjar
- #2:mysql/は、Docker-composeで使用するファイル
- #3:Docker-compose.ymlは、コンテナの設定
構築の流れと、構築後の概要図
おおよその流れは、
Dockerfileの作成 -> Docker-compose.ymlの作成 -> docker-composeでビルド -> docker-composeで起動
Linux上に、Javaアプリケーションの実行環境とDBの実行環境をそれぞれコンテナで作成し、コンテナ間はjdbc接続でデータアクセスする。
Dockerfileの作成
ビルド済みのjarファイルをコンテナへコピーして、Javaコマンドを実行する。
FROM openjdk:17
COPY ./build/libs/ /usr/searcehpost/
ENTRYPOINT ["java","-jar","/usr/searcehpost/searchpostcode-0.0.1-SNAPSHOT.jar"]
Docker-compose.ymlの作成
version: '3.1'
services:
java:
build: . #カレントディレクトリのDockerfileをビルド
image: searcehpost:1
container_name: java-searcehpost
tty: true
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME} #環境変数をホストからコンテナへ渡す
SPRING_DATASOURCE_PASSWORD: ${SPRING_DATASOURCE_PASSWORD} #
SPRING_DATASOURCE_URL: jdbc:mysql://mysql-1:3306/demo #ホスト名は、container_nameを指定する
db:
image: mysql:8.0.32
container_name: mysql-1
ports:
- "13306:3306" #ホスト側のport:コンテナ側のport
volumes:
- ./mysql/my.cnf:/etc/my.cnf #ホスト側のファイルをコンテナへコピーする
- ./mysql/:/docker-entrypoint-initdb.d #MySQLの起動時に自動実行したいスクリプトをコピーする
environment:
MYSQL_DATABASE: demo
MYSQL_ROOT_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}
MYSQL_USER: ${SPRING_DATASOURCE_USERNAME}
MYSQL_PASSWORD: ${SPRING_DATASOURCE_PASSWORD}
補足説明
-
services.java.build
今回は、javaのコンテナイメージはDockerfileから作成する。
もしDocker Hubからイメージをpullする場合は、imagesでイメージ名を指定すればよい。 -
services.java.environment
コンテナで使いたい環境変数を定義している。ホスト側の環境変数の指定が可能。
また、jdbc接続のホスト名にはcontainer_nameを指定する必要がある。この例では、MySQLコンテナのものを指定して接続する。 -
db.ports
ホスト側で使用するポートとコンテナ側で使用するポートをマッピングする。
ホスト側の環境でもMySQLを3306ポートで起動しているため、今回は変更した。もしホスト側で使用していないポートであれば、同じでも動作する。 -
db.volumes
ホスト側に用意したmy.cnfとコンテナ起動時に自動実行させたいファイルをコピーする。
/docker-entrypoint-initdb.dディレクトリは、MySQLコンテナが用意する特別なディレクトリで、スクリプトを自動実行してくれる。
対象の拡張子は、*.sql, *.sh, *.sql.gz の3つ。
実行はファイル名のアルファベット順に行われるので、
1.テーブル作成 -> 2.インデックス作成 -> 3.データインポート
のように実行順序を意識するように命名する必要がある。
詳しくは、こちらの "Initializing a fresh instance" を参照。
docker-composeでビルド
docker compose build
コマンドで、docker-compose.ymlおよびDockerfileをもとにコンテナをビルドする。
Usage: docker compose build [OPTIONS] [SERVICE...]
Build or rebuild services
[16:55:16 ec2-user ~/dev/java/searchpostcode] docker compose build
[+] Building 1.2s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 32B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/openjdk:17 1.1s
=> [internal] load build context 0.0s
=> => transferring context: 123B 0.0s
=> [1/2] FROM docker.io/library/openjdk:17@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 0.0s
=> CACHED [2/2] COPY ./build/libs/ /usr/searcehpost/ 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:dd7d43ab6d2565dfbbf126779be7d92151dcf516d3116c0416345104341c6ac7 0.0s
=> => naming to docker.io/library/searcehpost:1 0.0s
コンテナのイメージが作成される。
[16:55:28 ec2-user ~/dev/java/searchpostcode] docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
searcehpost 1 dd7d43ab6d25 37 minutes ago 499MB
mysql 8.0.32 21a7ac543605 7 hours ago 530MB
docker-composeで起動
docker compose up -d
コマンドで起動する。
Usage: docker compose up [OPTIONS] [SERVICE...]
Create and start containers
Options:
-d, --detach Detached mode: Run containers in the background
[16:55:41 ec2-user ~/dev/java/searchpostcode] docker compose up -d
[+] Running 3/3
⠿ Network searchpostcode_default Created 0.0s
⠿ Container java-searcehpost Started 1.4s
⠿ Container mysql-1 Started 1.4s
ここまでで、javaとMySQLのコンテナが起動された状態となる。
動作確認
コマンドラインからcurlで実行する。
APIからデータベースへアクセスができており、レスポンスも問題なし。
[18:35:04 ec2-user ~/dev/java/searchpostcode] curl localhost:8080/postcode/0600000
{"result":[{"kanaPrefecture":"ホッカイドウ","kanaCity":"サッポロシチュウオウク","kanaStreet":"イカニケイサイガナイバアイ","kanjiPrefecture":"北海道","kanjiCity":"札幌市中央区","kanjiStreet":"以下に掲載がない場合"}]}
EC2のセキュリティグループさえ許可をしておけば、インターネットからのアクセスも可能。
ログの閲覧
ログはdocker compose logsコマンドで確認できる。
複数のコンテナのログが混在で出力されるので、見た目はわかりにくい。
Javaアプリケーションのログ出力を標準出力にしているが、実用時はログファイルへ出力したうえで、ホスト側と共有するようにしたほうがよいと思います。
Usage: docker compose logs [OPTIONS] [SERVICE...]
View output from containers
[17:30:57 ec2-user ~/dev/java/searchpostcode] docker compose logs
java-searcehpost | 07:56:01,781 |-INFO in ch.qos.logback.core.model.processor.DefaultProcessor@3ec300f1 - End of configuration.
java-searcehpost | 07:56:01,782 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@482cd91f - Registering cur
rent configuration as safe fallback point
java-searcehpost |
java-searcehpost |
java-searcehpost | . ____ _ __ _ _
java-searcehpost | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
java-searcehpost | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
java-searcehpost | \\/ ___)| |_)| | | | | || (_| | ) ) ) )
java-searcehpost | ' |____| .__|_| |_|_| |_\__, | / / / /
java-searcehpost | =========|_|==============|___/=/_/_/_/
java-searcehpost | :: Spring Boot :: (v3.0.4)
java-searcehpost |
java-searcehpost | [2023-03-29 07:56:01.941+0000] [background-preinit] [INFO] [org.hibernate.validator.internal.util.Version] | HV000001:
Hibernate Validator 8.0.0.Final
...
mysql-1 | 2023-03-29 07:56:12+00:00 [Warn] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb
.d/my.cnf
mysql-1 | 2023-03-29 07:56:12+00:00 [Note] [Entrypoint]: Stopping temporary server
mysql-1 | 2023-03-29 07:56:14+00:00 [Note] [Entrypoint]: Temporary server stopped
mysql-1 |
mysql-1 | 2023-03-29 07:56:14+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
コンテナの停止
docker compose down
コマンドで停止。
-vオプションを付けていると、コンテナにコピーされたファイルも残らず削除される。
Usage: docker compose down [OPTIONS]
Stop and remove containers, networks
-v, --volumes volumes Remove named volumes declared in the volumes section of the Compose file and anonymous volumes attached to containers.
[18:44:56 ec2-user ~/dev/java/searchpostcode] docker compose down -v
[+] Running 3/3
⠿ Container mysql-1 Removed 1.3s
⠿ Container java-searcehpost Removed 0.6s
⠿ Network searchpostcode_default Removed 0.1s