不知道各位在團隊已經 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 喔
When you subscribe to the blog, we will send you an e-mail when there are new updates on the site so you wouldn't miss them.
評論