使用Docker部署Golang
交叉编译
首先,在项目的根目录( main.go
所在目录 )下执行以下命令进行交叉编译:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
若编译成功,根目录下将生成一个以项目名为文件名的二进制可执行文件。
编写Dockerfile
假设项目名称为service
:
# syntax=docker/dockerfile:1
FROM alpine
WORKDIR /app
COPY service /app
CMD ["./service"]
构建Docker镜像
docker build -t service:latest .
启动容器
docker run -d service:latest
Docker Hub
若需部署到远程服务器,则需通过Docker Hub
中转镜像。
因Docker Hub
定义了镜像的提交规范:
namespace/service:tag
相当于必须在镜像名称前带上自己的dockerID
,为了push
方便,可以在构建时直接指定:
docker build -t namespace/service:tag .
构建完成后推送至Docker Hub
:
docker push namespace/service:tag
远程服务器拉取镜像:
docker pull namespace/service:tag
bash
alpine
镜像的默认shell
为sh
,若要支持bash
,须在镜像构建时手动添加:
# syntax=docker/dockerfile:1
FROM alpine
WORKDIR /app
RUN apk update \
&& apk upgrade \
&& apk add --no-cache bash \
&& rm -rf /var/cache/apk/*
COPY service /app
CMD ["./service"]
时区
alpine
镜像的默认时区是UTC
,若要固定为CST
,须在镜像构建时手动添加:
# syntax=docker/dockerfile:1
FROM alpine
WORKDIR /app
RUN apk update \
&& apk upgrade \
&& apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo Asia/Shanghai > /etc/timezone \
&& apk del tzdata \
&& rm -rf /var/cache/apk/*
COPY service /app
CMD ["./service"]
自定义基础镜像
综上所述,当我们需要一个支持bash
且时区为CST
的镜像时,可以这样编写Dockerfile
:
# syntax=docker/dockerfile:1
FROM alpine
WORKDIR /app
RUN apk update \
&& apk upgrade \
&& apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo Asia/Shanghai > /etc/timezone \
&& apk del tzdata \
&& rm -rf /var/cache/apk/*
COPY service /app
CMD ["./service"]
上述写法已经满足需求,但apk
包的下载和安装需要时间,尤其是下面这两个阶段:
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz
大部分情况下这个时间都不会太短(至少需要几百秒,有些情况下甚至需要几十分钟)。
很显然,每次部署都要等待这个时间是不可接受的。
我们可以在alpine
的基础上,加入bash
和时区层,然后单独提交一个新镜像,后续业务再基于该新镜像进行构建。
如此一来,apk
的安装等待时间,只需忍受一次。
首先,编写基础镜像Dockerfile
:
# syntax=docker/dockerfile:1
FROM alpine
RUN apk update \
&& apk upgrade \
&& apk add --no-cache bash \
&& apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo Asia/Shanghai > /etc/timezone \
&& apk del tzdata \
&& rm -rf /var/cache/apk/*
其次,构建基础镜像:
docker build -t account/base:latest .
然后,推送至Docker Hub
:
docker push account/base:latest
最后,基于基础镜像构建业务镜像:
# syntax=docker/dockerfile:1
FROM account/base
WORKDIR /app
COPY service /app
CMD ["./service"]
Compile go packages and dependencies
Dockerfile
Docker Hub
推荐阅读
golang学习之旅——解开心中的go mod疑惑
在go1.16版本发布后,go module由原来的默认值 auto 变为 on 了,这意味着后续开发中,go更推荐用go module 模式开发,而不是gopath模式开发了。
Keson赞 11阅读 14.9k
又一款眼前一亮的Linux终端工具!
今天给大家介绍一款最近发现的功能十分强大,颜值非常高的一款终端工具。这个神器我是在其他公众号文章上看到的,但他们都没把它的强大之处介绍明白,所以我自己体验一波后,再向大家分享自己的体验。
良许赞 6阅读 1.9k
「刷起来」Go必看的进阶面试题详解
逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。
王中阳Go赞 4阅读 2k评论 1
初学后端,如何做好表结构设计?
这篇文章介绍了设计数据库表结构应该考虑的4个方面,还有优雅设计的6个原则,举了一个例子分享了我的设计思路,为了提高性能我们也要从多方面考虑缓存问题。
王中阳Go赞 4阅读 1.8k评论 2
一分钟搞明白!快速掌握 Go WebAssembly
最近因为各种奇怪的原因,更多的接触到了 WebAssembly。虽然之前很多博客也翻过写过各种文章,但总感觉欠些味道。于是今天梳理了一版,和大家一起展开学习。
煎鱼赞 4阅读 2.3k
突破难关:Docker镜像和容器的区别以及构建的最佳实践
Docker 可谓是开启了容器化技术的新时代,现在无论大中小公司基本上都对容器化技术有不同程度的尝试,或是已经进行了大量容器化的改造。伴随着 Kubernetes 和 Cloud Native 等技术和理念的普及,也大大增加了业务...
张晋涛赞 4阅读 1.2k
Aliyun-使用Docker方式安装Jenkins
之前自己在阿里云ECS上面安装了Jekins(安装jenkins的文章),最近因为服务器中了挖矿木马于是准备重新安装一下,但是想到每次安装jenkins都要手动安装jdk、maven、docker、kubectl,感觉好麻烦,于是使用官方推荐...
Awbeci赞 2阅读 2.1k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。