📘
コンテナで複数プロセスを起動する
目的
Java(Spring Boot)で作ったRestful WebAPIをNginx経由で呼び出したい。このときnginxとWebAPI(Javaアプリケーション)を1つのコンテナで稼働させるために、supervisorを使って複数プロセスを起動できる構成にする。
supervisord.confの作成
supervisorの設定ファイルを作成する。
-
[supervisord]セクション
- nodaemon:
true
を設定してdaemonで起動しないようにする(フォアグラウンドで動作させる)。
- nodaemon:
-
[program:xxxxx]セクション
- command: 実行するコマンドラインを記述する
今回は、java
とnginx
の2つ - stdout_xxx: 標準出力をコンテナログにリダイレクトする
- stderr_xxx: 標準エラー出力をコンテナログにリダイレクトする
- autostart: 自動起動を有効化(default : true)
- autorestart: 自動再起動を有効化(default : unexpected)
- command: 実行するコマンドラインを記述する
[supervisord]
nodaemon=true
[program:java-app]
command=java -Dfile.encoding=UTF-8 -jar /app/<jar file name>.jar
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=10
[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=5
Dockerfileの作成
Dockerファイルに記述する主な内容は次の通り。
- nginxをインストールする
- supervisorをインストールする
- JDKをコピー&Javaの設定をする
- 今回はMicrosoft Build of OpenJDKを使用
- ファイルをコピーする
- 作成したconfigファイル
- ビルドしたアプリケーション
FROM ubuntu:20.04
# Install nginx
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get install -y gnupg2 ca-certificates \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ABF5BD827BD9BF62 \
&& echo "deb https://nginx.org/packages/ubuntu/ focal nginx" >> /etc/apt/sources.list.d/nginx.list \
&& echo "deb-src https://nginx.org/packages/ubuntu/ focal nginx" >> /etc/apt/sources.list.d/nginx.list \
&& apt-get update \
&& apt-get install -y nginx --no-install-recommends
# Install Supervisor
RUN apt-get update \
&& apt-get install -y supervisor \
&& mkdir -p /var/log/supervisor
# Copy JDK
ENV JAVA_HOME /usr/lib/jvm/msopenjdk-17-amd64
ENV PATH "${JAVA_HOME}/bin:${PATH}"
COPY $JAVA_HOME $JAVA_HOME
# Copy .conf
COPY ./nginx/default /etc/nginx/conf.d/default.conf
COPY ./supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy Application
RUN mkdir /app
COPY ./app/<jar file name>.jar /app/<jar file name>.jar
EXPOSE 80
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
Containerの起動をShellにする
ShellFileから起動したい場合は、以下のようにする。
-
Shellファイルを用意
# # 実行したい処理を記述 # # supervisorを起動 /usr/bin/supervisord
-
Dockerfileをshellを起動するように修正
#~中略~ # Copy .sh COPY ./startup/container_startup.sh container_startup.sh EXPOSE 80 # CMD ["supervisord", "-c", "/etc/supervisord.conf"] CMD ["sh","-c","./container_startup.sh"]
JDKのContainerイメージを使用した場合
JDKのディストリビューションのコンテナイメージを使用するとJDKの追加部分が不要になる。
# Use JDK Image
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu
# Install nginx
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get install -y gnupg2 ca-certificates \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ABF5BD827BD9BF62 \
&& echo "deb https://nginx.org/packages/ubuntu/ focal nginx" >> /etc/apt/sources.list.d/nginx.list \
&& echo "deb-src https://nginx.org/packages/ubuntu/ focal nginx" >> /etc/apt/sources.list.d/nginx.list \
&& apt-get update \
&& apt-get install -y nginx --no-install-recommends
# Install Supervisor
RUN apt-get update \
&& apt-get install -y supervisor \
&& mkdir -p /var/log/supervisor
# Copy .conf
COPY ./nginx/default /etc/nginx/conf.d/default.conf
COPY ./supervisor/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy Application
RUN mkdir /app
COPY ./app/<jar file name>.jar /app/<jar file name>.jar
# Copy .sh
COPY ./startup/container_startup.sh container_startup.sh
EXPOSE 80
CMD ["sh","-c","./container_startup.sh"]
おわりに
Java側の死活監視の要否や1コンテナ・1プロセス論とかはまた別の話。
参考にしたドキュメント
Discussion