镜像构建
构建过程
- 创建Dockerfile文件。Dockerfile是用来构建Docker镜像的配置文件。
- 在Dockerfile中写入基础镜像信息和需要安装的软件包及配置信息。
- 构建镜像。使用docker build命令构建镜像。
docker build -t [镜像名]:[镜像标签] .
- 将构建的镜像推送到镜像仓库(如Docker Hub)。
docker login
docker push [镜像名]:[镜像标签]
Dockerfile书写内容
一般书写内容:
FROM 制作镜像的基础镜像
MAINTAINER 维护者的姓名和邮箱
RUN 希望在创建过程中运行的命令
COPY 将host目录下的文件拷贝到镜像内指定路径
WORKDIR 指定当前工作目录
VOLUME 分配卷
ENV 设置环境变量
EXPOSE 指定对外发布的端口
CMD 指定默认要运行的命令和参数,可被docker run指定的命令和参数替换
ENTRYPOINT 指定容器进程执行命令,不可被 docker run 指定的命令替换
下面是例子:
FROM node:18-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production
COPY . .
VOLUME ["/app_todo-mysql-data", "/todo-db"]
CMD ["node", "src/index.js"]
具体解析命令:
- FROM: 后面指定需要的镜像, 比如
FROM Ubuntu:18.04
这个只能使用一个镜像,你不满意,可以先打包然后添加你需要的内容和依赖,再次构建成你需要的镜像。
- MAINTAINER: 两个参数,第一个参数为作者名,第二个参数为邮箱, 比如:
MAINTAINER: gui 2238369245@qq.com
- RUN: 后面接命令,表示构建镜像执行的命令, 可以多次书写比如:
RUN touch test.txt
RUN rm test.txt
也可以一次书写多个。
RUN apt-get update && \
apt-get install -y package1 package2 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
里面的反斜杠表示换行
- COPY: 复制文件到镜像,有两个参数,第一个为要复制的文件名或者文件路径;第二个参数为复制到容器中的位置。 比如:
COPY file1 file2 .
这个表示将file1,file2复制到docker容器当前的工作目录下
COPY app/src ./src
表示把app/src目录下的所有文件复制到当前工作目录的src目录下,如果目录不存在它会帮你创建的,不要担心。
-
WORKDIR: 后面指定工作目录,在镜像里的位置,你指定的工作目录会存在于容器根目录下;除非你指定了路径,比如
WORKDIR: /tmp/app
, 这样就不会存放在根目录下了,而是具体的某一个目录下。 -
VOLUME: Dockerfile中预先指定一个容器内部的卷,以便在运行容器时进行挂载。
VOLUME ["/app_todo-mysql-data", "/todo-db"]
这里面可以指定多个卷,这里指定的卷默认会以原名的形式自动挂载到容器工作目录中。
如果要指定挂载位置,需要使用 -v ,比如说:
docker run -it -v /todo-db:/app/test test:4.0
- CMD: 指定创建容器之后的命令
CMD ["executable","param1","param2"]
CMD ["/usr/bin/wc","--help"]
CMD命令只能有一条,如果有多条,它只会执行最后一条,因为它是容器的启动命令;如果要执行多条语句,可以写成一个脚本。比如:
CMD ["sh", "-c", "/usr/local/bin/startup.sh && tail -f /dev/null"]
- ENTRYPOINT: 个人觉得和CMD作用差不多,不过这个命令不能被run 方法指定命令时替换。
CMD如果您想更改命令,则可以在运行时指定新的命令,它会覆盖原来的:
$ docker run <镜像> echo "Hello, Docker!"
Hello, Docker!
建议使用 CMD 指定容器启动时要执行的命令,这样可以提高容器镜像的灵活性和可维护性。
.dockerignore file
该文件用于忽略文件。
当你使用ADD添加文件或者COPY复制文件时,你想直接复制一个文件夹下的内容,但是里面又有几个文件我不想要。我们就可以使用.dockerfile文件。
.dockerignore
文件必须与 Dockerfile 文件位于同一目录下,且文件名必须精确命名为 .dockerignore
。
.dockerignore
文件是可选的,用于告诉 Docker 在构建镜像时忽略指定的文件或目录。该文件中列出的文件和目录将被排除在构建上下文之外,从而减少构建上下文的大小并加速构建过程。
这个文件的意思就是不复制或添加当前目录下的node_modules。
docker build 命令
docker build 命令用于构建对象,它默认是去寻找当前目录下的Dockerfile文件,以它为基础进行镜像的构建。
你不一定非要使用Dockerfile, 你可以自己创建文件然后去加载,但是必须使用 -f 去指定文件。
下面是一些常见option
- -t: 用于指定构建的镜像名称和标签。例如,
-t mytest:latest
将构建一个名为mytest
,标签为latest
的镜像。 - -f: 用于指定 Dockerfile 文件的路径和名称。默认情况下,Docker 使用当前目录下的
Dockerfile
文件来构建镜像。如果 Dockerfile 文件的名称或路径不同,可以使用-f
选项指定。例如,-f /path/to/Dockerfile
将使用/path/to/Dockerfile
文件来构建镜像。 - -m: 用于指定构建时使用的内存限制。例如,
-m 2g
将限制构建过程使用的内存为 2GB。 - –cpu-shares: 用于指定构建时使用的 CPU 资源配额。例如,
--cpu-shares 1024
将限制构建过程使用的 CPU 时间为 1024 个 CPU 分配单位。 - –no-cache: 用于禁用构建缓存,强制 Docker 从头开始构建镜像。如果 Dockerfile 中的指令没有变化,使用缓存可以加快构建速度,但可能会导致构建出的镜像不是最新的。
- –pull: 用于强制 Docker 从远程仓库拉取最新的基础镜像。如果不使用该选项,Docker 可能会使用本地缓存的基础镜像,而不是从远程仓库拉取最新的版本。
构建中使用缓存
你在构建的时候,你会不会发现构建第一次时会很慢,然后你只改变名字构建第二个镜像,会发现速度奇快。
这就是docker的缓存机制,它会缓存你上一次的构建数据。
docker每个命令都会创建一个新的镜像层,并在上一个镜像层的基础上进行修改。因此,命令的顺序可以影响镜像的大小和构建时间。
一般来说,应该将不太可能发生变化的指令放在前面,而将可能发生变化的指令放在后面。例如,可以先安装操作系统和软件包,再将应用程序复制到镜像中。这样,如果您在应用程序代码中进行了更新,只需要重新执行最后一条指令,而不必重新安装操作系统和软件包。
FROM node:18-alpine
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --production
VOLUME ["/app_todo-mysql-data", "/todo-db"]
COPY . .
CMD ["node", "src/index.js"]
像我这个Dockerfile, 我把不变的package.json yarn.lock放在前面,先将不容易改变的放在前面,后面就是容易改变的,比如复制的文件内容被修改,这层就会被重新构建。
合理利用缓存可以加快你的镜像构建哦!!