Spring BootをDocker Composeで動作させる
本章では、Spring Bootのプロジェクトをコンテナ環境で動作させる方法について共有します。
はじめに
コンテナ環境が必要となった経緯は、業務で結合テストを実施することになり、本番環境と同じ環境で実施する必要が発生したことが原因です。
従来は、ECインスタンスを一から用意して、本番環境と同じ設定を行っていたのですが、人依存であることと作業コストが大きいことが課題でした。
そこで課題を解決する方針として、金額も人資源も低コストで実施でき、再現性があるコンテナ環境を準備する運びとなりました。
前提
本番環境と同じ構成とはいえ、スケーラブルする必要はないので、Docker Composeで準備しました。サーバーの構成は、フロントにNGINX、バックエンドにTomcat、RDBMSにMySQL、インメモリデータストアにRedisを準備します。
Docker環境の構築
ファイル構成
以下に、Docker環境のディレクトリ構成を示します。
レシピ
コンテナ環境を構築するためのレシピを用意します。まずは、docker-compose.yamlファイルです。
[docker-compose.yaml]
version: "3" services: redis: container_name: redis image: redis:latest # 他コンテナ向けにポートを開放 expose: - 6379 mysql: container_name: mysql image: mysql:5.7 command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci environment: # MySQLの認証情報をセット MYSQL_ALLOW_EMPTY_PASSWORD: "yes" MYSQL_DATABASE: "HOGE" MYSQL_USER: "HogeUser" MYSQL_PASSWORD: "password" expose: - 3306 # デバッグでDBの中身を確認できるよう、ホストにもポートを開放 ports: - 3306:3306 volumes: # DBの構築クエリをセット - ./mysql:/docker-entrypoint-initdb.d # データを永続化先を指定 - mysql-datastore:/var/lib/mysql web: container_name: web-nginx image: nginx:latest depends_on: - web-app links: - web-app ports: # localhostでのアクセス先を指定 - 8081:81 volumes: - ./web_nginx/conf.d/:/etc/nginx/conf.d # Spring Bootでのstaticファイルを配置 - ./web_nginx/www/:/usr/share/nginx/www web-app: container_name: web-app links: - mysql - redis expose: - 8080 build: ./web_app environment: CATALINA_OPTS: "-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" SPRING_PROFILES_ACTIVE: "local" SPRING_DATASOURCE_URL: "jdbc:mysql://mysql:3306/HOGE?useUnicode=true&characterEncoding=UTF-8" SPRING_REDIS_HOST: "redis" # MySQLでのデータ永続化先を指定 volumes: mysql-datastore: driver: local
次に、Dockerファイルを準備します。
Tomcat
Webサーバーのレシピです。warファイルを始め、起動スクリプトをコンテナ内にコピーします。
[Dockerfile]
FROM tomcat:9-jre8-alpine RUN rm -rf /usr/local/tomcat/webapps/* /tmp/* \ && apk add --no-cache mysql-client redis ttf-dejavu COPY ./entrypoint.sh /tmp/ COPY ./*.war /usr/local/tomcat/webapps/ROOT.war ENTRYPOINT ["sh", "/tmp/entrypoint.sh"]
Dockerで実行させるシェルスクリプトです。最後にcatalina.shを実行しています。
[entrypoint.sh]
#!/usr/bin/env bash # Hibernateを動作させるために、redisとMySQLが動作するのを待ってから、Tomcatを起動させます set -e # exit script if any command fails (non-zero value) echo Waiting for redis service start...; while ! nc -z redis 6379; do sleep 1; done; echo Waiting for mysql service start...; while ! nc -z mysql 3306; do sleep 1; done; echo Connected!; catalina.sh run;
Nginx
最後に、Nginxサーバーのレシピです。
[app.conf]
server { listen 81; root /usr/share/nginx; error_page 403 /403.html; error_page 404 /404.html; error_page 500 /500.html; # リダイレクト用にlocalhostの転送先を指定 proxy_set_header Host $host:8081; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; location / { # tomcatで起動したWebサーバーのURLを指定 proxy_pass http://web-app:8080; } # リバースプロキシでstaticファイルを直接返す location ~* .*\.(jpg|gif|png|css|js|ico|svg) { root /usr/share/nginx/www; access_log off; } }
起動
上述したファイルを準備し、以下のコマンドを実行すると、Dockerの起動やシャットダウンができます。
# Imageファイルの生成 $ docker-compose build # Dockerをバックグラウンドで実行 $ docker-compose up -d # Dockerをシャットダウン $ docker-compose down
筆休め
コンテナ環境は、スクラップビルドが容易にでき、アプリ開発者でもお作法を学べば簡単にインフラ環境を準備できます。起動にかかる時間も短いため、ストレスなく扱えます。開発環境など、一律のインフラを構築したい場合には、是非利用してみてください。
以上、「Spring BootをDocker Composeで動作させる」でした。