如何搭建一个小体积的docker镜像?
1 任务说明
当前有一个golang的web项目,入口文件是main.go(Dockerfile放入同级目录下),我想通过Dockerfile生成一个镜像,通过镜像创建容器,部署项目。
但是单阶段生成的镜像文件为700MB,不适合传输,因此想通过两阶段生成镜像,减少镜像体积,这样产生的镜像为10MB左右。
2 Dockerfile
FROM golang:alpine
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.cn,direct"
WORKDIR /app
COPY . /app
ADD go.mod .
ADD go.sum .
RUN go mod download
RUN go build main.go
FROM scratch
WORKDIR /myapp
COPY --from=0 /app/main ./
RUN mkdir "log"
EXPOSE 9000
ENTRYPOINT ["./main"]
3 命令解释说明
首先引入基础镜像,镜像是分层的
FROM golang:alpine
接着设置golang的环境变量
ENV GO111MODULE=on \ // 启用go module模式
CGO_ENABLED=0 \ //设置linux平台的编译
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.cn,direct" // 设置golang第三方包的下载代理
设置工作目录,进入容器就会默认进入该目录下
WORKDIR /app
复制文件到工作目录下
COPY . /app // 将项目文件完整复制到app目录下
ADD go.mod . // 将依赖包添加进app
ADD go.sum .
RUN go mod download // 下载依赖包
编译项目,产生可执行的二进制文件
RUN go build main.go
然后是二阶段编译,引入一个空白镜像,将上一阶段编译好的可执行二进制文件放到里面
FROM scratch // 引入空白镜像
WORKDIR /myapp // 设置工作目录
COPY --from=0 /app/main ./ // 将可直接执行的二进制复制到当前工作目录下
启用9000端口,并设置入口执行文件(上一步生成的二进制文件)
EXPOSE 9000
ENTRYPOINT ["./main"]
4 生成镜像,启动容器
生成镜像
docker build -t <要生成镜像的名称>
例如:
docker build -t myapp
启动一个容器
docker run -p 9000:9000 <上一步生成镜像的名字>
例如:
docker run -p 9000:9000 myapp