环境

使用语言

  • 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)
}

Hello World

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

这种方式方便快捷,开发、调试阶段使用特别方便。

证书问题

现在,在代码中增加一行简单的 Http 请求:

Http 请求

再次打包、运行镜像:

证书错误

scratch
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"]

至此,完毕。