首页
Preview

如何使用 Docker 创建一个 Go 私有模块

Golang: 操作指南

Golang gopher展示如何保护连接,配置Docker,以及为私有Go模块构建应用程序Docker镜像

介绍

自从Go 1.11引入模块以来,Go应用程序的依赖管理得到了显著的改善。我们看到使用GOPROXY获取模块变得更加容易,认证请求得到更好的支持,依赖版本控制更加流畅等等。

但是如果你想创建自己的模块,你该从哪里开始呢?

好消息是,相对而言,公共包与私有包的创建并没有那么困难,但它们确实有一些不同之处。

👉 注意:在本文中,我会将Go package和Go module这两个术语互换使用。

尽管如此,处理私有Go模块分发的私有平台,例如bitbucket、Gitlab或Github,无论是创建个人项目还是保留专有逻辑“内部”,都是非常有价值的技能。因此,我想指导一些人如何操作。

作为额外的奖励,我还将向你展示如何使用Docker镜像开发Go应用程序,因此,振作起来,坐稳了,我们开始吧。

The GoDev Corner段落分隔符

简短的前言

本文结束后,你将能够:

[随意跳转到指定的部分]

先决条件

  • Go模块知识(注:如果你是Go模块的新手,我建议你从官方文档开始)
  • 已安装Go 1.16+
  • 熟悉Git

The GoDev Corner段落分隔符

开始

首先,我们将为Go私有模块创建一个GitHub私有仓库。

[如果只是简单地阅读本文,请随意跳到此部分]

下载示例项目代码库

没有必要从头开始编写示例Go模块。所以,请随意前往下面列出的GitHub仓库,并下载该项目的zip文件;是的,你没看错——无需克隆仓库,只需下载zip文件即可。

GitHub - marvinhosea/filter: Article Repo

单击仓库页面上的代码以查看类似于此的下拉列表。继续点击“下载zip”以下载代码库。

下载所需代码库的两个步骤

下载代码库的两个步骤

下载完成后,将zip文件解压缩到一个文件夹中。在提交代码库到私有GitHub仓库之前,我们必须进行一项更改。在你喜欢的IDE中打开提取的文件夹,并编辑go.mod文件,以匹配你的模块名称,将用户名替换为你的GitHub用户名,如下所示。

创建GitHub私有仓库

我们认为我们的私有Github仓库是一个私有的Go模块分发。因此,前往GitHub创建一个新的私有仓库,如下所示:

创建一个新的私有仓库

创建一个新的私有仓库

接下来,你将要将我们的Go模块文件添加到新创建的GitHub私有仓库中。

  • 在Go模块项目的根目录中,运行下面的命令以git初始化目录:
git init

👉 我们在git初始化项目之后添加文件;因为我们已经配置好了git ignore,所以在运行git add时不用担心任何问题。具体如下所示:

git add --all
  • 现在,如果你查看代码库,你会发现我们有一个简单的测试。在提交我们的代码之前,让我们运行它,以确保一切都正常运行:
go test -v -cover ./...
  • 如果成功完成,你应该看到类似于此的内容:

在你的Go私有模块中运行初始测试的代码

运行你的Go私有模块中的建议测试

  • 现在,该软件包已经正常运行,让我们添加git提交消息:

👉 随意创建你自己的]

git commit -m 'first commit'
  • 现在,让我们将远程源添加到项目中:
git remote add origin git@github.com:username/private-filter.git
  • 最后,运行下面的命令,将我们的项目推送到远程仓库:
git push -u origin main

如果你在GitHub上刷新项目仓库页面,你应该看到上面的命令已经成功地将代码库和文件从本地仓库传输到远程仓库。这就是我们所需要的全部内容。

The GoDev Corner段落分隔符# 如何使用 Go 私有模块

Go modules 允许开发者添加和管理依赖,但是私有 Go 模块的分发并不是开箱即用的,我们必须对 Go 和我们的设置进行一些额外的配置。

更改之后,获取 Go 模块依赖项将类似于使用 go get 命令获取公共 Go 模块。这将从 proxy.golang.org 的公共分发镜像下载 Go 模块。

Go 私有环境变量配置

因为我们使用的是 Go modules,请确保启用了 GO111MODULE;如果没有启用,请运行此命令:

export GO111MODULE=on

环境变量 GOPRIVATE 使我们能够分发 Go 私有模块,我们可以使用以下命令设置 GOPRIVATE 值:

go env -w GOPRIVATE=github.com/username/*

要设置 Go 环境变量,请使用 go env -w 命令。上述命令告诉 Go,模块分发源不是 Go 公共包分发。github.com/username/* 对应于你的组织或个人私有 Go 模块分发,也可以是 Gitlab、Bitbucket 或其他类似服务。

但是如果我们有多个私有模块怎么办呢?在这种情况下,我们可以使用逗号分隔模块的分发源,如下所示:

go env -w GOPRIVATE=github.com/username/*,github.com/otheruser/*

我们还可以直接在 bashrc 或 zshrc 文件中添加 GOPRIVATE 环境变量,但是我会让你自己进一步研究,或者只需运行以下说明即可添加 GOPRIVATE 环境变量。

echo "export GOPRIVATE=github.com/username/*" >> ~/.bashrc

设置 GOPRIVATE 不会干扰 Go 公共模块的分发。

要确认 GOPRIVATE 环境变量已设置,请运行此命令:

go env | grep GOPRIVATE

输出应该类似于下面的内容:

GOPRIVATE="github.com/username/*"

这就是我们在 Go 中使用 Go 私有模块所需的全部内容。让我们进行必要的配置,以允许 Go 工具从私有分发下载 Go 私有模块。

设置凭据和 Go 私有模块访问

在本节中,我们将了解如何在本地和 Docker 中使用 Go 私有模块。首先,让我们获取我们的 Go 私有模块:

  • 进入你的开发目录并创建一个简单的 Go 应用程序。在我的例子中,我将其称为 go-private-example
mkdir go-private-example && cd go-private-example
  • 现在,通过项目的根目录向我们的简单 Go 应用程序添加 go 模块:
go mod init go-private-example

这将生成一个 go.mod 文件,用于跟踪我们的依赖项。

  • 接下来,在根目录中创建一个 main.go 文件,并将下面的内容粘贴到其中:

  • 现在,我们有了 main 包和 main 函数,它们同时作为我们示例程序的入口点。打开终端并使用 go get 下载我们的私有 Go 模块:

go get github.com/username/private-module

如果你在终端中运行此命令,你将获得以下输出 [Go 1.19]:

Visual code depicting how to download the go private module using go get

使用 go get 下载私有 Go 模块

错误指示 Go 工具尝试访问 Go 私有模块,但由于访问被拒绝,无法下载。我们还没有设置身份验证凭据,接下来我们将看看下一步该怎么做:

The GoDev Corner paragraph separator

提供凭据

此时,有两种方法可供选择:使用 ssh 方法(更简单、更受欢迎)或使用 .netrc 方法。

我们将两种方法都介绍一下,以防你感兴趣,但我们将从使用 ssh 开始。

即使你配置了两种选项(即 ssh 和 .netrc),你仍然可以无问题地下载私有 Go 模块。

使用 ssh

Git 提供了一个全局配置文件,其中有一个名为 insteadOf 的选项,告诉 git 使用默认的 HTTPS URL 代替哪个 URL。例如,使用 “ssh://git@github.com/” 代替 “https://github.com/”。

当你配置了 ssh 并将其链接到你的私有 Go 模块分发时,你将拥有更安全的连接。

让我们将系统配置为使用 ssh 而不是 HTTPS:

  • 进入用户的主目录($HOME),打开 .gitconfig 文件,并在行末添加以下内容:
[url "git@github.com:"]
	insteadOf = https://github.com/

这告诉 git 使用 ssh URL 而不是 HTTPS URL。

这也适用于 Gitlab、Bitbucket 等。

使用 .netrc 文件

.netrc 文件位于用户的主目录中,用于存储登录所需的凭据,无需手动输入。更多信息可以在这里找到。此方法涉及可能在磁盘上留下未加密的凭据,请小心操作。首先,让我们进入主目录($HOME),并检查目录中是否有**.netrc**文件:

ls .netrc
  • 如果文件不存在,你将会收到下面的错误。否则请跳过这一部分,继续下面添加文件内容的部分。
No such file or directory
  • 如果文件不存在,运行以下命令创建文件:
touch .netrc
  • 如下所示,将其权限设置为600:
sudo chmod 600 .netrc
  • 现在打开文件,在末尾添加以下内容,然后关闭文件:
machine github.com login username password accesstoken

请用你的GitHub用户名替换上述行中的username,然后生成你的个人访问令牌,并将其替换为上述行中的accesstoken。你可以在这里创建新的访问令牌,为其分配相关的范围,然后复制它。

💡 创建令牌时一定要检查相关的范围。在考虑到令牌被泄露的安全问题时,要保持安全性。并且不要使用你的帐户密码。

Gitlab怎么办?

只需将github.com URL替换为gitlab.com或bitbucket.com URL或其他存储库服务。

现在,让我们尝试重复以下指令以再次获取我们的Go私有模块:

go get github.com/username/go-filter

输出结果将类似于以下内容:

Visual code explaining how to get the Go private module

再次获取我们的Go私有模块

正如你所看到的,我们的包已经被下载并添加到了我们的项目中。要确认,请在你喜欢的IDE中打开项目,并打开go.mod文件。内容应如下所示:

这意味着我们的Go私有模块已经作为依赖项添加,我们现在可以轻松地在我们的示例程序中使用它。让我们通过复制下面的内容并将其替换为先前添加的内容来更新我们的程序main.go文件:

在上面的程序中,我们将两个整数数组传递给我们私有的Go模块的filter函数,该函数将组合两个数组并过滤出重复的值。如果现在运行程序,我们将得到以下结果:

Go private module Example
[1 2 3 4 5 0 9 45]marvinhosea8

👉 这表明一切都按预期运行。

The GoDev Corner paragraph separator

Docker怎么办?

最终,你需要在某个时候创建一个Docker镜像。为了做到这一点,我们将看看如何配置Docker和Docker-compose文件以安全地下载我们的私有Go模块。

  • 在我们的示例项目中,运行以下命令创建一个Docker文件:
touch Dockerfile
  • 创建Dockerfile后,请将以下内容添加到其中:

☝️由于Docker超出了本文的范围,我只会解释Dockerfile的特定部分。第8和9行如下所示:

ARG GITHUB_TOKEN
ENV CGO_ENABLED=0 GO111MODULE=on GOOS=linux TOKEN=$GITHUB_TOKEN

我们定义了一个参数,它将在Docker镜像构建期间接受一个值。

💡出于安全考虑,参数是动态设置的。我再次强调,你的密钥和令牌不应该在Dockerfile中硬编码。

然后,我们传递GITHUB_TOKEN docker参数,一旦接收到GITHUB_TOKEN环境变量值(即我们的个人访问令牌),就会将其传递:

RUN go env -w GOPRIVATE=github.com/username/*

如前所述,此命令在第11行将设置Go的GOPRIVATE环境变量:

RUN git config --global url."https://${TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/"

第14行指定了我们将如何下载我们的私有Go模块,并使用Personal Access Token作为TOKEN传递环境变量:

在开始之前,让我们为我们的项目创建一个 .env 文件。

  • 在项目根目录中创建 .env 文件,并添加以下内容:

完成 .env 后,通过运行以下命令构建我们的应用程序Docker镜像:

export $(egrep -v ‘^#’ .env | xargs) && docker build --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} -t go-private-example .

在上述命令中,我们从我们的 .env 文件中获取值,并将它们作为环境变量及其值导出。然后我们使用从 .env 文件传递的环境变量参数运行Docker构建来构建Docker镜像。

构建完镜像后,我们可以通过运行以下命令来运行Docker镜像:

docker run go-private-example

输出结果应如下所示:

Go private module Example [1 2 3 4 5 0 9 45]

使用docker-compose

在项目的根目录中创建一个docker-compose.yml文件,并将其填充以下内容:

docker-compose文件与我们的Docker运行指令几乎相同。使用env_file标志传递环境文件,并按以下方式执行docker-compose命令:

docker compose up

输出结果应类似于以下内容:

[+] Running 1/0
 ⠿ go-private-example  Warning: No resource found to remove                            0.0s
[+] Running 2/2
 ⠿ Network go-private-example_default  Created                                         0.1s
 ⠿ Container go-private-example        Created                                         0.1s
Attaching to go-private-example
go-private-example  | Go private module Example
go-private-example  | [1 2 3 4 5 0 9 45]
go-private-example exited with code 0

现在,你已经拥有了自己的工作Go私有模块!

The GoDev Corner paragraph separator

结论

在本文中,我们探讨了使用和发布Go私有模块。我们还讨论了如何配置我们的设置以使用凭据下载Go私有模块以及如何在构建应用程序Docker镜像时使用私有Go模块。

我想再次强调——在配置和使用Go私有模块分发凭据时,你应该要小心,以避免暴露它们,这就是为什么它们被标记为私有的原因

参考资料

以下是文章代码库的列表:

GitHub — marvinhosea/go-private-example

GitHub — marvinhosea/filter: Article Repo

译自:https://medium.com/the-godev-corner/how-to-create-a-go-private-module-with-docker-b705e4d195c4

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
菜鸟一只
你就是个黄焖鸡,又黄又闷又垃圾。

评论(0)

添加评论