alpine镜像为基础将go应用部署在docker中

作者: adm 分类: docker,go 发布时间: 2022-06-22

当用docker进行部署go应用时,我们可以选择docker中的golang镜像。

但为了更快的启动速度和更小的磁盘占用,我们推荐以alpine镜像作为基础镜像。
Alpine 操作系统采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。

Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB)

有人可能会有疑问:为什么可以采用alpine镜像呢?alpine镜像不是没有go环境吗?

你的疑问是对的。alpine的确没有go环境。但是我们可以在编译机器中预先将代码编译成一个二进制文件,然后将该二进制文件在ADD到新的镜像中。该二进制文件的执行不依赖于go环境了,所以我们可以直接将它在alpine环境中跑起来。

但是编译成alpine版本的过程与其他linux如centos,过程稍有不同。
centos中编译:

go build main.go

但是编译成alpine版本则需要加

CGO_ENABLED=0 go build main.go
CGO_ENABLED

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main  //或者

默认情况下,Go的runtime环境变量CGO_ENABLED=1,即默认开始cgo,允许你在Go代码中调用C代码。通过设置CGO_ENABLED=0就禁用CGO了。
Dockerfile文件内容

FROM docker.io/alpine
RUN mkdir /app
WORKDIR /app
COPY ./app* .
#RUN mkdir -p ./config
#COPY ./app/config/settings.dev.yml ./config/settings.dev.yml
#RUN mkdir -p /temp/logs
# Install base packages
 RUN apk update && apk add curl bash tree tzdata 
     && cp -r -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 
     && echo -ne "Alpine Linux 3.4 image. (`uname -rsv`)
" >> /root/.built
EXPOSE 8081
CMD /app/main
 

通过dockerfile编译go的代码成的镜像仅有12.3M,当然这也取决于你的代码包大小.
制作镜像代码。

docker build -f Dockerfile -t mygo .

-f指定Dockerfile文件。最后面的.指定当前制作镜像的上下文。这个上下文和Dockerfile的COPY ./app* . 中第一个路径有关系。如果上下文不对的话,那么COPY 时会找不到对应的路径而制作镜像失败。这里很关键。最好是将上下文和Dockerfile文件在同一目录。我这里为了学习上下文故意设置成不一样而已。

启动容器

docker run -d --name bt -p 9004:9000 mygo 
docker run -d --name bt --network=host -p 9004:9000 mygo  //如在vm内无法上网

进入容器
镜像是使用alpine制作的,要进入该容器需要输入

docker exec -it bt /bin/sh 
//其他操作系统
docker exec -it bt /bin/bash

查看日志

docker logs bt 

关于服务的热更新

在更新了代码并重新编译之后,现在需要发布到线上,可以这样操作:
1、将编译好的可执行文件传到服务器。
2、使用 命令将可执行文件传入容器。

docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径
docker cp ./app/main bt:/app

3、执行服务重启命令

 docker restart bt

4、可以将以上步骤集成到jenkins等自动化部署工具上。

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!