コンテナ化した Spring アプリから PostgreSQL コンテナに接続する

前回の記事でコンテナ化した Spring アプリから、ローカルの PostgreSQL のコンテナに接続してみたいと思います.

前回の記事はこちら.


 

今回の構成を図式化すると以下のようになります.

同一ホスト(Mac)内に2つのコンテナ(アプリ、DB)があり、コンテナ間で通信を行います.

接続する方法

通常のローカルに建てたアプリとDBの接続であれば、以下のような YAML で問題なく接続できます.

spring:
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/sampledb
    username: postgres
    password: postgrespass

 
ただコンテナの場合、localhost を指定しまうとコンテナ内の領域にアクセスしていってしまうので接続できません.

localhost でアクセスさせたいなら以下のような構成になるでしょう.

1つのコンテナにアプリの Runtime も DB も両方一緒に含めるようにすれば localhost でアクセスできます.
 
今回はアプリと DB のコンテナを分けて運用したく、問題を解決するためにコンテナ名を用いてアプリから DB にアクセスするようにします.

 

Docker Compose

Docker だけでも出来ると思いますが、Docker Compose を使った方が楽そうなので、今回は Docker Compose を使うようにします.

docker-compose.yml

version: "2"
services:
  db:
    image: postgres:10.1-alpine
    container_name: "test-db"
    ports:
      - "5432:5432"
    volumes:
      - "db-data:/var/lib/postgresql/data"
    environment:
      POSTGRES_DB: sampledb
      POSTGRES_PASSWORD: postgrespass  
  app:
    image: wildfly-prototype:latest
    container_name: "prototype"
    ports:
      - "8080:8080"
      - "9990:9990"
    mem_limit: 1024m
    cpu_shares: 2048
    environment:
      spring.datasource.url: "jdbc:postgresql://db:5432/sampledb"
    depends_on:
      - db
volumes:
  db-data:
    driver: local

 
ポイントは以下の部分です.

environment:
 spring.datasource.url: “jdbc:postgresql://db:5432/sampledb”
depends_on:
 - db

docker-compose の version:’2′ からはサービス名で他のコンテナにアクセスできるようになっているようで、jdbc:postgresql://db:5432/sampledb で DB にアクセスできます.
(links も depends_on も接続には必要ないようです)

depends_on を記述しているのは起動順番を明示的に設定するためです.
この辺はこちらの記事を参考にさせていただきました.
docker-compose depends_onとlinksの違い

ちなみに、application.yml の値は環境変数で上書きできるようですね.
読み込みの優先順位についてはこちらの記事をご参照ください.
Spring-Bootの設定プロパティと環境変数

 

起動

Docker Compose から2つのコンテナを起動します.

$ docker-compose up

prototype   | 08:08:14,212 INFO  [org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor] (ServerService Thread Pool -- 75) Initializing ExecutorService 'applicationTaskExecutor'
prototype   | 08:08:15,578 INFO  [springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper] (ServerService Thread Pool -- 75) Context refreshed
prototype   | 08:08:15,807 INFO  [springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper] (ServerService Thread Pool -- 75) Found 1 custom documentation plugin(s)
prototype   | 08:08:15,979 INFO  [springfox.documentation.spring.web.scanners.ApiListingReferenceScanner] (ServerService Thread Pool -- 75) Scanning for api listing references
prototype   | 08:08:16,421 INFO  [springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator] (ServerService Thread Pool -- 75) Generating unique operation named: helloUsingGET_1
prototype   | 08:08:16,477 INFO  [com.example.demoapi.DemoApiApplication] (ServerService Thread Pool -- 75) Started DemoApiApplication in 15.537 seconds (JVM running for 48.519)

 
DB から値も取得できています.

Docker 側で名前解決の仕組みが用意されているのは簡単で良いですね〜!

 

以上です.