Search K
Appearance
Appearance
Dockerfile 中使用到的命令:
| 命令 | 作用 |
|---|---|
FROM image | 以 image镜像问基础 |
WORKDIR /path | 指定镜像内的相对目录,类似于 cd /path操作,Dockerfile 后续容器的相对路径都是基于此路径 |
ENV key=value | 指定容器内的环境变量 kv |
ARG key=value | 指定 Dockefile 文件内的变量 |
COPY src dest | 将 src 目录拷贝到容器内 dest 目录,src 目录相对于 Dockerfile 的上下文,dest 相对于 WORKDIR,如果 Dockerfile 没有指指定 WORKDIR,则向上查找父镜像,最后容器跟目录兜底 |
RUN command | 执行命令 |
EXPOSE port | 暴露端口,仅说明,并无实际功能。 可以 inspect 镜像来查看暴露的端口信息,可以写多行暴露多个端口。 |
EXTRYPOINT ["node"] | |
CMD ["app.js"] |
在项目根目录下新建一个名为 Dockerfile 的文本文件:
# from image 表示从当前image的基础上构建镜像
FROM node:16-alpine
# 指定镜像的相对目录, 相当于 cd /app
# Dockerfile后续镜像的相对路径都是相对于 /app
WORKDIR /app
# env指定的是容器内的env变量
ENV version=1
# arg指定的是dockerfile文件内的变量
ARG tag=1
# 第一个点是相对于Dockerfile所在的context上下文
# 第二个点则是相对于 WORKDIR 的目录,此时则是 /app
COPY . .
# RUN是执行shell命令
RUN npm install
# 镜像对外暴露端口
EXPOSE 8080
# EXPOSE 8080/udp
# ENTRYPOINT和CMD以及run镜像时传入的命令参数, 这三者产生的作用可以参考官方文档
ENTRYPOINT ["node"]
CMD ["app.js"]Dockerfile 上下文 Context
指 Dockerfile 所在的目录
在使用 COPY, ADD 命令时, 只可以添加上下文的文件到镜像中去, node_modules 或者 python 的 env 目录中存在很多小文件,这些小文件的存在影响了上下文 Context 的大小,影响 Docker 构建的性能,通常可以忽略这些文件。
TIP
在项目根录下创建一个.dockerignore的文本文件, 忽略排除掉无关的目录。
.dockerignore 采用类 glob 的模式匹配,但实际上和 glob 还是有很大区别。
# 表示注释/ 匹配根路径* 匹配 0 或 多个字符** 匹配任意深度的目录! 忽略反转本行规则
创建 .dockerignore 文件:
touch .dockerignore排除目录:
# 忽略 logs 目录
logs
# 忽略 logs 目录
logs/
# 忽略 src 目录
/src/
# 反转规则,不忽略排除 /src/main,即保留该目录
!/src/main
# 排除项目根目录下所有 .log 后缀的文件
*.log
# 排除所有层级下的 .log 后缀的文件
**/*.log
# 排除所有层级下的 node_modules 和 env 目录
**/node_modules/
**/env/# -t 表示 tag
# .表示从当前目录寻找Dockerfile文件来构建
docker build -t myapp .
# -f 指定具体的 Dockerfile文件来打包镜像
docker build -t myapp -f ./Dockerfile.devDocker 构建镜像是一个比较费时的过程,可以合理的利用 Docker 的 Layer 缓存机制来实现镜像打包的优化。
TIP
Dockerfile 文件中的每一行都是一个 Layer 层,Layer 层可以复用,形成类似缓存的效果。
优先把不易变更的内容写在 Dockerfile 中,即使重复多写几条类似的命令也没关系, 第一次构建后此行会变成 Layer 层缓存起来,后续每次 build 在缓存没破坏时,都会复用该 Layer 层缓存。
Node.js 应用打包镜像的简单优化案例:
FROM node:16-alpine
WORKDIR /app
# 拷贝多个文件时需要具体指明路径./ , 不可以只用 .
COPY package.json package-lock.json ./
RUN npm install
ENV a=1
COPY . .
ENTRYPOINT ["node"]
CMD ["app.js"]注意
COPY package.json package-lock.json ./ 命令被单独提出来,因为这 2 个文件的变动远小于工作区文件的变动,可以单独提出来形成一个 Layer 缓存层,从而在理论上加快一点速度。
多阶段构建主要是把不同功能的工作放到不同的镜像中完成, 比如编译工作和构建生产镜像包可以在不同阶段来构建。
编译所使用的 Dockerfile 文件配置:
# 编译
FROM gcc:9 as builder
WORKDIR /src
COPY main.c .
RUN gcc --static -o main main.c打包镜像所需要的 Dockerfile 文件配置:
# 构建镜像
FROM alpine:3
COPY --from=builder /src/main .
ENTRYPOINT ["/main"]
CMD []