起動ユーザーを変更したLibertyコンテナイメージの作成

Libertyコンテナはデフォルトでは`default(uid=1001)`というユーザーで起動し、このユーザーは`root(gid=0)`というグループに所属している。ファイル・ディレクトリのパーミッションは`664`または`775`となっている。

ユーザーを変更する方法をは以下の記事でも確認しているが、イメージサイズをなるべく小さくする方法を確認したメモ。

- [Libertyコンテナを非rootユーザーで実行する](https://qiita.com/sotoiwa/items/dc3f1d5ddec428f1ff45)

今回は`wasadmin(uid=2001)`というユーザーを作成し、このユーザーは`wasadmin(gid=2001)`に所属するようにするとする。また、ファイル・ディレクトリのパーミッションも`644`または`755`となるように変えるとする。

## kernel

はじめに、`kernel`のイメージの起動ユーザーを変えたい場合を確認する。

### FROM websphere-liberty:18.0.0.4-kernel

オリジナルの[kernelのDockerfile](https://github.com/WASdev/ci.docker/blob/1f420974a387fddfe980659f8536473b398143c9/ga/18.0.0.4/kernel/Dockerfile)でオーナー・パーミッションを設定をしているディレクトリに対して、上書きで設定する。

```dockerfile:Dockerfile
FROM websphere-liberty:18.0.0.4-kernel
USER 0
RUN groupadd -r -g 2001 wasadmin \
  && useradd -r -u 2001 -g wasadmin -s /usr/sbin/nologin wasadmin \
  && mkdir -p /home/wasadmin \
  && chown -R wasadmin:wasadmin /config \
  && chmod g-w /config \
  && chown -R wasadmin:wasadmin /opt/ibm/docker/docker-server \
  && chmod g-w /opt/ibm/docker/docker-server \
  && chown -R wasadmin:wasadmin /opt/ibm/wlp \
  && chmod g-w /opt/ibm/wlp \
  && chown -R wasadmin:wasadmin /logs \
  && chmod g-w /logs \
  && chown -R wasadmin:wasadmin /etc/wlp \
  && chmod g-w /etc/wlp \
  && chown -R wasadmin:wasadmin /lib.index.cache \
  && chmod g-w /lib.index.cache \
  && chown -R wasadmin:wasadmin /home/wasadmin \
  && chmod g-w /home/wasadmin
USER wasadmin
```

```shell
docker build -t wasadmin-liberty:18.0.0.4-kernel .
```

この方法でもよいが、レイヤーが二重になってしまい、イメージサイズが大きくなる。

### FROM ibmjava:8-jre

オリジナルの[kernelのDockerfile](https://github.com/WASdev/ci.docker/blob/1f420974a387fddfe980659f8536473b398143c9/ga/18.0.0.4/kernel/Dockerfile)を真似して、ユーザー作成部分とオーナー・パーミッション設定部分を改変する。`COPY`している部分は、ローカルにファイルがないので、`websphere-liberty:18.0.0.4-kernel`からコピーするようにする。

この方法がライセンス的にOKなのかは未確認。


```dockerfile:Dockerfile
FROM ibmjava:8-jre

RUN apt-get update \
    && apt-get install -y --no-install-recommends unzip \
    && rm -rf /var/lib/apt/lists/* \
    && mkdir /licenses/ \
    && groupadd -r -g 2001 wasadmin \
    && useradd -r -u 2001 -g wasadmin -s /usr/sbin/nologin wasadmin

COPY --from=websphere-liberty:18.0.0.4-kernel /licenses/*.html /licenses/

# Install WebSphere Liberty
ENV LIBERTY_VERSION 18.0.0_04
ARG LIBERTY_URL
ARG DOWNLOAD_OPTIONS=""
RUN LIBERTY_URL=${LIBERTY_URL:-$(wget -q -O - https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/wasdev/downloads/wlp/index.yml  | grep $LIBERTY_VERSION -A 6 | sed -n 's/\s*kernel:\s//p' | tr -d '\r' )}  \
    && wget $DOWNLOAD_OPTIONS $LIBERTY_URL -U UA-IBM-WebSphere-Liberty-Docker -O /tmp/wlp.zip \
    && unzip -q /tmp/wlp.zip -d /opt/ibm \
    && rm /tmp/wlp.zip \
    && chown -R 2001:2001 /opt/ibm/wlp \
    && chmod -R g+r /opt/ibm/wlp
ENV PATH=/opt/ibm/wlp/bin:$PATH

# Add labels for consumption by IBM Product Insights
LABEL "ProductID"="fbf6a96d49214c0abc6a3bc5da6e48cd" \
      "ProductName"="WebSphere Application Server Liberty" \
      "ProductVersion"="18.0.0.4"

# Set Path Shortcuts
ENV LOG_DIR=/logs \
    WLP_OUTPUT_DIR=/opt/ibm/wlp/output

# Configure WebSphere Liberty
RUN /opt/ibm/wlp/bin/server create \
    && rm -rf $WLP_OUTPUT_DIR/.classCache /output/workarea

COPY --from=websphere-liberty:18.0.0.4-kernel /opt/ibm/docker/docker-server /opt/ibm/docker/

# Create symlinks && set permissions for non-root user
RUN mkdir /logs \
    && mkdir /etc/wlp \
    && mkdir /lib.index.cache \
    && mkdir -p /home/wasadmin \
    && mkdir /output \
    && chmod -t /output \
    && rm -rf /output \
    && ln -s $WLP_OUTPUT_DIR/defaultServer /output \
    && ln -s /opt/ibm/wlp/usr/servers/defaultServer /config \
    && ln -s /opt/ibm /liberty \
    && mkdir -p /config/configDropins/defaults \
    && chown -R 2001:2001 /config \
    && chmod -R g+r /config \
    && chown -R 2001:2001 /opt/ibm/docker/docker-server \
    && chmod -R g+rx /opt/ibm/docker/docker-server \
    && chown -R 2001:2001 /opt/ibm/wlp \
    && chmod -R g+r /opt/ibm/wlp \
    && chown -R 2001:2001 /logs \
    && chmod -R g+r /logs \
    && chown -R 2001:2001 /etc/wlp \
    && chmod -R g+r /etc/wlp \
    && chown -R 2001:2001 /lib.index.cache \
    && chmod -R g+r /lib.index.cache \
    && chown -R 2001:2001 /home/wasadmin \
    && chmod -R g+r /home/wasadmin

USER 2001

EXPOSE 9080 9443

ENV KEYSTORE_REQUIRED true

ENTRYPOINT ["/opt/ibm/docker/docker-server"]
CMD ["/opt/ibm/wlp/bin/server", "run", "defaultServer"]
```

```shell
docker build -t wasadmin-liberty2:18.0.0.4-kernel .
```

### イメージサイズの比較

`kernel`であれば、オーナーを変更しているLiberty関連のファイルシステムがさほど大きくないので、それほど差はでない。

|イメージ|サイズ|備考|
|---|---|---|
|ubuntu:16.04|117MB||
|ibmjava:8-jre|317MB||
|websphere-liberty:18.0.0.4-kernel|358MB||
|wasadmin-liberty:18.0.0.4-kernel|379MB|websphere-liberty:18.0.0.4-kernelをベースに起動ユーザーを変更|
|wasadmin-liberty2:18.0.0.4-kernel|359MB|ibmjava:8-jreをベースに起動ユーザーを変更|

## javaee8

続いて、`javaee8`のイメージの起動ユーザーを変えたい場合を確認する。

### FROM websphere-liberty:18.0.0.4-javaee8

`websphere-liberty:18.0.0.4-javaee8`をベースにchwonする。

```dockerfile:Dockerfile
FROM websphere-liberty:18.0.0.4-javaee8
USER 0
RUN groupadd -r -g 2001 wasadmin \
  && useradd -r -u 2001 -g wasadmin -s /usr/sbin/nologin wasadmin \
  && mkdir -p /home/wasadmin \
  && chown -R wasadmin:wasadmin /config \
  && chmod g-w /config \
  && chown -R wasadmin:wasadmin /opt/ibm/docker/docker-server \
  && chmod g-w /opt/ibm/docker/docker-server \
  && chown -R wasadmin:wasadmin /opt/ibm/wlp \
  && chmod g-w /opt/ibm/wlp \
  && chown -R wasadmin:wasadmin /logs \
  && chmod g-w /logs \
  && chown -R wasadmin:wasadmin /etc/wlp \
  && chmod g-w /etc/wlp \
  && chown -R wasadmin:wasadmin /lib.index.cache \
  && chmod g-w /lib.index.cache \
  && chown -R wasadmin:wasadmin /home/wasadmin \
  && chmod g-w /home/wasadmin
USER wasadmin
```

```shell
docker build -t wasadmin-liberty:18.0.0.4-javaee8 .
```

### FROM wasadmin-liberty:18.0.0.4-kernel

先ほど`websphere-liberty:18.0.0.4-kernel`ベースでユーザーを変えたイメージをもとにして、[javaee8のDockerfile](https://github.com/WASdev/ci.docker/blob/1f420974a387fddfe980659f8536473b398143c9/ga/18.0.0.4/javaee8/Dockerfile)の内容を実行する。`COPY`部分はローカルにファイルがないので、`websphere-liberty:18.0.0.4-javaee8`イメージから持ってくる。

```dockerfile:Dockerfile
FROM wasadmin-liberty:18.0.0.4-kernel

ARG REPOSITORIES_PROPERTIES=""

RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
  && echo $REPOSITORIES_PROPERTIES > /opt/ibm/wlp/etc/repositories.properties; fi \
  && installUtility install --acceptLicense \
    appSecurity-2.0 ldapRegistry-3.0 \
    localConnector-1.0 monitor-1.0 requestTiming-1.0 restConnector-2.0 sessionCache-1.0 \
    sessionDatabase-1.0 ssl-1.0 transportSecurity-1.0 webCache-1.0 webProfile-8.0 \
    appSecurityClient-1.0 javaee-8.0 javaeeClient-8.0 openidConnectClient-1.0 monitor-1.0 microProfile-2.1 \
  && if [ ! -z $REPOSITORIES_PROPERTIES ]; then rm /opt/ibm/wlp/etc/repositories.properties; fi \
  && rm -rf /output/workarea /output/logs

COPY --from=websphere-liberty:18.0.0.4-javaee8 /config/server.xml /config/

RUN server start && server stop && rm -rf /output/resources/security/ /output/messaging /logs/*
```

```shell
docker build -t wasadmin-liberty2a:18.0.0.4-javaee8 .
```

### FROM wasadmin-liberty2:18.0.0.4-kernel

先ほど`ibmjava:8-jre`ベースでユーザーを変えたイメージをもとにして、[javaee8のDockerfile](https://github.com/WASdev/ci.docker/blob/1f420974a387fddfe980659f8536473b398143c9/ga/18.0.0.4/javaee8/Dockerfile)の内容を実行する。`COPY`部分はローカルにファイルがないので、`websphere-liberty:18.0.0.4-javaee8`イメージから持ってくる。

```dockerfile:Dockerfile
FROM wasadmin-liberty2:18.0.0.4-kernel

ARG REPOSITORIES_PROPERTIES=""

RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
  && echo $REPOSITORIES_PROPERTIES > /opt/ibm/wlp/etc/repositories.properties; fi \
  && installUtility install --acceptLicense \
    appSecurity-2.0 ldapRegistry-3.0 \
    localConnector-1.0 monitor-1.0 requestTiming-1.0 restConnector-2.0 sessionCache-1.0 \
    sessionDatabase-1.0 ssl-1.0 transportSecurity-1.0 webCache-1.0 webProfile-8.0 \
    appSecurityClient-1.0 javaee-8.0 javaeeClient-8.0 openidConnectClient-1.0 monitor-1.0 microProfile-2.1 \
  && if [ ! -z $REPOSITORIES_PROPERTIES ]; then rm /opt/ibm/wlp/etc/repositories.properties; fi \
  && rm -rf /output/workarea /output/logs

COPY --from=websphere-liberty:18.0.0.4-javaee8 /config/server.xml /config/

RUN server start && server stop && rm -rf /output/resources/security/ /output/messaging /logs/*
```

```shell
docker build -t wasadmin-liberty2b:18.0.0.4-javaee8 .
```

### イメージサイズの比較

`javaee8`の場合はLibertyのファイルシステムが大きいので、起動ユーザーの変更方法によりかなり差が出る。

|イメージ|サイズ|備考|
|---|---|---|
|websphere-liberty:18.0.0.4-javaee8|584MB|
|wasadmin-liberty:18.0.0.4-javaee8|829MB|websphere-liberty:18.0.0.4-javaee8をベースに起動ユーザーを変更
|wasadmin-liberty2a:18.0.0.4-javaee8|604MB|wasadmin-liberty:18.0.0.4-kernelをベースに起動ユーザーを変更<br>（websphere-liberty:18.0.0.4-kernelをベースに起動ユーザーを変更）|
|wasadmin-liberty2b:18.0.0.4-javaee8|584MB|wasadmin-liberty2:18.0.0.4-kernelをベースに起動ユーザーを変更<br>（ibmjava:8-jreをベースに起動ユーザーを変更）|