alpine镜像为基础将go应用部署在docker中
当用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等自动化部署工具上。