こんにちは、虎の穴ラボのY.Nです。
本記事は虎の穴ラボ Advent Calendar 2020 - Qiita 14日目の記事になります。
13日目はいわみーさんが「エンドユーザー向けのヘルプを書く時に気をつけていること」と言う記事を書かれています。
15日目はY.Iさんが「Pug+Stylusでお手軽にCSSお絵かきを初めよう!〜CSSお絵かき環境構築と便利なプロパティ紹介〜」という記事を書かれる予定です。
本記事の内容
開発環境と本番環境を簡単に振り分けできるようにDocker化していくのが本記事の内容です。
とらのあなが運営している「とらのあな通販」の業務サポートツール(以下ツール)があるのですが、
どうやら本番環境のDBを参照したり変更するのにテストを行う開発環境がないということで
→じゃあDockerで開発環境作ろう、どうせなら本番環境もDockerでデプロイできるようにしてしまおう。
というモチベーションではじめました。
本記事で使用する主な技術は下記のとおりです。
- Gradle
- Docker
- docker-compose
目次
ツールの構成について
ディレクトリ構成
ツールのディレクトリ構成は下記のようになっています。
/Tool - /gradle - /libs - /src - /main - /bat - /java - /kotlin - /resources - Database_dev.properties - Database_prod.properties - ... - gradlewなど...
ここで注目してほしいのは、Database_dev.propertiesとDatabase_prod.propertiesというファイルです。
DBのIPアドレス等の接続情報が記載されており、devが開発環境用、prodが本番環境用としています。
DBの接続先の変更
Database_xxx.propertiesの切り替えにはコマンドライン引数を使用します。
val db = "db:dev"; args.forEach { argument -> when { // ここで「db:xxx」というコマンドライン引数があれば取得します "^db:[a-zA-Z]+".toRegex().matches(argument) -> db = argument } } // DAOのコンストラクタ内でdb:prodならDatabase_prodを、それ以外ならDatabase_devを読み込むようにします val ecDao = OracleDao(db, OracleDao.DataBaseType.EC) val ecmdDao = OracleDao(db, OracleDao.DataBaseType.ECMD) val hogeDao = OracleDao(db, OracleDao.DataBaseType.HOGE) val fugaDao = OracleDao(db, OracleDao.DataBaseType.FUGA)
環境構築
下記の内容はMacOSで行っています。
Dockerのインストール
Dockerのインストールは公式に従って行います。
Install Docker Desktop on Mac | Docker Documentation
開発環境
それでは、開発環境をDockerコンテナ化していきましょう。
Dockerfileを作る
まず、Dockerfileを置くディレクトリを作成します。
mkdir -p Docker/dev
↑で作ったディレクトリにDockerfileを作成します。
FROM java:openjdk-8-jdk-alpine COPY . /Tool RUN apk update \ && apk add --virtual build-dependencies build-base bash curl \ && cd /Tool && ./gradlew clean \ && cd /Tool && ./gradlew build \ && mkdir -p /opt/ectool/bin/log/ \ && cp -R /Tool/build/libs/* /opt/ectool/bin \ && apk del build-dependencies \ && rm -rf /var/cache/apk/* \ && rm -rf ~/.gradle \ && rm -rf /Tool EXPOSE 8080 ENTRYPOINT java -jar -Xms1G -Xmx1G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/ectool/bin/log/ /opt/ectool/bin/*.jar db:dev, file:dev, 1>>/opt/ectool/bin/log/ectool_output.log, 2>> /opt/ectool/bin/log/ectool_error.log
イメージはOpenJDK8のAlpineイメージを使用しています。
やってることはこんな感じ
- プロジェクトをイメージ内の"/Tool"にコピー
- 必要なソフトウェアをインストール
- クリーンビルド
- ビルド結果を入れるディレクトリの作成
- ビルド結果を↑で作ったディレクトリに入れる
- 不要になったソフトウェアと一時ファイル、ソースコードを削除
- jarファイルの起動 → この時、引数に"db:dev"を渡しています
ビルドしてみる
それでは、ビルドしてみましょう。
# docker build -f Docker/dev/Dockerfile . ... Successfully built 1f6e0d3cb71c
できたっぽいですね、イメージを確認してみます。
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 1f6e0d3cb71c 27 seconds ago 256MB
できてそうです!
では、イメージのビルドができたので、次はdocker-composeでコンテナ作成と起動までを自動化していきます。
ちなみに、このイメージを起動するときはこんな感じで起動できます。
docker run -d -p 8080:8080 1f6e
localhost:8080 でアクセスできます
(次の作業のために、起動したコンテナはdocker stopで停止させておくかコンテナを削除しておいてください。)
docker-compose.ymlを作る
先程作ったディレクトリ(./Docker/dev)にdocker-compose.ymlというファイルを作成します。
version: '3' services: ectool-dev: build: context: ../../ dockerfile: Docker/dev/Dockerfile container_name: 'ectool-dev' ports: - 8080:8080 volumes: - /opt/ectool/bin/log:/opt/ectool/bin/log
記載内容はこんな感じです。
- context:ビルドするアプリのルートディレクトリの相対位置を指しています。
- dockerfile:contextから見たDockerfileの場所を指しています。
- ports:ホストとコンテナのポートフォワードを書いています(docker run -p 8080:8080と同じです)
- volumes:ログを永続化させるためにホストのディレクトリにマウントさせます。
予めディレクトリの作成とDocker Desktopの共有設定をする必要があります。
(Docker Desktop -> Preferences -> Resources -> FILE SHARING)
イメージをビルドする
docker-composeを使用してイメージをビルドしていきます。
# docker-compose -f Docker/dev/docker-compose.yml build --no-cache ... Successfully built 7272297d9f23 Successfully tagged dev_ectool-dev:latest
先程のdocker build
と同じ結果が出ます。
イメージも確認してみましょう。
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE dev_ectool-dev latest 7272297d9f23 About a minute ago 256MB
名前もついていい感じにできていますね!
コンテナを作る
では、いよいよ作ったイメージをコンテナにしてみましょう!
# docker-compose -f Docker/dev/docker-compose.yml up -d Creating ectool-dev ... done
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 92582bbf40c8 dev_ectool-dev "/bin/sh -c 'java -j…" 20 seconds ago Up 18 seconds 0.0.0.0:8080->8080/tcp ectool-dev
はい、できました!
それでは起動を確認していきます。
http://localhost:8080/
立ち上がりました!注文伝票検索機能を使うと....
明らかにテストっぽいデータが出てますね!やったー!
確認したら下記コマンドでコンテナを終了します。
# docker-compose -f Docker/dev/docker-compose.yml down Stopping ectool-dev ... done Removing ectool-dev ... done Removing network dev_default
本番環境
ということで開発環境はできました。次は本番環境を構築してみます。
Dockerfileを作る
こちらも本番環境用のDockerfileを置くディレクトリを作成します。
mkdir -p Docker/prod
↑で作ったディレクトリにDockerfileを作成します。
FROM java:openjdk-8-jdk-alpine COPY . /Tool RUN apk update \ && apk add --virtual build-dependencies build-base bash curl \ && cd /Tool && ./gradlew clean \ && cd /Tool && ./gradlew build \ && mkdir -p /opt/ectool/bin/log/ \ && cp -R /Tool/build/libs/* /opt/ectool/bin \ && apk del build-dependencies \ && rm -rf /var/cache/apk/* \ && rm -rf ~/.gradle \ && rm -rf /Tool EXPOSE 8080 ENTRYPOINT java -jar -Xms1G -Xmx1G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/ectool/bin/log/ /opt/ectool/bin/*.jar db:prod, file:prod, 1>>/opt/ectool/bin/log/ectool_output.log, 2>> /opt/ectool/bin/log/ectool_error.log
db:dev、file:devをそれぞれdb:prod、file:prodに変えているだけですね
docker-compose.ymlを作る
続けてdocker-compose.ymlを作ります。
version: '3' services: ectool-prod: build: context: ../../ dockerfile: Docker/prod/Dockerfile container_name: 'ectool-prod' ports: - 8080:8080 volumes: - /opt/ectool/bin/log:/opt/ectool/bin/log
起動する
ちなみに、docker-compose up はイメージがなければビルドも一緒にやってくれるのでdocker-compose buildは省略します。
# docker-compose -f Docker/prod/docker-compose.yml up -d Creating ectool-prod ... done
また、localhost:8080にアクセスしてみます。
同じ画面が出てきますが、注文伝票検索機能を使うと....
とらのあな通販での実際の注文伝票の内容が出てきました!※実際のご注文内容のため伏せさせていただきます。
まとめ
Dockerfileとdocker-compose.ymlとを2つずつ作って、環境ごとイメージを作り変えるといったことをやってきました。
これからDocker触るよとかDockerfileとdocker-composeを環境ごとに分けたいんだよねみたいな方の参考になれば良いなと思います!
これで開発環境ができて開発もやりやすくなって、本番環境のデプロイも楽になりそうな気がするので、
今後は、JenkinsやGitHub ActionsなどでCI/CDも使って自動デプロイとかできるといいなと考えています。
長くなりましたが、お読みいただきありがとうございました。
P.S.
虎の穴ラボではいくつかのオンラインイベントを企画しております。是非ご参加ください!!
【オンライン】とらのあなラボエンジニア座談会Vol.5【リーダー対談】
12/18(金) 19:30から「虎の穴ラボ」社員によるトークイベントを準備しております。 yumenosora.connpass.com
TORA LAB Management & Leader Meetup
12/23(金) 19:30からとらのあなが運営している「とらのあな通販」と「Fantia」の開発の魅力を発表し、参加いただいた方の気になる点やご質問に答えるイベントとなっています。 yumenosora.connpass.com
その他採用情報
虎の穴ラボでの開発に少しでも興味を持っていただけた方は、採用説明会やカジュアル面談という場でもっと深くお話しすることもできます。ぜひお気軽に申し込みいただければ幸いです。 カジュアル面談では虎の穴ラボのエンジニアが、開発プロセスの内容であったり、「今期何見ました?」といったオタクトークから業務の話まで何でもお応えします。 カジュアル面談や採用情報はこちらをご確認ください。 yumenosora.co.jp