Dockerfile配置详解

Dockerfile配置详解

1、关于Dockerfile

  • 基于Dockerfile制作镜像,每一个指令都会创建一个镜像层,因此能一个指令完成的动作尽量通过一个指令进行定义,否则会导致镜像层太多
  • 构建命令:
    • docker build -t [镜像名:版本号] .
    • docker build -t [镜像名:版本号] -f ./Dockerfile 参数-f可以指定Dockerfile的文件名

2、配置详解

说明

  • Dockerfile的注释行都是以#开头的。除注释外,每一行都是一条指令,指令通常是用大写的方式,这样可读性会高些。
  • 部分指令(FROMRUNADDCOPY…),如果是往镜像中新增文件或程序,就会在镜像中创建新的镜像层
  • 其他指令只是告诉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 用于从宿主机复制文件到镜像中
    • 支持使用TAR文件和URL路径
  • COPY 用于将文件作为一个新的镜像层添加到镜像中。
  • CMD 用于指定启动时需要执行的命令
    • 如果存在多条CMD命令,那么只有最后一个会生效
    • 如果在docker run 中指定需要执行的命令,那么会覆盖Dockerfile中的CMD命令
    • 如果指定了ENTRYPOINT,则会将CMD作为参数拼接在ENTRYPOINT后面,执行整条命令
  • ENTRYPOINT 用于指定镜像以容器方式启动后默认运行的程序
    • 只能指定一条,如果指定多条,那么只有最后一条会生效
    • 容器启动docker run中指定需要执行的命令会被拼接到ENTRYPOINT后面作为完整命令执行
  • LABEL 用于为镜像添加元数据
  • ENV 用于设置环境变量
  • EXPOSE 用于记录应用所使用的网络端口
  • VOLUME 用于指定挂载路径,只能实现匿名挂载
  • WORKDIR 用于指定工作路径,后续的指定将在该目录中执行
  • USER 用于指定运行上述指令或者启动容器时的用户名或UID
  • ARG 用于指定传递给构建运行时的变量
  • ONBUILD 用于设置镜像触发器

3、redis官方示例

FROM debian:bullseye-slim

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r -g 999 redis && useradd -r -g redis -u 999 redis

# grab gosu for easy step-down from root
# https://github.com/tianon/gosu/releases
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://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
	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://download.redis.io/releases/redis-6.2.6.tar.gz
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; \
	\
# disable Redis protected mode [1] as it is unnecessary in context of Docker
# (ports are not automatically exposed when running inside Docker, but rather explicitly by specifying -p / -P)
# [1]: https://github.com/redis/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da
	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; \
# for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
# see also https://github.com/docker-library/redis/issues/4#issuecomment-50780840
# (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
	\
# https://github.com/jemalloc/jemalloc/issues/467 -- we need to patch the "./configure" for the bundled jemalloc to match how Debian compiles, for compatibility
# (also, we do cross-builds, so we need to embed the appropriate "--build=xxx" values to that "./configure" invocation)
	gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
	extraJemallocConfigureFlags="--build=$gnuArch"; \
# https://salsa.debian.org/debian/jemalloc/-/blob/c0a88c37a551be7d12e4863435365c9a6a51525f/debian/rules#L8-23
	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; \
	\
# TODO https://github.com/redis/redis/pull/3494 (deduplicate "redis-server" copies)
	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"]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值