Dockerfile 基础
docker镜像构建需要至少一条FROM指令,表明从什么基础开始打架镜像,空镜像FROM scratch
, scratch不是一个可拉取的镜像,相当于一个关键字。最小的linux运行系统可以FROM busybox
开始搭建。
多阶段构建:一个Dockerfile可以多个From, 最后一个From生效,前面的可以AS别名,多用于构建最终运行的bin文件,COPY可以从前面的From阶段中拷贝文件。
一个go 项目编译,最小发布示例,注意静态编译参数:
FROM golang:1.17-alpine AS build
# Install tools required
RUN apk add --no-cache git
# Copy the entire ParsecClient and build it
COPY . /go/src/ParsecClient/
WORKDIR /go/src/ParsecClient/
# use proxy to get thirdpart package in china
RUN GO111MODULE=on GOPROXY=https://goproxy.cn go get -u
# https://stackoverflow.com/questions/36279253/go-compiled-binary-wont-run-in-an-alpine-docker-container-on-ubuntu-host
# GOARCH=arm64
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /bin/ParsecClient
# This results in a single layer image
FROM scratch
COPY --from=build /bin/ParsecClient /bin/ParsecClient
COPY ./ParsecClient.toml /etc/ParsecClient.toml
CMD ["/bin/ParsecClient"]
COPY --from=build
这里的from参数就指定从前面的构建阶段中拷贝数据,这样一个docker build命令可以完成构建测试和镜像生成, 并且这个构建环境是跨平台的。
scratch环境只能运行无任何依赖的二进制,go天生有这方面的优势,如果是标准C编译的二进制,是有动态库依赖的,不能直接运行, 需要FROM ubuntu
才能运行。官方提供了C的依赖写法,参考:https://github.com/docker-library/hello-world