スポンサーリンク

Docker デプロイ(CD/CI)

docker-nginx-SpringBoot-MySQL-redis

投稿日:2022年2月21日 更新日:

この記事のゴール

完成図

この手順を実施するに当たって、
・コンテナ同士の通信は「サービス名:ポート番号」
・ホスト→コンテナの通信は「localhost:ポート番号」で行うことを知っておく必要があります。

docker環境構築の際はいきなりdocker-compose.ymlを書くのではなくて、
順番に付け足していった方が挫折率が低いです。

そのため、この記事は次の順で構築を進めていきます。
・Step1.dockerでSpringBoot
・Step2.dockerでSpringBoot+MySQL
・Step3.dockerでSpringBoot+MySQL+redis
・Step4.dockerでSpringBoot+MySQL+redis+nginx

Step1.dockerでSpringBoot

まずはSpringBoot単体を起動できるような環境を作ります。
ローカルのソース群をコンテナにマウントして、
コンテナではローカル同様、gradle bootRunでSpringBootが起動するようにしていきます。

事前注意

後々、セッション管理はredisを使用しますが、
SpringBoot単体で動かす時にはgradle bootRunでエラーが発生しますので、
redis設定関係はコメントアウトしておきます。

    // セッション管理の設定
    // implementation "org.springframework.boot:spring-boot-starter-data-redis"
    // implementation "org.springframework.session:spring-session-data-redis"
spring:
    #session:
    #    store-type:redis

手順

ディレクトリ構成

noricgeographic@MacBook-Air okozukai % tree
.
├── docker-compose.yml
└── sources
    └── okozukai-system
        │   ├── libs
        │   │   ├── okozukai-system-0.0.1-SNAPSHOT-plain.jar
        ├── build.gradle
        └── src
            ├── main
            │   ├── java
            │   └── resources
            │       ├── application.yml

docker-compose.yml

version: "3"
services:
  app:
    container_name: okozukai-app
    image: openjdk:11
    tty: true
    volumes:
      - ./sources/okozukai-system/build/libs/okozukai-system-0.0.1-SNAPSHOT.jar:/okozukai-system.jar
    entrypoint: "java -jar /okozukai-system.jar"
    ports:
      - 80:8080

コンテナ起動と動作確認

docker-compose up -d でコンテナを起動します。

ブラウザからコンテナにアクセスして、動作確認します。

Step2.dockerでSpringBoot+MySQL

手順

ディレクトリ構成

Step1と同様です。

noricgeographic@MacBook-Air okozukai % tree
.
├── docker-compose.yml
└── sources
    └── okozukai-system
        │   ├── libs
        │   │   ├── okozukai-system-0.0.1-SNAPSHOT-plain.jar
        ├── build.gradle
        └── src
            ├── main
            │   ├── java
            │   └── resources
            │       ├── application.yml

docker-compose.yml

MySQLをサービスに加えます。

version: "3"
services:
  app:
    container_name: okozukai-app
    image: openjdk:11
    tty: true
    volumes:
      - ./sources/okozukai-system/build/libs/okozukai-system-0.0.1-SNAPSHOT.jar:/okozukai-system.jar
    entrypoint: "java -jar /okozukai-system.jar"
    ports:
      - 80:8080
    environment:
      spring.datasource.driverClassName: "com.mysql.cj.jdbc.Driver"
      spring.datasource.url: "jdbc:mysql://db/okozukai"
      spring.datasource.username: "okozukaiadmin"
      spring.datasource.password: "xxxxx"
    depends_on:
      - db
  db:
    container_name: okozukai-db
    image: mysql:8
    tty: true
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "rootpass"
      MYSQL_DATABASE: "okozukai"
      MYSQL_USER: "okozukaiadmin"
      MYSQL_PASSWORD: "xxxxx"
    volumes:
      - okozukai-db:/var/lib/mysql
    ports:
      - 3306:3306
volumes:
  okozukai-db:

14行目...コンテナ上のアプリからMySQLに接続させるために、
jdbc:mysql://localhost/okozukai ではなく
jdbc:mysql://db/okozukai となります。
(19行目のMySQLコンテナのサービス名を指定します)

コンテナ起動と動作確認

docker-compose up -d でコンテナを起動します。
(前Stepのコンテナが起動中の人は、docker-compose down で停止してから起動してください)

MySQLコンテナに入り、指定したユーザーとパスワードで接続できることを確認します。

$ docker exec -it okozukai-db /bin/sh
# mysql -u okozukaiadmin -p
Enter password: パスワードを入力
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 8.0.28 MySQL Community Server - GPL

Copyright (c) 2000, 2022, 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> use okozukai;
Database changed
mysql> show tables;
Empty set (0.01 sec)

DDLをDBに流し込んでください。
MySQLコンテナに入って直接DDLを流してもいいですし、flywayを使っている人はホストでflywayを実行します。

intelliJからflywayMigrateを実行した

MySQLコンテナは、docker-compose.ymlの"ports: - 3306:3306"により公開されているので、ホストのアプリからはlocalhost:3306で接続できます。

最後に、ブラウザからアプリにアクセスし、アプリからMySQLに接続できていることを確認します。

アプリからDBの検索や登録ができてればOKです。

Step3.dockerでSpringBoot+MySQL+redis

事前注意

redisを使うため、「Step1の事前準備でコメントアウトしていた箇所のコメントアウトを外してください。

    // セッション管理の設定
    implementation "org.springframework.boot:spring-boot-starter-data-redis"
    implementation "org.springframework.session:spring-session-data-redis"
spring:
    session:
        store-type:redis

手順

ディレクトリ構成

Step1,Step2と同様です。

noricgeographic@MacBook-Air okozukai % tree
.
├── docker-compose.yml
└── sources
    └── okozukai-system
        │   ├── libs
        │   │   ├── okozukai-system-0.0.1-SNAPSHOT-plain.jar
        ├── build.gradle
        └── src
            ├── main
            │   ├── java
            │   └── resources
            │       ├── application.yml

docker-compose.yml

redisの設定を加えます。

version: "3"
services:
  app:
    container_name: okozukai-app
    image: openjdk:11
    tty: true
    volumes:
      - ./sources/okozukai-system/build/libs/okozukai-system-0.0.1-SNAPSHOT.jar:/okozukai-system.jar
    entrypoint: "java -jar /okozukai-system.jar"
    ports:
      - 80:8080
    environment:
      spring.datasource.driverClassName: "com.mysql.cj.jdbc.Driver"
      spring.datasource.url: "jdbc:mysql://db/okozukai"
      spring.datasource.username: "okozukaiadmin"
      spring.datasource.password: "lknuve7gAre"
      spring.redis.host: "redis"
    depends_on:
      - db
      - redis
  db:
    container_name: okozukai-db
    image: mysql:8
    tty: true
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "rootpass"
      MYSQL_DATABASE: "okozukai"
      MYSQL_USER: "okozukaiadmin"
      MYSQL_PASSWORD: "lknuve7gAre"
    volumes:
      - okozukai-db:/var/lib/mysql
    ports:
      - 3306:3306
  redis:
    container_name: okozukai_session
    image: redis:7.0-rc1
volumes:
  okozukai-db:

17行目...コンテナ上のアプリに対して、redisの接続先を指定します。
ここでは、35行目でサービス名を"redis"にしているため、17行目のhostの値も"redis"になります。

35-37行目...redisはホスト(ローカル)からアクセスしませんので、portsは設定しませんでした。

コンテナ起動と動作確認

コンテナ起動前に、アプリの.jarを最新化します。
redisコンテナが起動していない状態だと、gradle buildは失敗すると思いますので、jarファイルを作るために gradle bootJarで作成してください。

docker-compose up -d でコンテナを起動します。

アプリにブラウザからアクセスし、セッションが利用できていることを確認します。

Step4.dockerでSpringBoot+MySQL+redis+nginx

これまでの環境にnginxを加えて完成します。

手順

ディレクトリ構成

nginxの設定ファイルを置くディレクトリを作成します。

okozukai % tree
.
├── docker-compose.yml
├── nginx
│   └── default.conf
└── sources
    └── okozukai-system
        ├── build
        │   ├── libs
        │   │   └── okozukai-system-0.0.1-SNAPSHOT.jar
        ├── build.gradle
        └── src
            ├── main
            │   ├── java
            │   └── resources
            │       ├── application.yml

docker-compose.yml

nginxコンテナを追加します。

version: "3"
services:
  app:
    container_name: okozukai-app
    image: openjdk:11
    tty: true
    volumes:
      - ./sources/okozukai-system/build/libs/okozukai-system-0.0.1-SNAPSHOT.jar:/okozukai-system.jar
    entrypoint: "java -jar /okozukai-system.jar"
    environment:
      spring.datasource.driverClassName: "com.mysql.cj.jdbc.Driver"
      spring.datasource.url: "jdbc:mysql://db/okozukai"
      spring.datasource.username: "okozukaiadmin"
      spring.datasource.password: "lknuve7gAre"
      spring.redis.host: "redis"
    depends_on:
      - db
      - redis
  db:
    container_name: okozukai-db
    image: mysql:8
    tty: true
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "rootpass"
      MYSQL_DATABASE: "okozukai"
      MYSQL_USER: "okozukaiadmin"
      MYSQL_PASSWORD: "lknuve7gAre"
    volumes:
      - okozukai-db:/var/lib/mysql
    ports:
      - 3306:3306
  redis:
    container_name: okozukai_session
    image: redis:7.0-rc1
  nginx:
    container_name: okozukai-nginx
    image: nginx:1.21
    restart: always
    ports:
      - 80:80
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
volumes:
  okozukai-db:

serveces > app のports: -80:8080 は削除します。
appにはnginxの80ポート経由でアクセスするからです。

nginx設定ファイル

この設定ファイルをnginxコンテナの/etc/nginx/conf.d/default.confにマウントします。

server {
    listen 80;

    location / {
        proxy_pass http://app:8080;
    }
}

proxy_passの値はlocalhostではありません。
nginxコンテナから見たappコンテナのパスなので、appコンテナのサービス名である"app"を指定する必要があります。
また、appコンテナではSpringBootが8080ポートで待機しているため、http://app:8080の記述になります。

コンテナ起動と動作確認

docker-compose up -d でコンテナを起動します。

全てのコンテナが正常に動いてそうであれば、ブラウザからlocalhost:8080にアクセスして、動作確認します。

あなたの作成したアプリが動いていればOKです。

SpringBootコードを修正したときは、ホストでgradle bootJarにより.jarを作り直します。

その後、appコンテナを再起動してください。
(docker-compose down -> up する必要はありません)

おまけ Gradleで.jarファイルを作ってdockerを再起動するタスクを作る

既存のbuild.gradleに下記を追加します。

task dockerRestart {
    dependsOn(bootJar)
    doLast {
        println("dockerコンテナを再起動します。")
        "docker container restart okozukai-app".execute()
    }
}

2行目...bootJarに依存する。(bootJarの後で実行される)

5行目...docker container restart okozukai-appを実行する。
okozukai-appの部分はSpringBootコンテナのサービス名にしてください。

これで gradle dockerRestart を実行すれば、最新の内容がコンテナに反映されるようになります。

ただし、.jarをSpringBootコンテナにマウントするようなdocker-compose.ymlになっていればです。
(本記事のものはそうなっています)

Udemyのハンズオン動画講座でSpringBootのスキルを磨く!

スポンサーリンク

-Docker, デプロイ(CD/CI)

Copyright© 【Spring Hack】 , 2022 All Rights Reserved Powered by AFFINGER5.