Dockerfile配置详解
1、关于Dockerfile
- 基于Dockerfile制作镜像,每一个指令都会创建一个镜像层,因此能一个指令完成的动作尽量通过一个指令进行定义,否则会导致镜像层太多
- 构建命令:
docker build -t [镜像名:版本号] .
docker build -t [镜像名:版本号] -f ./Dockerfile
参数-f
可以指定Dockerfile的文件名
2、配置详解
说明
- Dockerfile的注释行都是以
#
开头的。除注释外,每一行都是一条指令,指令通常是用大写的方式,这样可读性会高些。 - 部分指令(
FROM
、RUN
、ADD
、COPY
…),如果是往镜像中新增文件或程序,就会在镜像中创建新的镜像层 - 其他指令只是告诉Docker如何构建或者运行应用程序,就只会增加或修改镜像的元数据信息。
- 每个
RUN
指令会新增一个镜像层,因此提倡使用&&
连接多个命令以及使用反斜杠\
换行的方法,将多个命令包含在一个RUN指令中。 - 建议在构建后进行清理,当使用RUN执行一个命令时,通常会拉取一些构建工具,这些工具最好将其移除。
多阶段构建
- 一份多阶段构建示例Dockerfile(原文出自《深入浅出Docker》)
多阶段构建
多阶段构建方式是使用一个Dockerfile,其中包含多个FROM
指令,每个FROM指令都是一个新的构建阶段,并且可以复制之前阶段的构件AS
为镜像定义一个便于理解的名称COPY --from
从之前的阶段构建的镜像中复制所需要的应用程序
FROM node:latest AS storefront
WORKDIR /usr/src/atsea/app/react-app
COPY react-app .
RUN npm install
RUN npm run build
FROM maven:latest AS appserver
WORKDIR /usr/src/atsea
COPY pom.xml .
RUN mvn -B -f pom.xml -s /usr/share/maven/ref/settings-docker.xml dependency:resolve
COPY . .
RUN mvn -B -s /usr/share/maven/ref/settings-docker.xml package -DskipTests
FROM java:8-jdk-alpine
RUN adduser -Dh /home/gordon gordon
WORKDIR /static
COPY --from=storefront /usr/src/atsea/app/react-app/build/ .
WORKDIR /app
COPY --from=appserver /usr/src/atsea/target/AtSea-0.0.1-SNAPSHOT.jar .
ENTRYPOINT ["java", "-jar", "/app/AtSea-0.0.1-SNAPSHOT.jar"]
CMD ["--spring.profiles.active=postgres"]
常用指令
- 详细使用访问:https://www.jianshu.com/p/1aed40d82c62
FROM
用于指定基础镜像,通常是Dockerfile中的第一条指令MAINTAINER
用于指定镜像作者信息RUN
用于在镜像中执行命令,每个RUN指令都会创建一个新的镜像层
ADD
用于从宿主机复制文件到镜像中
COPY
用于将文件作为一个新的镜像层添加到镜像中。CMD
用于指定启动时需要执行的命令
- 如果存在多条CMD命令,那么只有最后一个会生效
- 如果在
docker run
中指定需要执行的命令,那么会覆盖Dockerfile中的CMD命令 - 如果指定了ENTRYPOINT,则会将CMD作为参数拼接在ENTRYPOINT后面,执行整条命令
ENTRYPOINT
用于指定镜像以容器方式启动后默认运行的程序
- 只能指定一条,如果指定多条,那么只有最后一条会生效
- 容器启动
docker run
中指定需要执行的命令会被拼接到ENTRYPOINT后面作为完整命令执行
LABEL
用于为镜像添加元数据ENV
用于设置环境变量EXPOSE
用于记录应用所使用的网络端口VOLUME
用于指定挂载路径,只能实现匿名挂载WORKDIR
用于指定工作路径,后续的指定将在该目录中执行USER
用于指定运行上述指令或者启动容器时的用户名或UIDARG
用于指定传递给构建运行时的变量ONBUILD
用于设置镜像触发器
3、redis官方示例
FROM debian:bullseye-slim
RUN groupadd -r -g 999 redis && useradd -r -g redis -u 999 redis
ENV GOSU_VERSION 1.12
RUN set -eux; \
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates dirmngr gnupg wget; \
rm -rf /var/lib/apt/lists/*; \
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"; \
export GNUPGHOME="$(mktemp -d)"; \
gpg --batch --keyserver hkps:
gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
gpgconf --kill all; \
rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
chmod +x /usr/local/bin/gosu; \
gosu --version; \
gosu nobody true
ENV REDIS_VERSION 6.2.6
ENV REDIS_DOWNLOAD_URL http:
ENV REDIS_DOWNLOAD_SHA 5b2b8b7a50111ef395bf1c1d5be11e6e167ac018125055daa8b5c2317ae131ab
RUN set -eux; \
\
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends \
ca-certificates \
wget \
\
dpkg-dev \
gcc \
libc6-dev \
libssl-dev \
make \
; \
rm -rf /var/lib/apt/lists/*; \
\
wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; \
echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; \
mkdir -p /usr/src/redis; \
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; \
rm redis.tar.gz; \
\
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' /usr/src/redis/src/config.c; \
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' /usr/src/redis/src/config.c; \
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' /usr/src/redis/src/config.c; \
\
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
extraJemallocConfigureFlags="--build=$gnuArch"; \
dpkgArch="$(dpkg --print-architecture)"; \
case "${dpkgArch##*-}" in \
amd64 | i386 | x32) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=12" ;; \
*) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=16" ;; \
esac; \
extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-hugepage=21"; \
grep -F 'cd jemalloc && ./configure ' /usr/src/redis/deps/Makefile; \
sed -ri 's!cd jemalloc && ./configure !&'"$extraJemallocConfigureFlags"' !' /usr/src/redis/deps/Makefile; \
grep -F "cd jemalloc && ./configure $extraJemallocConfigureFlags " /usr/src/redis/deps/Makefile; \
\
export BUILD_TLS=yes; \
make -C /usr/src/redis -j "$(nproc)" all; \
make -C /usr/src/redis install; \
\
serverMd5="$(md5sum /usr/local/bin/redis-server | cut -d' ' -f1)"; export serverMd5; \
find /usr/local/bin/redis* -maxdepth 0 \
-type f -not -name redis-server \
-exec sh -eux -c ' \
md5="$(md5sum "$1" | cut -d" " -f1)"; \
test "$md5" = "$serverMd5"; \
' -- '{}' ';' \
-exec ln -svfT 'redis-server' '{}' ';' \
; \
\
rm -r /usr/src/redis; \
\
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; \
find /usr/local -type f -executable -exec ldd '{}' ';' \
| awk '/=>/ { print $(NF-1) }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -r apt-mark manual \
; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
\
redis-cli --version; \
redis-server --version
RUN mkdir /data && chown redis:redis /data
VOLUME /data
WORKDIR /data
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 6379
CMD ["redis-server"]