记录一下使用Docker进行两阶段编译打包的过程。
最近使用Golang写了一个Web应用,在部署时想通过Docker进行部署,虽然之前也做过,但没有记录下来,导致还要重新摸一遍。因此,这次就记录一下。
整体需求
需要打包的Web应用使用Golang编写,其中用到了sqlite,即需要使用cgo。目前还没有交叉编译需求,只要求能够在linux服务端跑起来。
实现方式
为了减少镜像大小,选用了alpine作为基础镜像。最终的Dockerfile如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
# 升级到1.23.1,测试无问题
FROM golang:1.23.1-alpine3.19 AS builder
WORKDIR /build
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories
# 安装编译工具,build-base中包括了gcc、glibc等工具
RUN apk add --no-cache build-base upx
RUN go env -w GOPROXY="https://goproxy.cn,direct"
ENV CGO_ENABLED 1
COPY . .
RUN go build -ldflags="-s -w"
RUN upx ./obsidian-web
FROM alpine:3.19
# 解决时区问题
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \
&& apk update && apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Shanghai/Asia" > /etc/timezone \
&& apk del tzdata
# 需要git下载笔记仓库
RUN apk add --no-cache git ca-certificates openssh
WORKDIR /app
COPY --from=builder /build/obsidian-web /app/obsidian-web
ENV GIN_MODE release
ENTRYPOINT ["./obsidian-web"]
|
这里面有几个坑:
- 就目前来说(2024年4月28日),需要使用alpine3.18版本,否则编译sqlite时会报错。
- 安装编译工具时,直接安装build-base,之前想单独安装gcc、musl-dev,但没有成功。
下面就是构建镜像
1
|
sudo docker build -t obsidian-web:1.0.0 .
|
如果需要在本地构建镜像后部署到远程服务器上,就需要使用镜像的导出和导入功能
1
2
3
4
5
|
# 导出镜像
sudo docker save obsidian-web:1.0.1 | gzip > ../obsidian-web-1.0.1.tar.gz
# 导入镜像
sudo docker load < obsidian-web-1.0.1.tar.gz
|
参考:
https://www.cnblogs.com/kevinwan/p/16033634.html