分阶段构建golang运行环境Dockerfile镜像

本文介绍了使用Docker空镜像scratch进行分阶段构建镜像。分阶段构建可节约服务器资源,如用golang:1.18-alpine普通镜像构建后约占300MB,分阶段构建可能只需20MB左右。文中演示了相关文件编写,构建出的镜像节省近30倍空间,且程序能正常运行,还提及了docker的“悬空镜像”。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在开始这项工作之前大家可以先去看一下docker官方给出关于空镜像scratch的说明,采用官方简单的一句话就是:scratch是一个明确的空图像,特别是对于“从头开始”构建图像。

分阶段构建镜像就会用到scratch这个空镜像,这样的好处是可以大大节约服务器资源,比如用普通的镜像(golang:1.18-alpine)来说,它在构建完之后大约占300MB左右,那么我们通过分阶段构建的话可能只需要20MB左右(与你的程序文件以及系统安装的文件内容有关,总之会比原镜像小很多),这里我在想scratch既然是个空镜像干净的环境那么它系统加载的内容也会非常少,在一定程度上是不是也存在提升了程序的性能,这里懂的原理的同学可以交流。

接下来是分阶段构建镜像所用到的Dockerfile和docker-compose.yml以及相关文件的演示:

Dockerfile:

FROM golang:1.18-alpine as builder

# 设置必要的环境变量
ENV GO111MODULE=on \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64 \
    GOPROXY=https://goproxy.cn,direct

RUN set -ex \
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    && apk --update add tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && apk --no-cache add ca-certificates

# 移动到工作目录:/build
WORKDIR /build

# 将代码复制到容器中
COPY . .

RUN go mod download && go mod tidy -v && go build -o execute .

# 运行阶段指定scratch作为基础镜像
FROM scratch

WORKDIR /app

# 拷贝二进制可执行文件
COPY --from=builder /build/execute buildExecute

# 下载时区包
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo

# 设置当前时区
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# https ssl证书
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# 需要运行的命令
ENTRYPOINT ["./buildExecute"]

docker-compose.yml

version: "3"

services:
  my-golang:
    build: .
    image: golang-1.18-scratch
    container_name: my-golang
    ports:
      - "8888:8888"
    restart: always

编写测试程序main.go

package main

import (
    "github.com/gin-gonic/gin"
)

func InitRoute() *gin.Engine {

    gin.DisableConsoleColor()
    gin.SetMode(gin.ReleaseMode)

    r := gin.Default()

    r.GET("/", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "hello go!",
        })
    })

    return r
}

func main()  {
    r := InitRoute()
    err := r.Run(":8888") //启动监听8888端口
    if err != nil {
        panic(any(err))
    }
}

当前目录结构及文件:

这两个文件都放在项目的根目录之后执行:

docker-compose up -d --build

这时候我们查看执行完毕后的docker容器和镜像信息:

可以看到原镜像golang:1.18-alpine需要328MB空间,而我们通过分阶段构建出来的镜像golang-1.18-scratch仅需要11.4MB,由于我们的测试go程序相对简单,所以占用的空间也是很少的,节省了近30倍的空间,很香吧!

接下来我们检测一下程序是否正常运行:

我们在宿主机curl容器映射出来的8888端口,这个时候收到正确的响应数据,说明我们构建完的镜像已经在正常运行了。

PS:在我们上面的查看执行完毕后的docker容器和镜像信息这一步执行:

为什么出现了这么多none的镜像呢?经过查阅相关资料得知这叫做docker的“悬空镜像”,至于为什么大家可以查询一下相关的资料或者阅读这篇文章《docker的虚悬镜像是什么?》。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值