在build阶段主要是编译我们的应用程序,证书认证阶段将会安装我们所需要的CA证书,最后的生产发布阶段会将我们构建好的镜像推到镜像仓库中。而且发布阶段将会使用build阶段编译完毕的二进制文件和certs阶段安装的证书;
项目发布的多个build阶段
示例工程
main.go
[root@rabbitmq-2 gin_app]# cat /root/go/gin_app/main.go
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("http://www.likecs.com/", hello)
server := &http.Server{
Addr: ":8888",
}
fmt.Println("server startup...")
if err := server.ListenAndServe(); err != nil {
fmt.Printf("server startup failed, err:%v\n", err)
}
}
func hello(w http.ResponseWriter, _ *http.Request) {
w.Write([]byte("hello youmen.com!"))
}
编译阶段
Dockerfile
[root@rabbitmq-2 gin_app]# cat Dockerfile
FROM golang:alpine AS build
# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.io"
# 移动到工作目录:/build
WORKDIR $GOPATH/src/gin_docker
# 将代码复制到容器中
ADD . ./
# 将我们的代码编译成二进制可执行文件 app
RUN go build -o app
# 需要运行的命令
CMD ["./app"]
[root@rabbitmq-2 gin_app]# docker build -t gin_app -t gin_app . --target=build
[root@rabbitmq-2 gin_app]# docker images |grep gin_app
gin_app
latest
c35bb6310fce
10 minutes ago
321MB
[root@rabbitmq-2 gin_app]# docker run --rm -it -p 8888:8888 goweb_app
server startup...
[root@rabbitmq-2 ~]# curl localhost:8888
hello youmen.com!
生产阶段
[root@rabbitmq-2 gin_app]# cat Dockerfile
FROM golang:alpine AS build
# 为我们的镜像设置必要的环境变量
ENV GO111MODULE=on \
CGO_ENABLED=0 \
GOOS=linux \
GOARCH=amd64 \
GOPROXY="https://goproxy.io"
# 移动到工作目录:/build
WORKDIR $GOPATH/src/gin_docker
# 将代码复制到容器中
ADD . ./
# 将我们的代码编译成二进制可执行文件 app
RUN go build -ldflags "-s -w" -o app .
###################
# 接下来创建一个小镜像
###################
FROM scratch As prod
# 从builder镜像中把/go/src/gin_docker 拷贝到当前目录
# 设置应用程序以非 root 用户身份运
# User ID 65534 通常是 'nobody' 用户.
# 映像的执行者仍应在安装过程中指定一个用户。
COPY --chown=65534:0 --from=build /go/src/gin_docker .
USER 65534
# 需要运行的命令
CMD ["./app"]
[root@rabbitmq-2 gin_app]# docker build -t gin_app -t gin_app . --target=pro
[root@rabbitmq-2 gin_app]# docker images |grep gin_app
gin_app
latest
592cd0dca666
32 seconds ago
4.42MB