概要
intra-martが起動するDockerコンテナを作成する にinspire the nextされ、ムシャクシャしてやってみた。
intra-mart の環境をDockerコンテナ上に構築します。
軽量と噂のalpineで。ubuntuならapt-getでresinが入るご時世なのにね。
今回目指すイメージは以下のような感じです。
- 「/imart/login」で、作成したテナント管理者でログインできるところまでを確認します。
- imart.warは、外から渡せるようにします。
- データベースは別に立てたコンテナのものを利用します。
- Webサーバ(Apacheとか)は用意しません。
- IMBoxとIM-ContentSearchは入れないものとします。(CassandraやSolrが必要なため)
試した各アプリケーションのバージョンです。
application | version | 説明 |
---|---|---|
Resin Pro | 4.0.48 | 本家が配布しているものを利用します。 |
OpenJDK | 1.8.0_92 | apkでインストールされるものを利用します。 |
intra-mart | 8.0.13(Maxima) | 2016 Springを利用します。 |
PostgreSQL | 9.5.3 | DockerHubで配布されているlatestを利用します。 |
注1 システム要件を100%満たしていないが、そこは不問とする。割り切った関係が大事です。
注2 本家のresin-proにはlicenseが含まれていないため、自分でlicenseを入れる必要があります。入れなくても30日ぐらいは動くらしい
注3 Oracleじゃなきゃダメなintra-mart上で動くアプリケーションは、見なかったことにする。
事前に用意しておくもの
- imart.war
- postgresのjdbcドライバ (postgresql-9.4.1208.jar)
intra-mart Accel シリーズ TRY版 ダウンロードからIM-Jugglingツールをダウンロードして、
warファイルを作成します。
手順の詳細は、インスパイア元に記載があるので、そちらを参照されたい。
resin-web.xmlについて
preparedStatementCacheQueriesの値を0とか8とか小さい値にしていないと、テナントのセットアップ時にエラーが出て泣けることになります。
本家のマニュアルでは、20を指定している例が提示されているけど、これだとエラーになった。
参考 intra-martのテナント環境セットアップ時にjava.sql.SQLExceptionが発生したときの対策
<database jndi-name="jdbc/default">
<driver>
<type>org.postgresql.Driver</type>
<url>jdbc:postgresql://postgres:5432/iap_db</url>
<user>imart</user>
<password>imart</password>
<init-param>
<param-name>preparedStatementCacheQueries</param-name>
<param-value>8</param-value>
</init-param>
</driver>
<max-connections>20</max-connections>
<prepared-statement-cache-size>8</prepared-statement-cache-size>
</database>
Dockerビルド用のファイルを作成
Dockerfile
以下のようなDockerfileを書きました。
javaさえあればいいんだろ、という甘い考えは、resinのmakeの段階で打ち砕かれます。
また、jni.hもmake時に必要です。なので、resinのmake後に、必要でなくなったタイミングでapk delで消します。(ダイエットのため)
alpineのサイトで、必要とされるファイル、それが含まれるパッケージを探します。
FROM alpine:3.4
ENV RESIN_VERSION 4.0.48
ENV RESIN_HOME /opt/resin-pro-${RESIN_VERSION}
ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk
RUN apk add --virtual=build-dependencies --no-cache g++ libstdc++ linux-headers make wget ca-certificates && \
apk add --no-cache openjdk8 && \
ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" && \
ALPINE_GLIBC_PACKAGE_VERSION="2.23-r3" && \
ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && \
wget \
"https://raw.githubusercontent.com/andyshinn/alpine-pkg-glibc/master/sgerrand.rsa.pub" \
-O "/etc/apk/keys/sgerrand.rsa.pub" && \
wget \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
apk add --no-cache \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && \
\
rm "/etc/apk/keys/sgerrand.rsa.pub" && \
/usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 C.UTF-8 || true && \
echo "export LANG=C.UTF-8" > /etc/profile.d/locale.sh && \
\
apk del glibc-i18n && \
\
rm "/root/.wget-hsts" && \
rm \
"$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" \
"$ALPINE_GLIBC_I18N_PACKAGE_FILENAME"
ENV LANG=C.UTF-8
RUN wget http://caucho.com/download/resin-pro-${RESIN_VERSION}.tar.gz -P /usr/local && \
cd /usr/local && \
tar xvzf resin-pro-${RESIN_VERSION}.tar.gz && \
rm -f resin-pro-${RESIN_VERSION}.tar.gz && \
cd resin-pro-${RESIN_VERSION} && \
./configure --prefix=/opt/resin-pro-${RESIN_VERSION} --enable-64bit && \
make && \
make install && \
rm -rf /usr/local/resin-pro-4.0.48 && \
ln -s /opt/resin-pro-${RESIN_VERSION} /opt/resin && \
apk del build-dependencies
EXPOSE 8080
ENTRYPOINT ["/opt/resin/bin/resinctl"," -server", "app-0", " start-with-foreground"]
本当はresin.propertiesなどを適切に編集する必要があるけど、動作確認レベルではなくても何とかなります。
割り切って先に進むことにします。
Dockerイメージのビルド
Dockerビルドを実行しイメージを作成します。
docker build -t imart-base:4.0.48 .
PostgreSQLの準備
イメージの取得&起動
docker run --name postgres -d -e PGPASSWORD=postgres -e POSTGRES_USER=postgres -p 5432:5432 postgres:latest
現時点でのlatestは9.5.3とのこと。
intra-martが接続するロールの作成
データベースとログインロールの作成を参照して、ロールを作ります。
今回はPostgreSQLもコンテナなので、こんな感じでやってみました。
まず、コンテナに接続。
docker exec -it postgres bash
PostgreSQLにつないで。
psql -U postgres
ロールとデータベースを作る。
postgres=# CREATE ROLE imart WITH LOGIN PASSWORD 'imart';
CREATE ROLE
postgres=# CREATE DATABASE iap_db OWNER imart ENCODING 'utf8';
CREATE DATABASE
resinのコンテナを起動する
まず、事前に用意したファイルが以下のようにあると仮定します。
- /home/intramart/war/*.war (IM-Jugglingで作成したwarファイル)
- /home/intramart/lib/*.jar (JDBCドライバ)
これをdocker runするときにマウントして渡すことにします。
先に立てたPostgreSQLは--linkで渡しておきます。
docker run -it -d --name intra -p 8080:8080 --link postgres:postgres -v /home/intramart/war/:/opt/resin/webapps -v /home/intramart/lib/:/opt/resin/webapp-jars imart-base:4.0.48
しばらくすると、warファイルの展開がなされ、resinが起動します。
テナントセットアップとログインの確認
以下にアクセスすると、初期設定画面が出てきます。ウィザードに従って進みます。
http://<Dockerのホスト>:8080/imart/system/login
この後、システム管理者でログインすると、以下のような画面になります。
以下にアクセスし、テナント管理者でもログインできることを確認します。
http://<Dockerのホスト>:8080/imart/login
おまけ
Resinの入ったコンテナのイメージサイズ
場所 | サイズ |
---|---|
Ubuntu(ビルドしている環境) | 337.3MB |
Gitlab Registry | 123 MB |
DockerのホストはUbuntu 16。 もう少し削れるかもしれない。