差不多两年前学习记录过《使用 Github Action 自动构建 Release 版本》,也研究过《使用 Docker 构建多架构镜像》,手动推镜像到 DockerHub,其实一直还差最后一公里 —— 提交代码到 Github 自动构建 Release 二进制成品,并构建镜像推送到 DockerHub 仓库。
而这就是 Goreleaser 所擅长的,本文记录了相关配置和使用方式。
本地安装 Goreleaser
brew install goreleaser
Go Releaser 配置
在项目根目录执行初始化,生成 .goreleaser.yaml 配置文件
goreleaser init
按需修改,我的示例配置如下
version: 2
project_name: passkey-demo
before:
hooks:
- go mod tidy
builds:
- id: server
main: .
binary: passkey-demo
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
goarch:
- amd64
- arm64
ldflags:
- -s -w
- -X main.version={{ .Version }}
- -X main.commit={{ .Commit }}
archives:
- id: default
formats: [tar.gz]
name_template: >-
{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}
checksum:
name_template: checksums.txt
changelog:
use: github
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- "^chore:"
release:
draft: true
prerelease: auto
footer: |
---
Released by GoReleaser.
dockers_v2:
- id: server
ids:
- server
dockerfile: Dockerfile
platforms:
- linux/amd64
- linux/arm64
images:
- "{{ .Env.DOCKERHUB_USERNAME }}/passkey-demo"
tags:
- "{{ .Version }}"
- latest
注意需要替换 “your-docker-hub-username” 为你的 DockerHub 的用户名,登录后在 URL 中的就是用户名

Github Action 配置
创建/修改 .github/workflows/release.yml 文件,内容如下:
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: '1.25'
check-latest: true
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
以上配置的 secrets.GITHUB_TOKEN 无需手动配置,Docker 的两个环境变量需要配置。
获取 Docker User Access Token
点击右上角头像,点击 “Account Settings” - “Settings” 下的 “Personal access tokens”,创建一个 “Read & Write” 权限的 Token

生成的 Token 只展示一次,复制下来使用,即 secrets.DOCKERHUB_TOKEN
在 Github 上配置 Secrets
点击 Github 仓库的 “Settings”,侧边栏找到 “Secrets and variables”,我这里添加的是 Repository secrets 类型

Dockerfile 配置参考
放到项目根目录
FROM alpine:3.23
RUN apk add --no-cache ca-certificates
WORKDIR /app
# 使用构建参数获取目标架构
ARG TARGETARCH
# GoReleaser 将二进制文件放在 linux/<arch>/ 目录下
COPY linux/${TARGETARCH}/passkey-demo /app/passkey-demo
EXPOSE 8080
ENTRYPOINT ["/app/passkey-demo"]
本地测试构建
注意替换 DOCKERHUB_USERNAME 为你的用户名
DOCKERHUB_USERNAME=your-username goreleaser release --snapshot --clean

查看构建的镜像
docker images | grep passkey-demo
已构建出镜像

如果想进一步运行测试镜像,可以运行:
docker run --rm -p 8080:8080 kissbug8720/passkey-demo:latest
推送标签触发构建
git tag v0.0.12
git push origin v0.0.12
在仓库的 Action 可以看到构建任务。

构建完成后,在 Github 仓库的 releases 可以看到一个 Draft 类型的发布,点击编辑,可修改描述,二进制成品也可以编辑,发布后即对外部可见。
Github Release

Docker Hub 镜像
访问:https://hub.docker.com/r/kissbug8720/passkey-demo/tags

可以看到 0.0.12 标签后 latest 标签的镜像。
最后
从「手动便携难以维护的脚本」到「封装良好的现代化发布方案」,Golang 项目非常推荐使用 Goreleaser 进行发布。