关于 dockerfile 构建时访问 golang 私有库登录问题

关于 dockerfile 构建时访问 golang 私有库登录问题

在开发项目时使用 Gitlab 作为公司内网 golang 私有库,且所有仓库均为 private。打包项目为 docker 镜像时拉取依赖包问题

问题描述

公司有个项目 A 是由 golang 编写的,且 A 依赖的库 B、C、D 等也是商业代码的一部分,不可放在 github 等公共仓库中,这个问题在 Golang 使用 Gitlab 作为私有库 时已经解决了。

不过并没有解决干净,当时的做法仅适用于在开发环境中拉取依赖包(开发环境使用了 govendor 没发现镜像打包问题)或者在 jenkins 中通过 Makefile 或其他脚本先行编译代码,然后再把二进制文件通过 Dockerfile 写入镜像。如果是这么做,那之前写好的 Dockerfile 与 Makefile 只能重写了。

解决思路

由于项目打包平时是使用 Makefile 与 Dockerfile 联动,并且 Dockerfile 最开始就是使用多层构建的方式进行项目编译。那么只需要在编译的那层镜像进行修改即可,使编译的时候能够登录 gitlab 账号访问到私有的依赖库。

要想在 Dockerfile 中登录 gitlab 首先要确保登录是安全的,至少是在安全的地方登录的。

git 无密码登录无非就是两种,一种是通过 ssh key 登录,由于 go get 采用的 https 方式,懒得去使用 insteadOf 方式转换,且提供私钥还需要上传个文件到容器呢。另一种则是通过用户名密码的方式登录,但是这种登录方式需要先 clone 一次仓库输入用户名密码才能使用?有点坑。

通过查询官方文档 Git 工具 - 凭证存储 发现可以通过先把用户名密码写入 ~/.git-credentials 的方式来实现免密访问,不过有个问题就是该文件中存储的密码是明文的。莫急,喝杯水想了想编译代码是在 dockerfile 的中间层,实际发布是最后的基于 base 存放二进制文件的镜像,同时编译是通过 jenkins 实现的,只要这个账号只能访问 gitlab 中依赖库的 group,账号密码通过 --build-arg 传入也就相对安全了(gitlab 内网部署且只能内网访问,Jenkins 只有相关人员有权限登录及查看)。

实现

通过写入 git 服务器的用户名密码到 ~/.git-credentials 中,并使用 git config --global credential.helper store 指定当前环境中使用磁盘中存储的用户名密码访问即可。

Dockerfile 示例如下:

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
35
36
37
38
39
40
41
ARG GO_VER
ARG ALPINE_VER

FROM alpine:${ALPINE_VER} as base
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache tzdata dmidecode
RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf

FROM golang:${GO_VER}-alpine${ALPINE_VER} as golang
ARG GIT_USER
ARG GIT_PWD

ENV GO111MODULE=on \
GOPRIVATE=git.akiya.cc \
GOPROXY=http://proxy.akiya.cc/goproxy/

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add --no-cache \
gcc \
musl-dev \
git \
bash \
make \
&& echo "https://${GIT_USER}:${GIT_PWD}@git.akiya.cc" > ~/.git-credentials \
&& git config --global credential.helper store

ADD . $GOPATH/src/git.akiya.cc/foo/bar
WORKDIR $GOPATH/src/git.akiya.cc/foo/bar

FROM golang as orderer
ARG GO_TAGS
RUN make foobar GO_TAGS=${GO_TAGS}

FROM base
ENV TZ=Asia/Shanghai

COPY --from=foobar /go/src/git.akiya.cc/foo/bar/build/bin /usr/local/bin
COPY --from=foobar /go/src/git.akiya.cc/foo/bar/config/config.yaml /etc/foobar
EXPOSE 80

CMD ["foobar"]
评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...