kikki's tech note

技術ブログです。UnityやSpine、MS、Javaなど技術色々について解説しています。

Spring BootをDocker Composeで動作させる

本章では、Spring Bootのプロジェクトをコンテナ環境で動作させる方法について共有します。

はじめに

コンテナ環境が必要となった経緯は、業務で結合テストを実施することになり、本番環境と同じ環境で実施する必要が発生したことが原因です。
従来は、ECインスタンスを一から用意して、本番環境と同じ設定を行っていたのですが、人依存であることと作業コストが大きいことが課題でした。
そこで課題を解決する方針として、金額も人資源も低コストで実施でき、再現性があるコンテナ環境を準備する運びとなりました。

前提

本番環境と同じ構成とはいえ、スケーラブルする必要はないので、Docker Composeで準備しました。サーバーの構成は、フロントにNGINX、バックエンドにTomcatRDBMSMySQL、インメモリデータストアにRedisを準備します。

Docker環境の構築

ファイル構成

以下に、Docker環境のディレクトリ構成を示します。

  • /
    • /mysql
      • hogehoge.sql // スキーマの構築とテストデータを投入するクエリ
    • /web-app
      • Dockerfile // Tomcatを構築するためのレシピ
      • entrypoint.sh
      • hogehoge.war
    • /web-nginx
    • docker-compose.yaml

レシピ

コンテナ環境を構築するためのレシピを用意します。まずは、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
    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"
      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で動作させる」でした。


※無断転載禁止 Copyright (C) kikkisnrdec All Rights Reserved.