【go语言开发】go项目打包成Docker镜像,包括Dockerfile命令介绍、goctl工具生成
作者:mmseoamin日期:2024-02-20

本文主要介绍如何将go项目打包成镜像,首先介绍Dockerfile常用命令介绍,然后介绍使用工具goctl用于生成Dockerfile,还可以根据需求自定义指令内容,最后讲解如何将go-blog项目打包成镜像,以及如何运行等

文章目录

  • 前言
  • Dockerfile介绍
  • goctl工具生成Dockerfile
    • 安装工具
    • 命令行输入
    • Dockerfile
    • 构造镜像
      • 查看镜像:
      • 启动镜像:

        前言

        参考文档:

        • docker日常使用,编写dockerfile等
        • dockerfile编写

          开发完项目之后,可以通过dockerfile将项目打包成镜像

          Dockerfile介绍

          Dockerfile 是用于构建 Docker 镜像的文本文件,其中包含一系列指令(命令)。这些指令按照顺序执行,用于定义镜像的构建过程。下面是常用的 Dockerfile 命令及其详细解释:

          • FROM:指定基础镜像,用于构建当前镜像的基础。例如:FROM ubuntu:latest。
          • LABEL:为镜像添加元数据,可以包含任意键值对。例如:LABEL maintainer="yourname@example.com"。
          • RUN:在镜像中执行命令,并创建新的镜像层。例如:RUN apt-get update && apt-get install -y curl。
          • CMD:指定容器启动时要执行的命令,该命令只能有一个。例如:CMD ["nginx", "-g", "daemon off;"]。
          • EXPOSE:声明容器运行时监听的端口。例如:EXPOSE 8080。
          • ENV:设置环境变量。例如:ENV MYSQL_VERSION 5.7。
          • ADD:将文件、目录或远程 URL 的内容复制到镜像中。例如:ADD app.jar /app/。
          • COPY:将文件或目录复制到镜像中。例如:COPY ./src /app/src。
          • WORKDIR:设置工作目录,后续命令将在该目录下执行。例如:WORKDIR /app。
          • VOLUME:声明持久化目录,用于在容器和主机之间共享数据。例如:VOLUME /data
          • ENTRYPOINT:指定容器启动时要执行的命令,与 CMD 不同的是,ENTRYPOINT 不会被Dockerfile 中的指令覆盖。例如:ENTRYPOINT ["java", "-jar", "app.jar"]。
          • USER:设置运行后续命令的用户名或 UID。例如:USER myuser。
          • ARG:定义构建参数,可以在构建镜像时通过 --build-arg 传递。例如:ARG VERSION=latest。
          • ONBUILD:指定触发器命令,在当前镜像被继承时执行。例如:ONBUILD ADD . /app。

            下面是一个简单的示例,演示了如何编写一个用于构建基本 Go 应用程序的 Dockerfile。

            # 使用官方的 Golang 镜像作为基础镜像
            FROM golang:1.16
            # 在容器内创建一个目录来存放我们的应用代码
            RUN mkdir /app
            # 将工作目录切换到 /app
            WORKDIR /app
            # 将当前目录下的所有文件拷贝到 /app 目录
            COPY . .
            # 编译 Go 应用程序
            RUN go build -o myapp .
            # 暴露 8080 端口
            EXPOSE 8080
            # 运行应用程序
            CMD ["./myapp"]
            

            当然还有更简便的方式,使用goctl工具生成Dockerfile,解放了生成力~

            goctl工具生成Dockerfile

            安装工具

             go install github.com/zeromicro/go-zero/tools/goctl@latest
            

            命令行输入

            (base) yangmiao@ym-mac gin-blog % goctl docker --help
            Generate Dockerfile
            Usage:
              goctl docker [flags]
            Flags:
                  --base string      The base image to build the docker image, default scratch (default "scratch")
                  --branch string    The branch of the remote repo, it does work with --remote
                  --exe string       The executable name in the built image
                  --go string        The file that contains main function
              -h, --help             help for docker
                  --home string      The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
                  --port int         The port to expose, default none
                  --remote string    The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
                                     The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
                  --tz string        The timezone of the container (default "Asia/Shanghai")
                  --version string   The goctl builder golang image version
            

            在执行该命令后,Goctl 会自动生成一个名为 Dockerfile 的文件,包含适当的环境配置和基础镜像信息。

            goctl docker --go main.go 
            

            生成的Dockerfile文件如下所示

            Dockerfile

            多阶段构建

            • 第一个 FROM 开始的部分是构建一个 builder 镜像,目的是在其中编译出可执行文件 main
            • 第二个 From 开始的部分是从第一个镜像里 copy 出来可执行文件 main,并且用了基础镜像 scratch ,以保障最终镜像尽可能小
              FROM golang:alpine AS builder
              LABEL stage=gobuilder
              ENV CGO_ENABLED 0
              ENV GOPROXY https://goproxy.cn,direct
              RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
              RUN apk update --no-cache && apk add --no-cache tzdata
              WORKDIR /build
              ADD go.mod .
              ADD go.sum .
              RUN go mod download
              COPY . .
              RUN go build -ldflags="-s -w" -o /app/main main.go
              FROM scratch
              COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
              COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
              ENV TZ Asia/Shanghai
              WORKDIR /app
              COPY --from=builder /app/main /app/main
              CMD ["./main"]
              
              • 默认禁用了 cgo
              • 启用了 GOPROXY 加速 go mod download
              • 去掉了调试信息 -ldflags=“-s -w” 以减小镜像尺寸
              • 安装了 ca-certificates,这样使用 TLS证书就没问题了
              • tzdata 在 builder 镜像安装,并在最终镜像只拷贝了需要的时区
              • 自动设置了本地时区

                构造镜像

                至于docker如何使用,可以参考Docker-常用命令介绍,看这一篇就够了

                在项目根目录下,执行docker build,用于生成镜像,生成镜像后就可以查看和启动了~

                docker build -t go-blog:v1 .
                
                (base) yangmiao@ym-mac gin-blog % docker build -t go-blog:v1 .
                ERROR: Cannot connect to the Docker daemon at tcp://localhost:2375. Is the docker daemon running?
                (base) yangmiao@ym-mac gin-blog % sudo docker build -t go-blog:v1 .
                Password:
                [+] Building 515.7s (18/18) FINISHED       
                 => [internal] load build definition from Dockerfile                                 0.1s
                 => => transferring dockerfile: 694B  0.0s
                 => [internal] load .dockerignore     0.1s
                 => => transferring context: 2B       0.0s
                 => [internal] load metadata for docker.io/library/golang:alpine                   308.4s
                 => [internal] load build context    10.3s
                 => => transferring context: 215.37MB10.1s
                 => [builder 1/9] FROM docker.io/library/golang:alpine@sha256:70afe55365a265f0762257550bc38440e0d6d6b97020d3f8c85328f00200dd8e    156.9s
                 => => resolve docker.io/library/golang:alpine@sha256:70afe55365a265f0762257550bc38440e0d6d6b97020d3f8c85328f00200dd8e              0.0s
                 => => sha256:86a63ed24dc22a348b35d99b5ec9dc67ff66563b539875e5c8ab2d870b3991ac 286.31kB / 286.31kB                                 75.8s
                 => => sha256:ae48e6158ebb1a353f7d7b0676b0bd55a09a448a440b65135db378ffb0040919 64.09MB / 64.09MB                                  153.7s
                 => => sha256:70afe55365a265f0762257550bc38440e0d6d6b97020d3f8c85328f00200dd8e 1.65kB / 1.65kB                                      0.0s
                 => => sha256:635bf83d6a1993bf40e3c575d7b522d41950af4f1a5c1c7cd01c81d93b76f4bf 1.16kB / 1.16kB                                      0.0s
                 => => sha256:1ddcbcaf7f02eab589ea6e5727ede30fe040922e4674737894898cddeaba40e0 6.34kB / 6.34kB                                      0.0s
                 => => sha256:2c03dbb20264f09924f9eab176da44e5421e74a78b09531d3c63448a7baa7c59 3.33MB / 3.33MB                                     76.8s
                 => => sha256:edabe92b0de78c4b662f63a4b2884d0821795e38a90c7ec070ccfa98f8aa236c 156B / 156B                                        151.3s
                 => => extracting sha256:2c03dbb20264f09924f9eab176da44e5421e74a78b09531d3c63448a7baa7c59                                           0.8s
                 => => extracting sha256:86a63ed24dc22a348b35d99b5ec9dc67ff66563b539875e5c8ab2d870b3991ac                                           0.1s
                 => => extracting sha256:ae48e6158ebb1a353f7d7b0676b0bd55a09a448a440b65135db378ffb0040919                                           2.6s
                 => => extracting sha256:edabe92b0de78c4b662f63a4b2884d0821795e38a90c7ec070ccfa98f8aa236c                                           0.0s
                 => [builder 2/9] RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories                                  1.0s
                 => [builder 3/9] RUN apk update --no-cache && apk add --no-cache tzdata             2.7s
                 => [builder 4/9] WORKDIR /build      0.0s
                 => [builder 5/9] ADD go.mod .        0.0s
                 => [builder 6/9] ADD go.sum .        0.0s
                 => [builder 7/9] RUN go mod download14.2s
                 => [builder 8/9] COPY . .            7.4s
                 => [builder 9/9] RUN go build -ldflags="-s -w" -o /app/main main.go                24.5s
                 => [stage-1 1/4] COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt                         0.0s
                 => [stage-1 2/4] COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai                           0.0s
                 => [stage-1 3/4] WORKDIR /app        0.0s
                 => [stage-1 4/4] COPY --from=builder /app/main /app/main                            0.1s
                 => exporting to image                0.1s
                 => => exporting layers               0.1s
                 => => writing image sha256:556e5362b86a63c8d1325549b595d987c8c79ad749524875c9d018c44cbf3ad5                                        0.0s
                 => => naming to docker.io/library/go-blog:v1                                        0.0s
                

                查看镜像:

                sudo docker images | grep go-blog
                

                【go语言开发】go项目打包成Docker镜像,包括Dockerfile命令介绍、goctl工具生成,在这里插入图片描述,第1张

                启动镜像:

                 sudo docker run -it go-blog:v1