ActonOS Build Skill
Use this skill when building ActonOS artifacts: the frontend, Go binary, Docker image, or bare-metal ISO.
Build Pipeline Overview
make deps → make lint → make test → make test-race (Linux CI) → make build-web → make build → make docker → make iso
| Target | What It Does | Output |
|---|---|---|
make deps | Install Go + Node dependencies | — |
make lint | Run Go vet, gofmt, golangci-lint, ESLint | — |
make test | Run all tests (unit + integration) | build/coverage.out |
make test-race | Run the Linux CGO race detector | Required CI gate |
make build-web | Build React frontend (Vite production) | web/dist/ |
make build | Build full actond binary (includes web) | build/actond |
make build-only | Build Go binary only (skip web rebuild) | build/actond |
make docker | Build Docker image | actonos/actonos:VERSION |
make iso | Build bare-metal installation ISO | build/ActonOS-vVERSION.iso |
make all | Full pipeline: lint → test → build | build/actond |
Build Variables
The Go binary embeds version metadata via linker flags (-ldflags):
LDFLAGS := -s -w \
-X main.Version=$(VERSION) \
-X main.GitCommit=$(GIT_COMMIT)$(GIT_DIRTY) \
-X main.BuildTime=$(BUILD_TIME)
These are read from:
VERSIONfile →main.Versiongit rev-parse --short HEAD→main.GitCommitdate -u→main.BuildTime
Step-by-Step: Full Production Build
1. Build the Frontend
make build-web
# Runs: cd web && npm run build
# Output: web/dist/ (compressed static assets)
The frontend is built with Vite and produces gzip/brotli compressed assets that are embedded into the Go binary via go:embed.
2. Build the Go Binary
make build
# Runs: CGO_ENABLED=0 go build -trimpath -ldflags '...' -o build/actond ./cmd/actond/
Critical: Always build with CGO_ENABLED=0 for a fully static binary.
3. Cross-Compilation
# Linux AMD64 (default target for MiniPC/Docker)
GOOS=linux GOARCH=amd64 make build
# Linux ARM64 (for ARM-based devices)
GOOS=linux GOARCH=arm64 make build
4. Build Docker Image
make docker
# Output: actonos/actonos:VERSION and actonos/actonos:latest
The Dockerfile uses multi-stage build:
- Stage 1: Build Go binary
- Stage 2: Build frontend
- Stage 3: Alpine minimal runtime image (<35 MB)
5. Build ISO (Bare-metal)
# Requires: Debian/Ubuntu host with live-build and debootstrap
make iso
# Runs: bash scripts/build-iso.sh
# Output: build/ActonOS-vVERSION.iso
go:embed Integration
The built frontend assets are embedded into the Go binary:
// internal/server/static.go
//go:embed all:../../../web/dist
var embeddedAssets embed.FS
The layered_fs.go module implements a layered filesystem that checks /data/overrides/ before falling back to embedded assets, allowing runtime UI customization.
Verifying a Build
# Check binary version
./build/actond --version
# Check binary size
ls -lh build/actond
# Check it's truly static (no dynamic linking)
file build/actond
# Expected: "ELF 64-bit LSB executable, x86-64, statically linked"
# Quick smoke test
./build/actond --data-dir=./dev-data --log-level=debug &
curl http://localhost:8080/api/health
kill %1
Common Build Issues
| Issue | Cause | Solution |
|---|---|---|
web/dist not found | Frontend not built | Run make build-web first |
CGO required | Using mattn/go-sqlite3 | Use modernc.org/sqlite instead |
go:embed pattern matches no files | Empty web/dist/ | Build frontend first |
| Binary not static | CGO_ENABLED=1 | Set CGO_ENABLED=0 |
| Docker build OOM | Low memory during Go build | Increase Docker memory limit |
Reference Files
- Makefile — Build pipeline definitions
- deploy/docker/Dockerfile — Docker build config
- scripts/build-iso.sh — ISO build script
- internal/server/static.go — go:embed config