前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在docker环境导入私有仓库的问题

在docker环境导入私有仓库的问题

作者头像
LA0WAN9
发布2021-12-14 09:07:07
1.6K0
发布2021-12-14 09:07:07
举报
文章被收录于专栏:火丁笔记

最近我遇到了一个在 docker 环境导入私有仓库的问题:一个 Golang 项目,使用 gitlab ci 来发布,通过 gitlab runner 调用 docker-compose 来打包,但是在构建时失败了。

让我们重回案发现场,看看问题是怎么产生的:

首先是 .gitlab-ci.yml 文件,其相关代码片段内容如下:

代码语言:javascript
复制
build_job:
  stage: build
  script:
    - make docker-build

然后是 Makefile 文件,其相关代码片段内容如下:

代码语言:javascript
复制
.PHONY: docker-build
docker-build:
	@docker-compose build

接着是 docker-compose.yml 文件,其相关代码片段内容如下:

代码语言:javascript
复制
build:
  context: .
  dockerfile: Dockerfile

最后是 Dockfile 文件,其相关代码片段内容一下:

代码语言:javascript
复制
FROM golang:1.17 AS builder
WORKDIR /go/src/app
COPY . .
RUN go build

结果在 build 的时候报错了:

fatal: could not read Username for ‘https://git.domain.com’: terminal prompts disabled

因为 git.domain.com 是一个私有仓库,所以问题乍一看上去会以为是 GOPRIVATE 和 GOPROXY 的配置有问题,不过我的配置都是 OK 的:

代码语言:javascript
复制
shell> go env -w GOPRIVATE=git.domain.com
shell> go env -w GOPROXY=https://goproxy.cn,direct

实际上,根本原因是因为访问私有仓库的时候是需要用户名和密码的,但是在 docker 容器里获取不到用户名密码,所以就报错了。下面看看我是如何解决问题的:

第一次尝试

既然问题出在用户名密码上,那么把仓库改成公开的不就可以了么?可惜结果报错:

Visibility level public is not allowed in a private group.

我用的是 gitlab,它不允许在私有组里搞一个公开项目。

第二次尝试

既然搞不成公开项目,那么就想办法传递用户名密码吧,不过我们在使用 git 的时候,一般不会直接使用用户名密码,而是使用 KEY 来访问仓库,下面举例说明一下如何传递私钥参数 SSH_PRIVATE_KEY(其中牵扯到一个 docker 构建参数的概念):

首先因为此类信息比较敏感,所以应该避免硬编码,我们选择在 gitlab 里创建它:

Secret variables: settings > Pipelines
Secret variables: settings > Pipelines

Secret variables: settings > Pipelines

接着是 docker-compose.yml 文件,其相关代码片段内容如下:

代码语言:javascript
复制
build:
  context: .
  dockerfile: Dockerfile
  args:
    - SSH_PRIVATE_KEY

最后是 Dockfile 文件,其相关代码片段内容一下:

代码语言:javascript
复制
FROM golang:1.17 AS builder
ARG SSH_PRIVATE_KEY
WORKDIR /go/src/app
COPY . .
RUN umask 0077 \
    && mkdir -p ~/.ssh \
    && echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa \
    && ssh-keyscan git.domain.com >> ~/.ssh/known_hosts \
    && git config --global url."git@git.domain.com:".insteadOf https://git.domain.com/
RUN go build

此方法可以解决问题,但是把敏感信息传来传去总觉得不安心,容易出问题,资料:Access Private Repositories from Your Dockerfile Without Leaving Behind Your SSH Keys

第三次尝试

如果不想把敏感信息传来传去,那么还有没有安全的解决方案呢?答案是肯定的!我们只要在 gitlab runner 里执行「go mod vendor」就可以了,这是因为 gitlab runner 已经缓存了 git 认证信息,它可以访问所有的私有仓库,当执行「go mod vendor」后,项目依赖就都被放到 vendor 目录里了,接下来当执行到 Dockerfile 的 COPY 指令时,依赖就被自然而然的拷贝到了容器中,从而不用再联网执行 git 下载。

下面是修改后的 .gitlab-ci.yaml 文件,其相关代码片段内容如下:

代码语言:javascript
复制
build_job:
  stage: build
  script:
    - go mod vendor
    - make docker-build

也就是说,我们只加了一行代码「go mod vendor」,就解决了问题,是不是很简洁。最后友情提示一下:记得把 vendor 目录放到 .gitignore 里哦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一次尝试
  • 第二次尝试
  • 第三次尝试
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档