Dockerfile详解

回首往事、写给曾经的自己

  docker是一个好东西、但是官方文档的组织方式不太合理,它在介绍完成docker的基本概念之后,直接就操了一段dockerfile。在我当时还

  是一个初学者的时候,dockerfile成为了学习路上最大的障碍。

 

  现想回想起来一个主要的问题是,dockerfile太突然了! 没有“起承转合”上来就直接“刚”。好在我比较的“坚韧不拔,不抛弃不放弃”最终

  还是get到了dockerfile的哲学

 

从虚拟机到docker

  在实现的软件开发上线过程中,常常会遇到这样的事,测试同学在开发环境上测试的的时候,软件的功能是正常的;但是它在测试环境上对软件

  的功能进行测试的时候发现软件直接报错了,或是功能不对,最后以整个公司之力去排查问题,结果发现只是用了一个比较老的jar包;两样的问题

  可能在生产环境上还要再发生一次。次数多了之后开发同学开始变得不自信了,你问他这个版本的程序在客户的主机上能正常运行吗?他会说不太

  确定,这个要看情况 。

 

  我见过的比较大胆的做法,软件公司把自己的软件安装在虚拟机上,在测试通过后,他们发布的不是软件,而是是整个虚拟机。VMware真是的爱死

  他们了。用户那里只要安装有对应版本的VMware就行了,他们通过发布VMware镜像的方式发行自己的软件,虽然看上去有点豆,

  不可否认是解决了他们的问题。

 

  上面的做法太笨重了,每次发布一个windows-server-2008 + .net framework + 软件 好几十个G呀!然而这几十个G中大多数的内容对于目标

  软件来说是无用的

 

  docker 做了什么呢?事实上docker的做法和上面的发布vmware的镜像的做法差不多,只不过docker的做法减少了大量的无用内容的发布,这

  这docker发布的镜像在体积上就要小上不少。

 

  

  

 

  docker一直在强调它能做到“开发环境”与“生产环境”的完全一致,

 

 

 

 

---

转载于:https://www.cnblogs.com/JiangLe/p/9195668.html

Dockerfile 是用于构建 Docker 镜像的文本文件,其中包含了按顺序执行的一系列指令。每个指令都会在镜像中创建一个新的层,这使得 Docker 镜像具有分层的结构,可以高效地利用存储空间并加快构建速度[^1]。 ### Dockerfile 的基本结构 Dockerfile 通常由以下几个部分组成: - **基础镜像信息**:使用 `FROM` 指令指定。 - **维护者信息**:可选,使用 `LABEL` 或 `MAINTAINER` 指令指定。 - **镜像操作指令**:如 `RUN`、`COPY`、`ADD` 等,用于对镜像进行操作。 - **容器启动命令**:如 `CMD`、`ENTRYPOINT`,用于指定容器启动时运行的命令。 - **其他配置指令**:如 `WORKDIR`、`ENV`、`EXPOSE`、`VOLUME` 等,用于设置容器的工作环境。 ### Dockerfile 指令详解 #### `FROM` `FROM` 指令用于指定基础镜像,这是 Dockerfile 的第一条指令,并且每个 Dockerfile 至少要有一个 `FROM` 指令。可以指定标签来选择特定版本的基础镜像,也可以使用 `AS` 关键字为构建阶段命名,常用于多阶段构建[^3]。 ```dockerfile FROM ubuntu:20.04 ``` #### `ARG` `ARG` 指令用于定义构建时的变量,可以在构建镜像时通过 `--build-arg` 参数传递值。这些变量可以在 Dockerfile 中被 `RUN` 指令等引用[^2]。 ```dockerfile ARG VERSION=1.0 RUN echo "Version: $VERSION" ``` #### `ENV` `ENV` 指令用于设置环境变量,这些变量在构建过程中以及容器运行时都可用。环境变量可以通过 `$VAR` 的形式在 Dockerfile 中引用。 ```dockerfile ENV MY_PATH /usr/local/myapp WORKDIR $MY_PATH ``` #### `COPY` `COPY` 指令用于将本地文件系统中的文件或目录复制到镜像中的指定路径。支持从构建阶段复制文件(多阶段构建)[^3]。 ```dockerfile COPY . /app ``` #### `WORKDIR` `WORKDIR` 指令用于设置工作目录。后续的 `RUN`、`CMD`、`ENTRYPOINT` 等指令都会在这个目录下执行。如果目录不存在,会被自动创建[^4]。 ```dockerfile WORKDIR /app ``` #### `RUN` `RUN` 指令用于在镜像构建过程中执行命令。这些命令通常用于安装软件包或编译代码[^1]。 ```dockerfile RUN apt-get update && apt-get install -y nginx ``` #### `CMD` `CMD` 指令用于指定容器启动时默认执行的命令。如果有多个 `CMD` 指令,只有最后一个会生效。`CMD` 提供的默认参数可以在运行容器时被覆盖。 ```dockerfile CMD ["nginx", "-g", "daemon off;"] ``` #### `ENTRYPOINT` `ENTRYPOINT` 指令用于配置容器启动时运行的可执行文件。与 `CMD` 不同的是,`ENTRYPOINT` 的参数不会被覆盖,而是将 `CMD` 或运行时提供的参数作为其参数。 ```dockerfile ENTRYPOINT ["nginx", "-g"] CMD ["daemon off;"] ``` #### `LABEL` `LABEL` 指令用于为镜像添加元数据,如版本号、描述等信息。这些标签可以通过 `docker inspect` 命令查看[^2]。 ```dockerfile LABEL version="1.0" LABEL description="This is a sample Dockerfile" ``` #### `EXPOSE` `EXPOSE` 指令用于声明容器运行时监听的端口。虽然它不会自动映射端口,但可以作为文档说明,帮助用户了解容器需要暴露哪些端口[^1]。 ```dockerfile EXPOSE 80 ``` #### `VOLUME` `VOLUME` 指令用于创建挂载点,使数据可以在容器之间共享或持久化。即使容器停止或删除,卷中的数据仍然存在[^4]。 ```dockerfile VOLUME ["/data"] ``` #### `USER` `USER` 指令用于指定运行容器时使用的用户。这有助于提高安全性,避免以 root 用户身份运行容器。 ```dockerfile USER myuser ``` #### `ONBUILD` `ONBUILD` 指令用于设置一个触发器,当该镜像被其他镜像作为基础镜像时,这些触发器会在子镜像构建时自动执行。这对于构建依赖于父镜像的子镜像非常有用。 ```dockerfile ONBUILD COPY . /app ONBUILD RUN make /app ``` ### 多阶段构建 多阶段构建允许在一个 Dockerfile 中使用多个 `FROM` 指令,每个 `FROM` 指令定义一个独立的构建阶段。通过这种方式,可以在一个阶段中编译代码,在另一个阶段中仅包含运行所需的文件,从而减少最终镜像的大小。 ```dockerfile # 第一阶段:构建阶段 FROM golang:1.18 AS builder WORKDIR /app COPY . . RUN go build -o myapp # 第二阶段:运行阶段 FROM alpine:latest WORKDIR /app COPY --from=builder /app/myapp . CMD ["./myapp"] ``` ### 最佳实践 - **最小化镜像大小**:尽量使用轻量级的基础镜像(如 Alpine Linux),并清理不必要的文件和缓存。 - **合理使用缓存**:Docker 在构建镜像时会利用缓存来加速构建过程。为了充分利用缓存,应将不经常变化的指令放在前面。 - **安全性和权限管理**:避免以 root 用户身份运行容器,使用 `USER` 指令指定非特权用户。 - **多阶段构建**:利用多阶段构建减少最终镜像的体积,只保留必要的文件和依赖项。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值