ci(config): add GHCR image publish workflow
Publish frontend, backend, and remote-gateway images to GHCR on pushes to main and manual runs. Also update docker-compose to pull the three service images from ghcr.io instead of Docker Hub.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
name: Docker Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- service: frontend
|
||||
dockerfile: packages/frontend/Dockerfile
|
||||
- service: backend
|
||||
dockerfile: packages/backend/Dockerfile
|
||||
- service: remote-gateway
|
||||
dockerfile: packages/remote-gateway/Dockerfile
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/nexus-terminal-${{ matrix.service }}
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
type=sha,format=short,prefix=sha-
|
||||
|
||||
- name: Build and push ${{ matrix.service }}
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max,scope=${{ matrix.service }}
|
||||
@@ -3,3 +3,4 @@
|
||||
## [Unreleased]
|
||||
|
||||
- 2026-03-25:初始化 `.helloagents/` 知识库骨架与首批模块文档,不代表源码功能变更。
|
||||
- 2026-03-25:新增 GHCR Docker 发布 workflow,并将 `docker-compose.yml` 的三个业务镜像切换到 `ghcr.io/micah123321/*`。
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# 变更提案: ghcr-docker-publish
|
||||
|
||||
## 元信息
|
||||
```yaml
|
||||
类型: 新功能
|
||||
方案类型: implementation
|
||||
优先级: P1
|
||||
状态: 草稿
|
||||
状态说明: 已实施并归档
|
||||
创建: 2026-03-25
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. 需求
|
||||
|
||||
### 背景
|
||||
当前仓库没有自动构建并发布 Docker 镜像的 GitHub Actions,根目录 `docker-compose.yml` 仍引用 Docker Hub 上的 `heavrnl/*` 镜像。为了让提交到 `main` 后可以自动生成当前仓库对应的镜像,需要接入 GitHub Container Registry(GHCR)发布链路,并把本地编排切换到仓库所有者名下的 GHCR 镜像。
|
||||
|
||||
### 目标
|
||||
- 在 `main` 分支推送后,自动构建 `frontend`、`backend`、`remote-gateway` 三个 `amd64` 镜像并推送到 GHCR。
|
||||
- 每次 `main` 推送同时发布 `latest` 与 `sha-<commit>` 两类标签。
|
||||
- 将根目录 `docker-compose.yml` 切换为引用 `ghcr.io/micah123321/nexus-terminal-{frontend,backend,remote-gateway}:latest`。
|
||||
|
||||
### 约束条件
|
||||
```yaml
|
||||
时间约束: 无
|
||||
性能约束: 仅考虑 linux/amd64,暂不引入多架构构建
|
||||
兼容性约束: 现有三个 Dockerfile 必须继续可用,compose 中的服务名、端口和环境变量保持不变
|
||||
业务约束: 使用 GitHub 官方 Actions 与 GHCR;提交到 main 后自动发布 latest 和 sha 标签
|
||||
```
|
||||
|
||||
### 验收标准
|
||||
- [ ] `.github/workflows/` 下新增可在 `main` push 时构建并推送三类镜像的 workflow
|
||||
- [ ] workflow 发布的镜像仓库为 `ghcr.io/micah123321/nexus-terminal-{frontend,backend,remote-gateway}`
|
||||
- [ ] 每次 `main` push 至少生成 `latest` 和 `sha-<commit>` 两类标签
|
||||
- [ ] `docker-compose.yml` 中三个业务镜像已切换到上述 GHCR 地址
|
||||
|
||||
---
|
||||
|
||||
## 2. 方案
|
||||
|
||||
### 技术方案
|
||||
新增一个基于 `docker/setup-buildx-action`、`docker/login-action`、`docker/metadata-action` 和 `docker/build-push-action` 的 GitHub Actions workflow。workflow 在 `push` 到 `main` 时执行,使用 GitHub 提供的 `GITHUB_TOKEN` 登录 GHCR,按三个独立 job 分别构建 `frontend`、`backend`、`remote-gateway` 镜像。每个 job 都显式指定 `platforms: linux/amd64`,并通过 metadata action 生成 `latest` 与 `sha-<commit>` 标签。随后更新根 `docker-compose.yml` 中的镜像引用到当前仓库 owner 的 GHCR 镜像。
|
||||
|
||||
### 影响范围
|
||||
```yaml
|
||||
涉及模块:
|
||||
- workspace-root: 新增 workflow,更新 docker-compose 镜像来源
|
||||
- frontend: 使用现有 Dockerfile 作为 GHCR 构建输入
|
||||
- backend: 使用现有 Dockerfile 作为 GHCR 构建输入
|
||||
- remote-gateway: 使用现有 Dockerfile 作为 GHCR 构建输入
|
||||
预计变更文件: 2
|
||||
```
|
||||
|
||||
### 风险评估
|
||||
| 风险 | 等级 | 应对 |
|
||||
|------|------|------|
|
||||
| workflow 使用 `GITHUB_TOKEN` 推送 GHCR 失败(仓库包权限未开启) | 中 | 在 workflow 中显式声明 `packages: write`,并沿用官方登录动作 |
|
||||
| 某个 Dockerfile 在 GitHub Actions 环境下构建失败 | 中 | 保持各镜像独立 job,便于快速定位失败服务 |
|
||||
| compose 切到 GHCR 后,用户若未登录私有包仓库将拉取失败 | 低 | 默认假设目标仓库包可公开读取;若后续设为私有,再补充部署说明 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术设计(可选)
|
||||
|
||||
### 架构设计
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[push main] --> B[GitHub Actions workflow]
|
||||
B --> C[build frontend image]
|
||||
B --> D[build backend image]
|
||||
B --> E[build remote-gateway image]
|
||||
C --> F[GHCR]
|
||||
D --> F
|
||||
E --> F
|
||||
G[docker-compose.yml] --> F
|
||||
```
|
||||
|
||||
### API设计
|
||||
N/A
|
||||
|
||||
### 数据模型
|
||||
N/A
|
||||
|
||||
---
|
||||
|
||||
## 4. 核心场景
|
||||
|
||||
### 场景: main 分支自动发布镜像
|
||||
**模块**: workspace-root
|
||||
**条件**: 向 `main` 分支推送提交。
|
||||
**行为**: GitHub Actions 自动构建三个服务的 `linux/amd64` 镜像并推送到 GHCR,同时生成 `latest` 和 `sha-<commit>` 标签。
|
||||
**结果**: 仓库发布链路与部署编排使用同一组 GHCR 镜像来源。
|
||||
|
||||
### 场景: 本地 compose 拉取远程镜像
|
||||
**模块**: workspace-root
|
||||
**条件**: 部署环境执行 `docker compose pull` 或 `docker compose up`。
|
||||
**行为**: `docker-compose.yml` 直接从 `ghcr.io/micah123321/*` 拉取三个业务镜像。
|
||||
**结果**: compose 不再依赖旧的 Docker Hub 镜像命名。
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术决策
|
||||
|
||||
### ghcr-docker-publish#D001: 使用 GHCR + main push 自动发布 latest 和 sha 标签
|
||||
**日期**: 2026-03-25
|
||||
**状态**: ✅采纳
|
||||
**背景**: 需要在不引入额外制品系统的前提下,把当前仓库的 Docker 镜像发布链路收口到 GitHub。
|
||||
**选项分析**:
|
||||
| 选项 | 优点 | 缺点 |
|
||||
|------|------|------|
|
||||
| A: GHCR + `latest` + `sha-<commit>` | 与 GitHub 仓库权限一体化,既有稳定标签又可精确追溯到提交 | 会额外产生较多镜像标签 |
|
||||
| B: 仅发布 `latest` | 配置最简单 | 无法精确回滚到指定提交 |
|
||||
**决策**: 选择方案 A
|
||||
**理由**: 该方案兼顾可追溯性与部署便利性,适合当前“提交即发布”的需求。
|
||||
**影响**: 影响 `.github/workflows` 和根 `docker-compose.yml`,后续部署默认从 GHCR 拉取镜像。
|
||||
|
||||
---
|
||||
|
||||
## 6. 成果设计
|
||||
|
||||
N/A
|
||||
@@ -0,0 +1,51 @@
|
||||
# 任务清单: ghcr-docker-publish
|
||||
|
||||
```yaml
|
||||
@feature: ghcr-docker-publish
|
||||
@created: 2026-03-25
|
||||
@status: completed
|
||||
@mode: R2
|
||||
```
|
||||
|
||||
## 进度概览
|
||||
|
||||
| 完成 | 失败 | 跳过 | 总数 |
|
||||
|------|------|------|------|
|
||||
| 4 | 0 | 0 | 4 |
|
||||
|
||||
---
|
||||
|
||||
## 任务列表
|
||||
|
||||
### 1. 发布工作流
|
||||
|
||||
- [√] 1.1 在 `.github/workflows/docker-publish.yml` 中新增 main push 触发的 GHCR 发布 workflow | depends_on: []
|
||||
- [√] 1.2 为 workflow 配置 `frontend`、`backend`、`remote-gateway` 三个镜像的 `linux/amd64` 构建与 `latest`/`sha-<commit>` 标签 | depends_on: [1.1]
|
||||
|
||||
### 2. 部署编排
|
||||
|
||||
- [√] 2.1 在 `docker-compose.yml` 中把三个业务镜像切换到 `ghcr.io/micah123321/nexus-terminal-{frontend,backend,remote-gateway}:latest` | depends_on: [1.2]
|
||||
|
||||
### 3. 验证与知识库同步
|
||||
|
||||
- [√] 3.1 检查 workflow 与 compose 语法/内容一致性,并记录已知限制 | depends_on: [2.1]
|
||||
|
||||
---
|
||||
|
||||
## 执行日志
|
||||
|
||||
| 时间 | 任务 | 状态 | 备注 |
|
||||
|------|------|------|------|
|
||||
| 2026-03-25 03:17 | 方案包创建 | 完成 | 创建 implementation 类型方案包并进入开发实施 |
|
||||
| 2026-03-25 03:24 | 1.1 / 1.2 | 完成 | 新增 GHCR 发布 workflow,main push 发布 latest 和 sha 标签 |
|
||||
| 2026-03-25 03:24 | 2.1 | 完成 | docker-compose 三个业务镜像切换到 ghcr.io/micah123321 |
|
||||
| 2026-03-25 03:25 | 3.1 | 完成 | 已人工复核 workflow 与 compose;本机缺少 docker,未执行 `docker compose config` |
|
||||
|
||||
---
|
||||
|
||||
## 执行备注
|
||||
|
||||
> 记录执行过程中的重要说明、决策变更、风险提示等
|
||||
|
||||
- 由于当前环境无 Python 解释器,方案包由主代理按模板直接创建。
|
||||
- 本机缺少 Docker CLI,compose 未做命令级语法验证;workflow 也未运行 `actionlint`。
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
| 时间戳 | 名称 | 类型 | 涉及模块 | 决策 | 结果 |
|
||||
|--------|------|------|---------|------|------|
|
||||
| 暂无 | - | - | - | - | - |
|
||||
| 202603250317 | ghcr-docker-publish | implementation | workspace-root | ghcr-docker-publish#D001 | ✅完成 |
|
||||
|
||||
## 按月归档
|
||||
|
||||
### 2026-03
|
||||
- 暂无已归档方案
|
||||
- [202603250317_ghcr-docker-publish](./2026-03/202603250317_ghcr-docker-publish/) - 新增 GHCR 镜像发布 workflow 并切换 compose 镜像来源
|
||||
|
||||
## 结果状态说明
|
||||
- ✅ 完成
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
语言: TypeScript, Vue, Node.js
|
||||
框架: Vue 3, Vite, Express 5
|
||||
包管理器: npm workspaces
|
||||
构建工具: Vite(frontend), TypeScript 编译(backend/remote-gateway), Docker Compose(部署)
|
||||
构建工具: Vite(frontend), TypeScript 编译(backend/remote-gateway), GitHub Actions + GHCR(镜像发布), Docker Compose(部署)
|
||||
```
|
||||
|
||||
### 主要依赖
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## 职责
|
||||
|
||||
管理仓库根目录的 npm workspaces、共享依赖、`patch-package` 补丁应用以及 Docker Compose 部署编排。该模块不是业务运行时服务,但决定了三个子包如何安装、构建和协同运行。
|
||||
管理仓库根目录的 npm workspaces、共享依赖、`patch-package` 补丁应用、GitHub Actions 发布流程以及 Docker Compose 部署编排。该模块不是业务运行时服务,但决定了三个子包如何安装、构建、发布和协同运行。
|
||||
|
||||
## 接口定义(可选)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|----------|------|--------|------|
|
||||
| `package.json#workspaces` | `packages/*` | npm workspace 列表 | 声明后端、前端、远程网关三个子包属于同一工作区。 |
|
||||
| `package.json#postinstall` | 无 | shell 命令 | 安装依赖后自动执行 `patch-package`。 |
|
||||
| `.github/workflows/docker-publish.yml` | GitHub push / workflow_dispatch 事件 | GHCR 镜像 | 在 `main` 推送时发布三个 `linux/amd64` 业务镜像到 GHCR。 |
|
||||
| `docker-compose.yml` | 环境变量、卷、端口映射 | 服务编排 | 统一启动 `frontend`、`backend`、`remote-gateway`、`guacd`。 |
|
||||
|
||||
### 数据结构
|
||||
@@ -31,9 +32,14 @@
|
||||
|
||||
### 容器化部署
|
||||
**条件**: 使用根目录 `docker-compose.yml` 启动服务。
|
||||
**行为**: `frontend` 暴露 `18111:80`,`backend` 读取根 `.env` 并挂载 `./data:/app/data`,`remote-gateway` 依赖 `guacd` 和 `backend`。
|
||||
**行为**: `frontend` 暴露 `18111:80`,`backend` 读取根 `.env` 并挂载 `./data:/app/data`,`remote-gateway` 依赖 `guacd` 和 `backend`,三个业务镜像默认从 `ghcr.io/micah123321` 拉取。
|
||||
**结果**: Web 入口、REST API、远程桌面网关与 `guacd` 形成完整运行拓扑。
|
||||
|
||||
### 镜像自动发布
|
||||
**条件**: 向 `main` 分支推送代码,或在 GitHub Actions 手动触发 workflow。
|
||||
**行为**: `.github/workflows/docker-publish.yml` 使用各子包现有 Dockerfile 构建 `linux/amd64` 镜像,并向 GHCR 发布 `latest` 与 `sha-<commit>` 标签。
|
||||
**结果**: 仓库镜像发布链路与 compose 使用的镜像来源保持一致。
|
||||
|
||||
## 依赖关系
|
||||
|
||||
```yaml
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
frontend:
|
||||
image: heavrnl/nexus-terminal-frontend:latest
|
||||
image: ghcr.io/micah123321/nexus-terminal-frontend:latest
|
||||
container_name: nexus-terminal-frontend
|
||||
ports:
|
||||
- "18111:80"
|
||||
@@ -11,7 +11,7 @@ services:
|
||||
- nexus-terminal-network
|
||||
|
||||
backend:
|
||||
image: heavrnl/nexus-terminal-backend:latest
|
||||
image: ghcr.io/micah123321/nexus-terminal-backend:latest
|
||||
container_name: nexus-terminal-backend
|
||||
env_file:
|
||||
- .env
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
- nexus-terminal-network
|
||||
|
||||
remote-gateway:
|
||||
image: heavrnl/nexus-terminal-remote-gateway:latest
|
||||
image: ghcr.io/micah123321/nexus-terminal-remote-gateway:latest
|
||||
container_name: nexus-terminal-remote-gateway
|
||||
environment:
|
||||
GUACD_HOST: guacd
|
||||
|
||||
Reference in New Issue
Block a user