常用指令
FROM
表示从哪个基础镜像开始构建
常用的镜像有:
- alpine
🔆 注意:这里有一个坑就是:alpine镜像内是不包含glibc的,从而导致go build完的可执行文件在容器里面无法执行。 此时的解决方法是需要设置 CGO_ENABLED=0,就像下面的一样。
ENV CGO_ENABLED=0 GO111MODULE=on GOPROXY="https://goproxy.cn,direct"
RUN go mod tidy && go build -o webservice
- ubuntu
🔆 注意:不同的ubuntu镜像版本所内置的glib版本是不一样的,所以需要注意跑在容器中的应用需要依赖的是什么版本的glibc。
# 查看glibc的版本
ldd --version
ENTRYPOINT 与 CMD
将两者配合使用,以达到这样的效果:容器已启动的时候,执行指定的内容,并且可以在外部指定传入这个可执行内容的参数
ENTRYPOINT
指定可执行的内容,比如可执行文件
CMD
指定可执行文件的默认参数,在容器启动的时候(docker run)的时候,可以通过指定参数来替代默认参数
例子
FROM ubuntu:20.04
WORKDIR /app
COPY bin/webservice .
ENTRYPOINT [ "/app/webservice"]
CMD [ "-host", "0.0.0.0", "-port", "8080", "-thost", "thirdparty", "-tport", "9527"]
WORKDIR
指定容器启动后的工作目录,也就是默认所在的路径
ADD
同样是拷贝内容入镜像中,但是这个ADD支持解压
COPY
COPY src dst
COPY —from=xxx src dst
分段构建
概念:在Dockerfile里面存在多个FROM
在前面的FROM先构建,构建出来的内容(比如可执行文件等)可以被后面的FROM使用。
有什么作用?此处使用一个例子来说明。
FROM golang:1.20 AS go-build-dev
WORKDIR /app
COPY main.go main.go
COPY go.mod go.mod
COPY go.sum go.sum
ENV CGO_ENABLED=0 GO111MODULE=on GOPROXY="https://goproxy.cn,direct"
RUN go mod tidy && go build -o webservice
FROM alpine:latest
WORKDIR /app
COPY --from=go-build-dev /app/webservice /app/webservice
ENTRYPOINT [ "./webservice"]
CMD [ "-host", "0.0.0.0", "-port", "8080", "-thost", "thirdparty", "-tport", "9527"]
- 从上面的例子可以看出,第一段从golang的基础镜像构建出了可执行文件webservice
- 但是这个golang基础镜像的大小接近1GB的大小!!!
- 但是我们使用golang这个基础进行只是为了进行可执行文件的创建,真正运行可执行程序的时候并不需要这么大的一个镜像;
- 所有在第二段构建中,使用的十分轻量级的alpine作为基础镜像(大小只有几十MB),
- 我们要做只需要将上一阶段构建的结果
COPY到当前构建过程,并且做成新的镜像 - 这样最后得到的镜像大小只有几十MB,大大减小了镜像的大小
因此,总结来说,分段构建允许我们使用前面构建生成的结果,并且抛弃掉繁重的构建环境,最后仅将可执行文件等必要运行时资源打包进镜像内,从而减小镜像的大小。