不知道各位在團隊已經 Dockerize 一陣子以來,有沒有認真探究過
Dockerfile
究竟是在做什麼呢?
沒有也沒關係,今天就由本人來小小講解一下 Dockerfile 的奧妙之處吧。
如果已經忘記前一篇,或還沒試過 docker commit 的各位,先去玩一下體驗一下。
Dockerfile 說穿了其實就是 自動化 跟 標準化 docker commit 在做的事。試想如果每一次針對 container 可讀寫的那一層做了什麼事都要 手動 下一次 docker commit 那會有多麻煩。
就如同初學 java 的時候我們總會經過以下的步驟:
撰寫 Dockerfile 的時候其實也有 類似的步驟 :
以上其實有三個重點:
一個 Spring boot Application 的 Dockerfile 範例如下:
FROM openjdk:8-jdk-alpine ENV GOSU_VERSION 1.12 RUN set -eux; \ \ apk add --no-cache --virtual .gosu-deps \ ca-certificates \ dpkg \ gnupg \ ; \ \ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \ wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \ wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \ \ # verify the signature export GNUPGHOME="$(mktemp -d)"; \ gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \ gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \ command -v gpgconf && gpgconf --kill all || :; \ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \ \ # clean up fetch dependencies apk del --no-network .gosu-deps; \ \ chmod +x /usr/local/bin/gosu; \ # verify that the binary works gosu --version; \ gosu nobody true ARG JAR_NAME=app.jar ARG HOME_DIR=/home/java-app # Setting timezone ENV TZ=Asia/Taipei ENV JAR_PATH=$HOME_DIR/$JAR_NAME RUN apk --update add tzdata && \ cp /usr/share/zoneinfo/Asia/Taipei /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/* RUN set -eux && \ addgroup --gid 9999 java-app && \ adduser -S -u 9999 -g java-app -h $HOME_DIR -s /bin/sh -D java-app && \ chown -R java-app:java-app $HOME_DIR COPY --chown=java-app:java-app ./target/*-SNAPSHOT.jar $JAR_PATH COPY ./entrypoint.sh entrypoint.sh RUN chmod +x entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
針對 Dockerfile 還有更多興趣的人可以參考官方的 best practice 喔