整理一下docker的基础命令,以及多阶段编译的简单应用。

基础命令

  • FROM

拉取一个基准环境镜像

  • RUN

运行指令

  • COPY

将宿主机的目录复制到镜像中,注意目录路径

  • WORKDIR

改变在容器的当前目录

  • EXPOSE

表示容器会暴露此端口,但不是真正的在运行时暴露这个端口,只是一个类似于文档的作用,真正的暴露还是在docker -p 8000:8000,这样做一个端口的映射

  • ENTRYPOINT

类似的是CMD命令,ENTRYPOINT 是容器启动时执行的不变的命令,CMD是可以被用户修改的参数。

ENTRYPOINT [ “echo”, “a” ]

CMD [ “b” ]

执行结果: a, b

Docker run -p 8000:8000 imageName c d e

执行结果:a c d e ( ENTRYPOINT 正常情况下不会被覆盖,CMD是提供个默认值,可被重写 )

构建

目录:

1
2
3
4
5
6
7
8
/learn-docker
├── Dockerfile
├── go.mod
├── go.sum
└── hello
└── main.go

1 directory, 4 files

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"github.com/gin-gonic/gin"
"net/http"
)

func main() {
r := gin.Default()

r.GET("/hello", func(c *gin.Context) {
c.String(http.StatusOK, "hello world!!!")
})

_ = r.Run(":8080")
}

Dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 启动编译环境
FROM golang:1.17-alpine AS builder

# 配置编译环境
RUN go env -w GO111MODULE=on
RUN go env -w GOPROXY=https://goproxy.cn,direct

# 拷贝源代码到镜像中
COPY . /go/src/learn-docker

# 编译
# 进入代码目录
WORKDIR /go/src/learn-docker
# 微服务中,编译指定的项目即可,不建议编译整个大型项目,浪费时间,同时也容易构建失败
RUN go install ./hello/...

FROM alpine:3.15
COPY --from=builder /go/bin/hello /bin/hello

# 申明暴露的端口
EXPOSE 8080

# 设置服务入口
ENTRYPOINT [ "/bin/hello" ]

命令执行的顺序会影响构建速度,不变的命令应在之前运行,变化的放在后面,不变的会尽量用到cache。

构建:

1
2
3
4
$ docker build -t hello -f Dockerfile .
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello latest 530fe26c543a 31 minutes ago 14.7MB