ActonOS 构建技能
在构建 ActonOS 产物时使用此技能:前端、Go 二进制文件、Docker 镜像或裸机 ISO。
构建流水线概览
make deps → make lint → make test → make test-race (Linux CI) → make build-web → make build → make docker → make iso
| 目标 | 功能 | 输出 |
|---|---|---|
make deps | 安装 Go + Node 依赖 | — |
make lint | 运行 Go vet、gofmt、golangci-lint、ESLint | — |
make test | 运行所有测试(单元测试 + 集成测试) | build/coverage.out |
make test-race | 运行 Linux CGO 竞态检测器 | 必需的 CI 门控 |
make build-web | 构建 React 前端(Vite 生产模式) | web/dist/ |
make build | 构建完整的 actond 二进制文件(包含前端) | build/actond |
make build-only | 仅构建 Go 二进制文件(跳过前端重建) | build/actond |
make docker | 构建 Docker 镜像 | actonos/actonos:VERSION |
make iso | 构建裸机安装 ISO | build/ActonOS-vVERSION.iso |
make all | 完整流水线:lint → test → build | build/actond |
构建变量
Go 二进制文件通过链接器标志(-ldflags)嵌入版本元数据:
LDFLAGS := -s -w \
-X main.Version=$(VERSION) \
-X main.GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) \
-X main.BuildTime=$(BUILD_TIME)
这些值从以下来源读取:
VERSION文件 →main.Versiongit rev-parse --short HEAD→main.GitCommitdate -u→main.BuildTime
分步指南:完整生产构建
1. 构建前端
make build-web
# 运行:cd web && npm run build
# 输出:web/dist/(压缩的静态资源)
前端使用 Vite 构建并生成 gzip/brotli 压缩资源,这些资源通过 go:embed 嵌入到 Go 二进制文件中。
2. 构建 Go 二进制文件
make build
# 运行:CGO_ENABLED=0 go build -trimpath -ldflags '...' -o build/actond ./cmd/actond/
关键:始终使用 CGO_ENABLED=0 构建完全静态的二进制文件。
3. 交叉编译
# Linux AMD64(MiniPC/Docker 的默认目标)
GOOS=linux GOARCH=amd64 make build
# Linux ARM64(适用于 ARM 设备)
GOOS=linux GOARCH=arm64 make build
4. 构建 Docker 镜像
make docker
# 输出:actonos/actonos:VERSION 和 actonos/actonos:latest
Dockerfile 使用多阶段构建:
- 阶段 1:构建 Go 二进制文件
- 阶段 2:构建前端
- 阶段 3:Alpine 最小运行时镜像(<35 MB)
5. 构建 ISO(裸机)
# 需要:Debian/Ubuntu 主机,已安装 live-build 和 debootstrap
make iso
# 运行:bash scripts/build-iso.sh
# 输出:build/ActonOS-vVERSION.iso
go:embed 集成
构建好的前端资源嵌入到 Go 二进制文件中:
// internal/server/static.go
//go:embed all:../../../web/dist
var embeddedAssets embed.FS
layered_fs.go 模块实现了一个分层文件系统,在回退到嵌入资源之前会先检查 /data/overrides/,从而允许运行时 UI 自定义。
验证构建
# 检查二进制文件版本
./build/actond --version
# 检查二进制文件大小
ls -lh build/actond
# 确认它是完全静态的(无动态链接)
file build/actond
# 预期输出: