Dockerfile详解
Dockerfile详解
本文基于win10 docker 讲述Dockerfile的书写,并举例示范。
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
基本步骤
- 创建名为Dockerfile的文件
- 书写Dockerfile文件
- 构建镜像,如:
docker build -t nginx:v3 .
(.代表当前目录,nginx:v3是Dockerfile中定义的镜像标签) - 运行docker镜像:
docker run -d nginx:v3
命令介绍
FROM
引用最基础的镜像,即构建的基础镜像。
1 | FROM nginx:latest |
RUN
用于执行后面跟着的命令行命令。
1 | RUN <命令行命令> |
&& 可用于连接命令,如:wget http://redis.tar && tar -xzvf redis.tar
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
1 | COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"] |
ADD
ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY。
与COPY的区别是,若 <源文件> 为 tar 压缩文件的话,会自动复制并解压到 <目标路径>!!!
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
1 | CMD ["<可执行文件或命令>","<param1>","<param2>",...] |
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
此命令适合搭配CMD使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参。
如构建以下的镜像:
1 | FROM nginx |
不传参数,默认运行dockerfile中的CMD参数。
1
docker run nginx:test
docker run 传参数,覆盖运行run 的参数。
1
docker run nginx:test -c /etc/nginx/new.conf
以上两种方式最后运行的都是:nginx -c /etc/nginx/new.conf
,推荐使用数组的方式书写ENTRYPOINT。
ENV
设置环境变量。
1 | ENV <key> <value> |
VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
- 避免重要的数据,因容器重启而丢失,这是非常致命的。
- 避免容器不断变大。
1 | VOLUME ["<路径1>", "<路径2>"...] |
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点!!!
EXPOSE
声明端口,需要在运行时搭配 -p端口映射使用。
1 | EXPOSE <端口1> [<端口2>...] |
WORKDIR
指定工作目录(项目当前路径)。
1 | WORKDIR <工作目录路径> |
更多命令信息参考:https://docs.docker.com/engine/reference/builder/
案例示范
使用dockerfile部署一个简单的gin项目应用。
创建docker文件夹
书写gin程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080")
}生成go mod 依赖文件
1
go mod init docker
拉取go依赖包
1
go mod download
测试应用程序,访问
localhost:8080/ping
1
go run main.go
书写Dockerfile文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22From golang:latest
# 创建文件夹
RUN mkdir /app
# 当前工作目录
WORKDIR /app
# 将当前文件夹的所有文件复制到容器中
COPY . /app
# 设置go代理
ENV GO111MODULE=on GOPROXY=https://goproxy.io,direct
# 下载go的依赖
RUN go mod tidy
# 暴露端口
EXPOSE 8080
# 运行
CMD go run main.go构建镜像
1
docker build -t gin-app .
运行容器:
1
docker run -d -p 8080:8080 gin-app
正常运行。
参考: