环境
使用语言
- Go
使用镜像
- golang
- alpine
- scratch
Go 程序
一个简单的服务
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello world")
}
func main() {
http.HandleFunc("/", indexHandler)
http.ListenAndServe(":9090", nil)
}
Dockerfile
FROM golang as golang
# 配置模块代理
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct
ADD . /www
# 进入工作目录
WORKDIR /www
# 打包 AMD64 架构
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o go_server
FROM scratch
# 暴露服务端口
EXPOSE 9090
WORKDIR /www
# 复制打包的 Go 文件到系统用户可执行程序目录下
COPY --from=golang /www/go_server /www
# 容器启动时运行的命令
ENTRYPOINT ["/www/go_server"]
Build And Run
这里构建运行有两种方式,手动构建运行和坚决 IDEA 自动化构建运行。看自己情况吧,平常开发、调试使用最多还是 IDEA 的工具。
手动构建运行
Build
Dockerfile 文件在项目根目录
到项目根目录下执行构建。
$ docker build -t go-server .
Sending build context to Docker daemon 319.5kB
Step 1/11 : FROM golang as golang
---> 7d1902a99d63
Step 2/11 : ENV GO111MODULE=on
---> Using cache
---> ed95a3bc3434
Step 3/11 : ENV GOPROXY=https://goproxy.cn,direct
---> Using cache
---> 66891aef30f7
Step 4/11 : ADD . /www
---> b49b62db2164
Step 5/11 : WORKDIR /www
---> Running in 33d9c9b15f7a
Removing intermediate container 33d9c9b15f7a
---> b006f3544e39
Step 6/11 : RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o go_server
---> Running in 0767b3a56024
Removing intermediate container 0767b3a56024
---> 84495494227a
Step 7/11 : FROM scratch
--->
Step 8/11 : EXPOSE 9090
---> Running in 902dd62ef52d
Removing intermediate container 902dd62ef52d
---> b6780ffe375d
Step 9/11 : WORKDIR /www
---> Running in d5450d2c0707
Removing intermediate container d5450d2c0707
---> d8fe6d34cdb5
Step 10/11 : COPY --from=golang /www/go_server /www
---> 4c18f839ac11
Step 11/11 : ENTRYPOINT ["/www/go_server"]
---> Running in e8ee9bd5dd93
Removing intermediate container e8ee9bd5dd93
---> 4a0482f236cb
Successfully built 4a0482f236cb
Successfully tagged go-server:latest
Run
运行镜像即可访问
$ docker run --rm -it -p 9090:9090 --name go-server go-server
IDEA 自动化构建工具
Docker 开启 2375 远程服务端口
注意,此端口是无密码验证端口,一般用在测试环境,如果是公网服务器或重要服务,切勿暴露端口。建议使用 安全的 2376 服务端口。
- 开启方法1
$ vim /usr/lib/systemd/system/docker.service
# 增加参数:-H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
# 重新加载 docker 守护线程
$ systemctl daemon-reload
# 重启docker
$ systemctl restart docker
- 开启方法2
$ vim /etc/docker/daemon.json
{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
# 重新加载 docker 守护线程
$ systemctl daemon-reload
# 重启docker
$ systemctl restart docker
IDEA 配置
File | Settings | Build, Execution, Deployment | Docker
添加 Docker 服务
编辑启动配置
点击 Run
之后会直接进行 Build 和 Run 两步。
这种方式方便快捷,开发、调试阶段使用特别方便。
证书问题
现在,在代码中增加一行简单的 Http 请求:
再次打包、运行镜像:
原因就是 scratch
中并没有需要的根证书,只需要添加进入即可。修改后的 Dockerfile:
FROM golang as golang
# 配置模块代理
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct
ADD . /www
# 进入工作目录
WORKDIR /www
# 打包 AMD64 架构
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags '-w -s' -o go_server
# 主要是为了下一步的 scratch 拉取 ca-certificates 根证书
FROM alpine:3.14 as alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk update && apk add ca-certificates
FROM scratch
# 配置项目环境(根据自己情况来)
ENV GO_PROFILE=pro
ENV GIN_MODE=release
# 暴露服务端口
EXPOSE 9090
WORKDIR /www
# 复制打包的 Go 文件到系统用户可执行程序目录下
COPY --from=golang /www/go_server /www
# 为所有标准证书颁发机构添加了根证书
COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# 复制程序配置文件(根据自己情况来)
ADD ./config/etc /www/config/etc
# 容器启动时运行的命令
ENTRYPOINT ["/www/go_server"]
至此,完毕。
文章评论