砂漠の旅人(たびと)|新天地:たびとの旅路

電脳砂漠を旅する、ある旅人の日記。フロッピーを頼りに歩いた日から、クラウドの地平を見つめる今日まで。見つけたオアシスも、迷い込んだ砂の迷宮も、全てこの羊皮紙に。

二つの魂を、箱庭で結べ ~WebとDB、Dockerによる共存の儀~

旅の途中、興味深いオアシスを見つけた。忘れないうちに、この羊皮紙に記しておくとしよう。

Dockerという名の魔法の箱庭。そこで一体のゴーレムを創り出すのは、もはや造作もないことだ。しかし、真の冒険者は、そこで満足しない。WebサーバとDBサーバ、二つの異なる魂を持つゴーレムを同じ箱庭に召喚し、互いに魂の対話をさせる。それこそが、より高度な世界を創造するための、次なるステップなのだ。

かつて、私はWeb/AP/DBの三層構造という、巨大な神殿の建立に苦しんだ経験がある。今回は、その第一歩として、WebとDB、二つのサーバをDockerコンテナとして錬成し、docker-composeという名の世界の契約書で、その絆を結びつける。これは、単一の魂から、複数の魂が共存する生態系を創り出す、壮大な儀式の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Dockerという箱庭で、複数のゴーレムを召喚し、互いに対話させたいと願う者
  • コンテナ起動時に、DBサーバに初期テーブルという名の記憶を刻み込みたい探求者

第一の儀式:世界の設計図(ファイル構成)

まずは、これから創造する世界の、完全な設計図を示す。webrdb、二つの魂のための区画を設け、それぞれに魂の設計図(Dockerfile)と、世界の契約書(docker-compose.yml)を配置する。

これから創造する、世界の設計図

第二の儀式:世界の契約書を記す(docker-compose.yml)

これが、二つの魂の運命を司る、最も重要な古文書だ。 rdbPostgreSQL)とweb(Nginx)、二つのサービスを定義する。そして、最も重要な呪文がnetworksだ。mynetworkという名の魔法のネットワークを創造し、二つの魂をそこに所属させることで、彼らは互いを「名前」で呼び合うことができるようになる。

version: '3.8'
services: 
  rdb:
    container_name: 'postgres'
    build: ./rdb
    ports:
      - "5433:5432"
    environment:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: Password01#
      DATABASE_HOST: localhost
    volumes:
      - rdb_data:/var/lib/postgresql/data:rw
      - ./rdb/initdb:/docker-entrypoint-initdb.d
    tty: true
    restart: always
    networks:
      - mynetwork
  
  web:
    container_name: 'nginx'
    build: ./web
    ports:
      - "8080:80"
    environment:
      - LANG=ja_JP.utf8
      - TZ=Asia/Tokyo
    tty: true
    restart: always
    networks:
      - mynetwork

volumes:
  rdb_data:

networks:
  mynetwork:
    driver: bridge
    ipam:
      driver: default

第三の儀式:魂の設計図を記す(Dockerfileとinit.sh)

Webサーバの魂(./web/Dockerfile)

魂には、軽量にして高速なnginx:alpineを選ぶ。

FROM nginx:alpine
ENV LANG ja_JP.utf8
ENV TZ Asia/Tokyo

ENTRYPOINT /usr/sbin/nginx -g "daemon off;" -c /etc/nginx/nginx.conf

DBサーバの魂(./rdb/Dockerfile)

魂には、信頼性の高いpostgres:alpineを選ぶ。

FROM postgres:alpine
ENV LANG ja_JP.utf8
ENV TZ Asia/Tokyo

DBの初期記憶(./rdb/initdb/init.sh)

そして、init.shという名の羊皮紙に、召喚時に実行すべき「初期記憶の刻印」の儀式を記しておく。

set -e
psql -U postgres postgres << ENDSQL
--
CREATE TABLE sample (
  id text primary key,
  name text
);
COMMENT ON COLUMN sample.id is 'ID';
COMMENT ON COLUMN sample.name is '名前';
--
ENDSQL

最終儀式:世界の創造と、魂の対話

全ての設計図が揃ったら、docker-compose buildで二つの魂を錬成し、docker-compose up -dで世界を創造する。

世界の確認

まずは、WebサーバのNginxが、外界からの呼びかけに応えるかを確認する。ブラウザでhttp://localhost:8080を訪れ、歓迎の辞が表示されれば、門は開かれている証拠だ。

Webサーバの魂が、我々を歓迎している

次に、DBサーバのPostgreSQLが、正しく記憶を刻んでいるかを確認する。DB接続ツールで対話し、sampleテーブルが存在すれば、儀式は成功だ。

DBサーバの魂に、初期記憶は正しく刻まれた

魂と魂の対話

最後に、二つの魂が、互いの存在を認識できるかを確認する。 Webサーバの魂に入り込み、ping rdbと問いかける。DBサーバからも同様に、ping webと。 互いに確かな応答があれば、我々の箱庭に、完璧な生態系が誕生したことになる。

$ docker-compose exec web /bin/sh
/ # ping rdb
PING rdb (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=1.050 ms
...

羊皮紙を巻く前に

今回は、DockerでWebサーバとDBサーバを構築し、ネットワーク設定によって、それらを名前で連携させる方法を紹介した。DBサーバのコンテナのビルド時に、初期テーブルを作成する儀式も、多くの冒険で役立つだろう。

この魔法と、前回紹介した.NETアプリをビルドする魔法を組み合わせれば、Web-AP-DBの三層構造という、より巨大な神殿さえも、この箱庭に建立できるはずだ。その可能性は、無限に広がっている。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

ラクダの独り言

ご主人が、今度は箱の中に、二匹のゴーレムを創り出して、お互いに「ピンポン」とか言い合わせている。なんでも、そうやって仲良くさせないと、ちゃんとお仕事してくれないらしい。俺に言わせりゃ、最初から一匹の、もっとデカくて賢いゴーレムを創りゃいいだろうに。まったく、人間ってのは、面倒なことが好きだな。やれやれだぜ。