DockerでNginx, Tomcat, MySQL環境作成
概要
今日はdockerを使ったjavaアプリ作成のためのローカル環境について書きます!
ちなみにこれから書く内容はMacBookPro × Docker18.06.0-ceで検証済したものとなります。
docker構成
作成したdocker-compose.ymlやDockerfileはこんな感じ
ディレクトリ構成
. ├── docker │ ├── mailcatcher01 │ │ └── Dockerfile │ ├── mysql01 │ │ ├── Dockerfile │ │ └── config │ │ └── charset.cnf │ ├── nginx01 │ │ ├── Dockerfile │ │ └── conf │ │ └── nginx.conf │ └── tomcat01 │ ├── Dockerfile │ ├── conf │ │ └── supervisord.conf │ └── deployment ├── docker-compose.yml └── tournament └── src ├── main │ ├── java │ └── resources └── test ├── java └── resources
docker-compose
基本的な書き方は公式をみて調べてもらえば書いてあるんで、あんまり書くこと無いですが、強いて言うならservlet01サービスにvolumesを指定。ローカル環境でビルドツール(gradleやmaven)により生成したwarファイルを./docker/tomcat01/deployment/以下に配置することでコンテナ内にも自動でデプロイできるようにしました。
version: '3' services: web01: container_name: nginx01 build: ./docker/nginx01 image: nginx01:1.0.0 ports: - "80:80" environment: TZ: "Asia/Tokyo" volumes: - ./docker/nginx01/conf:/etc/nginx/conf.d extra_hosts: - "tournament.local:127.0.0.1" servlet01: container_name: tomcat01 build: ./docker/tomcat01 image: tomcat01:1.0.0 environment: TZ: "Asia/Tokyo" expose: - "8080" ports: - "8000:8000" volumes: - ./docker/tomcat01/deployment:/usr/local/tomcat/webapps/:rw db01: container_name: mysql01 build: ./docker/mysql01 image: mysql01:1.0.0 command: >- /entrypoint.sh mysqld --slow_query_log=3 --long_query_time=3 --slow_query_log_file=/var/log/mysql/slow.log environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: tournament TZ: "Asia/Tokyo" ports: - "3306:3306" volumes: - data:/var/lib/mysql mail01: container_name: mailcatcher01 build: ./docker/mailcatcher01 image: mailcatcher01:1.0.0 ports: - 1025:1025 - 1080:1080 volumes: data: {}
Nginx
webサーバーにはNginxを使用。会社ではApacheしか触ったことなかったのでこっちを使ってみる。
FROM nginx:1.15.0
Nginxの設定ファイルがこんな感じ。
server { listen 80; server_name tournament.local; access_log /var/log/nginx/tomcat_access.log; error_log /var/log/nginx/tomcat_error.log; location / { proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://servlet01:8080/tournament/; index index.html index.htm; } }
- 80番ポートで自分の設定したドメイン(tournament.local)をキャッチ
- proxy_passでデプロイしたwarファイルtournament.warのコンテキストパスである/tournamentに飛ばす
- proxy_set_headerでリバースプロキシー対策の設定
Tomcat
JbossかJettyか悩んだけどサーブレットコンテナーにはTomcatを選択。
FROM tomcat:8.0-jre8-alpine # set server defautlt setting RUN apk --update add tzdata perl curl openssh openrc supervisor && \ rm -rf /var/cache/apk/* ENV TZ Asia/Tokyo # access to velocity frmo jboss ENV JAVA_OPTS="-Dspring.profiles.active=local" ENV JPDA_ADDRESS=8000 ENV JPDA_TRANSPORT=dt_socket # start tomcat & sshd COPY ./conf/supervisord.conf /etc/supervisor/conf.d/supervisord.conf CMD /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
Tomcatを起動させるだけならCMD ["catalina.sh", "run"]
だけでいいんですが、先日Tomcatのアプリケーションでscpファイル転送しようとしたらこれではうまくいかなかった。。
そんなときsupervisordで複数のプロセス起動する作戦にしたらうまく行ったのでこっちの方式にしてます。
[supervisord] nodaemon=true [program:sshd] command=/usr/sbin/sshd -D [program:tomcat] command=/usr/local/tomcat/bin/catalina.sh jpda run
ちなみにjdpaオプションをつけて起動させることでデバッグモードで実行できるようにしています。これはまた別の記事でも書くとしよー
MySQL
DBは慣れ親しんだMySQLにした
FROM mysql:5.6 # 設定ファイルを配置 # (MySQLは設定ファイルの権限が777だと読み込まない) COPY config /etc/mysql/conf.d/ RUN chmod 644 /etc/mysql/conf.d/* RUN apt-get update && \ apt-get install -y locales && \ rm -rf /var/lib/apt/lists/* && \ echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \ locale-gen ja_JP.UTF-8 ENV LC_ALL ja_JP.UTF-8
簡単な設定だけ書いておく
[mysqld] explicit_defaults_for_timestamp = 1 character-set-server=utf8 sql_mode=NO_ENGINE_SUBSTITUTION [mysql] default-character-set=utf8
mailcatcher
実際にメール送信しないが送信した内容を確認したいのでブラウザでSMTPを利用したメール送信を確認できるmailcatcherを使う!
FROM yappabe/mailcatcher
docker実行
ここまでファイルが出来たらあとはコマンド叩くとコンテナが立ち上がってアプリ開発ができる。
イメージ作成&コンテナ立ち上げ
--build
オプション付けるとビルドも一緒にやってくれる。
docker-compose up -d --build docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------------------------- mailcatcher01 /run.sh Up 0.0.0.0:1025->1025/tcp, 0.0.0.0:1080->1080/tcp mysql01 docker-entrypoint.sh /entr ... Up 0.0.0.0:3306->3306/tcp nginx01 nginx -g daemon off; Up 0.0.0.0:80->80/tcp tomcat01 /bin/sh -c /usr/bin/superv ... Up 0.0.0.0:8000->8000/tcp, 8080/tcp
こんな感じでStateがUpとなるとうまくいってるはず!
warファイルをデプロイ
どこかでちゃんと動く簡単なwarファイルをゲットしてファイル名をtournament.warにして./docker/tomcat01/deployment/tournament.war
に配置。
ブラウザでアクセス
http://tournament.local/
にアクセスしてデプロイしたjavaアプリケーションが動作したらOK
メールの内容を確認
http://tournament.local:1080/
にアクセスしてMailCatcherが表示さればOK
コンテナ終了
コンテナ終了したかったらこんな感じでコマンド叩く
docker-compose down Name Command State Ports ------------------------------
コンテナにアクセスする
Nginxのログを見る
コンテナ名(nginx01)を指定してコンテナにアクセス。アクセスログをtailでチェック
docker exec -it nginx01 bash tail -f /var/log/nginx/tomcat_access.log
Tomcatのログを見る
コンテナ名(tomcat01)を指定してコンテナにアクセス。tomcatのログをtailでチェックしてちゃんとデプロイされたか確認
docker exec -it tomcat01 bash tail -f /usr/local/tomcat/logs/catalina.2018-08-19.log
MySQLのデータを見る
コンテナ名(mysql01)を指定してコンテナにアクセス。mysqlコマンドでデータベースにアクセスしていろいろ操作。ユーザー名とパスワードは宜しく自分の環境で作ったものとか使用してくだされ
docker exec -it mysql01 bash mysql -h localhost -u root -proot
まとめ
ちゃんと動くwarファイルを用意して以下部分だけみんなの環境用に設定すれば動くはず。。。
- warファイル(sample.war)を
./docker/tomcat01/deployment/
に配置 - Nginxのプロキシー先のディレクトリをtournamentからsampleに変更
- ドメイン名を好きなものに変えてNginxのserver_nameもそれに変更
本当はこのdocker環境をAmazonECS(ElasticContainerService)に展開してそのまま本番でも動くようにしたかったが、結構壁にぶつかってしまったんでこれは時間を見つけてまた今度記事にしてみよう