こんにちは。船井総研デジタルのいっちーです。
前回の記事では、このシリーズで作っていくシステムの要件について考えてみました。
早速今回から、開発に入っていきたいと思います。
開発環境・実行環境を整える
今回の開発で使う環境・ツールは以下のとおりです。
- WSL2/Ubuntu version 2
- openjdk version 19.0.2
- Apache Maven version 3.8.7
- Docker version 20.10.22
- VSCode version 1.76.2
- その他、DB接続ツール等
VSCodeからWSL2/Ubuntuにリモート接続して、開発を行う…という想定です。以降、本稿ではWSL2/Ubuntuのことを単にUbuntuと記載します。各ツール類のインストールや設定方法は、他の記事にお譲りすることにして、早速環境を作っていきましょう。
まずは開発用のフォルダを作成します。
Javaソースを格納するフォルダと、Dockerファイルを格納するフォルダを作りました。Ubuntuからは、下記のように見ることができます。
$ ls /mnt/c/work/negitter/
README.md app docker
コンテナを設計して、設定ファイルを作る
コンテナ設計
前回の記事で考えたコンテナ構成を設計に落としていきます。
ホスト側から設定したいものはbind mountで、DBデータはVolumeで永続化する想定です。この設計に基づいて、docker-compose.ymlとDockerfileを作っていきます。
docker-compose.ymlとDockerfileの作成
docker-compose.yml
docker-compose.ymlは以下のようになりました。
version: "3"
services:
web:
container_name: web
build:
context: .
dockerfile: ./web/Dockerfile
restart: always
volumes:
- ./web/conf.d:/etc/nginx/conf.d
- ./web/log:/var/log/nginx
- ./web/src:/usr/share/nginx/html
ports:
- ${HTTP_PORT}:80
networks:
mynetwork:
ipv4_address: ${WEB_IPADDRESS}
ap:
container_name: ap
build:
context: .
dockerfile: ./ap/Dockerfile
restart: always
volumes:
- ./ap/webapps:/usr/local/tomcat/webapps
- ./ap/log:/usr/local/tomcat/logs
ports:
- ${AP_PORT}:8080
networks:
mynetwork:
ipv4_address: ${AP_IPADDRESS}
db:
container_name: db
build:
context: .
dockerfile: ./db/Dockerfile
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_ja_0900_as_cs_ks
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${ROOT_PASS}
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASS}
TZ: ${TZ}
ports:
- ${DB_PORT}:3306
volumes:
- db-store:/var/lib/mysql
- ./db/script:/docker-entrypoint-initdb.d
networks:
mynetwork:
ipv4_address: ${DB_IPADDRESS}
volumes:
db-store:
networks:
mynetwork:
driver: bridge
ipam:
driver: default
config:
- subnet: ${SUBNET}
COMPOSE_PROJECT_NAME=negitter
ROOT_PASS=root
DB_NAME=negitter
DB_USER=user
DB_PASS=pass
DB_PORT=3306
AP_PORT=8080
HTTP_PORT=80
TZ=Asia/Tokyo
WEB_IPADDRESS=172.19.0.23
AP_IPADDRESS=172.19.0.24
DB_IPADDRESS=172.19.0.22
SUBNET=172.19.0.0/24
他の作業で作ってるコンテナとバッティングしたときに修正がしやすいように、IPアドレスやポート番号といった情報は.env
ファイルに外出ししています。ポートはデフォルトポートで書いていますが、必要に応じて書き換えると良いでしょう。
Webコンテナ
WebコンテナのDockerfileは以下のようになりました。設定ファイルは、とりあえずリバースプロキシの設定のみ記載しています。
FROM nginx:latest
EXPOSE 80
RUN service nginx start
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://172.19.0.24:8080;
}
}
APコンテナ
APコンテナのDockerfileは以下のようになりました。今回、特に追加でインストールするもの等はありません。
FROM tomcat:latest
EXPOSE 8080
DBコンテナ
DBコンテナのDockerfileは以下のようになりました。文字コードを設定するための設定ファイルと、それをコンテナ内に取り込むための処理を記載しています。また、コンテナ構築と同時にテーブル作成を行うため、docker-entrypoint-initdb.d
に紐づけたフォルダにテーブル作成のスクリプトを格納します。
FROM mysql:latest
ADD ["./db/conf/my.cnf", "/etc/mysql/conf.d/"]
RUN chmod 644 /etc/mysql/conf.d/my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_ja_0900_as_cs_ks
[client]
default-character-set=utf8mb4
use negitter;
DROP TABLE if exists negi_mst;
CREATE TABLE negi_mst(
id int NOT NULL AUTO_INCREMENT COMMENT 'ID'
, negi_name varchar (128) NOT NULL COMMENT 'ねぎ名称'
, register_datetime datetime NOT NULL COMMENT '登録日時'
, PRIMARY KEY (id)
) COMMENT = 'ねぎマスタ';
DROP TABLE if exists message_tbl;
CREATE TABLE message_tbl(
id int NOT NULL AUTO_INCREMENT COMMENT 'ID'
, register_name varchar (256) NOT NULL COMMENT '投稿者名'
, negi_message varchar (256) NOT NULL COMMENT 'つぶやき'
, register_datetime datetime NOT NULL COMMENT '投稿日時'
, PRIMARY KEY (id)
) COMMENT = 'メッセージテーブル';
必要に応じて、初期データ投入のスクリプトを追加しても良いでしょう。今回は空のテーブルが作れれば十分なので、これでOKとします。
最終的に、Dockerの設定ファイルは以下のような構成になりました。
.
├── .env
├── docker-compose.yml
├── ap
│ └─── Dockerfile
├── db
│ ├── Dockerfile
│ ├── conf
│ │ └── my.cnf
│ └── script
│ └── 00_create_tables.sql
├── docker-compose.yml
└── web
├── Dockerfile
└── conf.d
└── nginx.conf
2023/03/24追記
DBコンテナの設定でcollation-serverがutf8mb4_unicode_ciとなっていましたが、この設定だとひらがなとカタカナの区別をしなくなってしまうので、たとえば「深谷ねぎ」と「深谷ネギ」を同じ文字列だと判定してしまいます。
正しくはcollation-server=utf8mb4_ja_0900_as_cs_ksと設定するべきでした。お詫びして訂正いたします。
起動と動作確認
コンテナビルド~起動
docker-compose
を使って、コンテナのビルドと起動を行います。
$ docker-compose build
Building web
Step 1/3 : FROM nginx:latest
---> a99a39d070bf
Step 2/3 : EXPOSE 80
---> Using cache
---> 9a384215c0c4
Step 3/3 : RUN service nginx start
---> Using cache
---> a2f1bb17a22b
Successfully built a2f1bb17a22b
Successfully tagged negitter_web:latest
Building ap
Step 1/2 : FROM tomcat:latest
---> ad4994520144
Step 2/2 : EXPOSE 8080
---> Using cache
---> 337cb58f5bfe
Successfully built 337cb58f5bfe
Successfully tagged negitter_ap:latest
Building db
Step 1/3 : FROM mysql:latest
---> b939d379d46e
Step 2/3 : ADD ["./db/conf/my.cnf", "/etc/mysql/conf.d/"]
---> Using cache
---> 22469fea4200
Step 3/3 : RUN chmod 644 /etc/mysql/conf.d/my.cnf
---> Using cache
---> 6602c45ce192
Successfully built 6602c45ce192
Successfully tagged negitter_db:latest
コンテナのビルドができたので、起動します。
$ docker-compose up -d
Creating network "negitter_mynetwork" with driver "bridge"
Creating volume "negitter_db-store" with default driver
Creating web ... done
Creating ap ... done
Creating db ... done
DBコンテナの疎通確認
手近なDB接続ツールを使って、DBコンテナにアクセスします。DBnegitter
上に、negi_mst
とmessage_tbl
の2つのテーブルが見えていれば成功です。
WEB・APコンテナの疎通確認
まだWebアプリの本体は作っていないので、Tomcatのサンプルアプリケーションを使って疎通確認します。
Tomcat公式から、サンプルアプリケーションのwarファイルsample.war
をダウンロードします。
ダウンロードしたsample.war
を、C:\work\negitter\docker\ap\webapps
配下にコピーします。Tomcatが立ち上がっていれば、自動的にwarが展開されてsampleアプリケーションがデプロイされます。
数分待って、http://localhost/sample/にアクセスし、Tomcatのサンプルページが立ち上がれば疎通確認は完了です。
疎通確認できたら、sample.war
は削除しても構いません。
まとめ
今回の記事では、環境構築と疎通確認まで行いました。次回は、Spring bootのプロジェクトを作成し、いよいよアプリ本体を作っていこうと思います。
それではまた。