# HWLAB Deployment And Publish Reference This reference records the stable DEV publish and rollout rules. It does not authorize PROD, service restarts outside the documented DEV path, secret reads, or direct pushes to `main`. It is also the long-term reference for [pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116): service deployment regularization must progress from stable docs, to controlled CLI/script entrypoints, to UniDesk CI/CD plus imageized delivery. ## Workspaces | Purpose | Path | | --- | --- | | Runner and commander worktree | `/workspace/hwlab` | | D601 publish/build worktree | `/home/ubuntu/workspace/hwlab` | Use `/home/ubuntu/workspace/hwlab` for D601 build and rollout operations. Do not treat `/home/ubuntu/hwlab` or other runner worktrees as the publishing truth. ## Regularization Stages | Stage | Current HWLAB state | Required next behavior | | --- | --- | --- | | 1. Long-term reference | This file records DEV deployment, Cloud Web publish, API/edge/health, frp, D601 registry, k3s rollout, rollback, and verification rules. `AGENTS.md` indexes it. | Keep process issues as sources only; update this reference when a deployment rule changes. | | 2. CLI or controlled scripts | Existing controlled entrypoints cover contract planning, desired-state planning, artifact publish, DEV apply/report, k3s read-only visibility, and Cloud Web checks. Rollback is documented as commands/report hints but is not yet one unified CLI command. | Converge check, plan, publish, apply, rollback, status, and verify into HWLAB CLI or a small controlled script surface backed by `deploy/deploy.json`. | | 3. UniDesk CI/CD plus images | DEV services are imageized and published to the D601 registry. D601 rollout still includes manual bridge steps for Cloud Web and frp/k3s execution. | Move build, publish, desired-state refresh, rollout, post-deploy validation, and report upload into standard UniDesk CI/CD jobs without replacing HWLAB runtime. | ## Artifact Publish DEV artifacts publish to the D601 local/internal registry: ```text 127.0.0.1:5000/hwlab/* ``` The stable publish command is: ```sh node scripts/dev-artifact-publish.mjs --publish ``` For a single Cloud Web image: ```sh node web/hwlab-cloud-web/scripts/build.mjs node scripts/dev-artifact-publish.mjs --publish --services hwlab-cloud-web ``` Cloud Web must build `web/hwlab-cloud-web/dist` before publish because the runtime wrapper serves `dist` before source files. A correct source commit with stale `dist` can still publish an old UI. After a successful multi-service publish, refresh the artifact catalog from the publish report: ```sh node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json node scripts/deploy-desired-state-plan.mjs --promotion-commit $(git rev-parse --short=7 origin/main) --check ``` If publish is blocked, keep the report blocked rather than inventing digests: ```sh node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --blocked node scripts/deploy-desired-state-plan.mjs --promotion-commit $(git rev-parse --short=7 origin/main) --check ``` The desired-state files are a single deployment truth: `deploy/deploy.json`, `deploy/artifact-catalog.dev.json`, and `deploy/k8s/base/workloads.yaml` must carry the same promotion commit and immutable image tag before they are used as apply input. A `--target-ref` desired-state plan may report a uniform older state as `promotion_pending`; PR review and CI/CD promotion gates must use `--promotion-commit --check` so stale or partially refreshed commit, image, workload, and mirror-env fields are blocked before any DEV apply. Reports under `reports/` are evidence snapshots only and cannot override this desired-state contract. ## API, Edge, Health, And FRP The public route is fixed: | Surface | Current entry | | --- | --- | | Cloud Web | `http://74.48.78.17:16666/` | | Cloud Web live health | `http://74.48.78.17:16666/health/live` | | API/edge health | `http://74.48.78.17:16667/health` | | API/live health | `http://74.48.78.17:16667/health/live` | FRP maps master public `16666/16667` to D601 `hwlab-dev` services. Use `deploy/deploy.json` as the source for endpoint and FRP drift checks: ```sh node scripts/deploy-contract-plan.mjs --check ``` Do not reintroduce public `6666/6667` as active DEV endpoints. Internal k3s services may still use internal `6667`. ## Cloud Web Manual DEV Rollout The verified manual path for `hwlab-cloud-web` is: ```sh cd /home/ubuntu/workspace/hwlab git pull --ff-only origin main node web/hwlab-cloud-web/scripts/build.mjs node scripts/dev-artifact-publish.mjs --publish --services hwlab-cloud-web KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev set image deployment/hwlab-cloud-web hwlab-cloud-web=127.0.0.1:5000/hwlab/hwlab-cloud-web: KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout status deployment/hwlab-cloud-web --timeout=180s ``` The rollout must use D601 native k3s: ```sh KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev get deploy hwlab-cloud-web -o wide ``` Public verification must check the browser entry on `16666`, not legacy ports: ```sh curl -fsS http://74.48.78.17:16666/health/live curl -fsS http://74.48.78.17:16666/ | sed -n '1,80p' curl -fsS http://74.48.78.17:16666/styles.css | rg 'overflow: hidden|100dvh' curl -fsS http://74.48.78.17:16666/help.md | sed -n '1,40p' curl -fsS http://74.48.78.17:16667/health/live ``` Cloud Workbench acceptance also expects Chinese default UI, no outer page scroll, and an internal Markdown help surface. The frontend contract is [cloud-workbench.md](cloud-workbench.md). ## Apply Boundary `scripts/dev-deploy-apply.mjs` is the DEV-only apply/report path. A real apply requires explicit non-production flags: ```sh node scripts/dev-deploy-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report ``` The apply path must stop before mutation when artifact evidence, registry digests, kube access, DEV health, or required runtime readiness are missing. It must not read secret values or target PROD. Suspended template Jobs are immutable in `spec.template`. Only the explicit DEV allowlist may be replaced by the apply script: - `hwlab-agent-worker-template` - `hwlab-cli-template` ## Rollback Boundary Rollback remains DEV-only and must be explicit. Capture current image state before changing a workload: ```sh KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev get deploy hwlab-cloud-web -o wide KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout history deployment/hwlab-cloud-web ``` For a Deployment rolled by `set image`, use Kubernetes rollout undo only for the same DEV Deployment: ```sh KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout undo deployment/hwlab-cloud-web KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-dev rollout status deployment/hwlab-cloud-web --timeout=180s ``` After rollback, repeat public verification on `16666` and `16667`. Do not use rollback to change PROD, read secrets, restart unrelated services, or conceal an artifact/report mismatch. ## Controlled Entrypoint Design The #116 target is a single controlled deployment surface. Until that lands, use the repo-owned scripts below instead of ad hoc shell fragments. | Action | Current controlled entrypoint | Gap to close | | --- | --- | --- | | Check deployment contract and FRP/endpoint drift | `node scripts/deploy-contract-plan.mjs --check` | Fold into `hwlab deploy check --env dev`. | | Plan desired image/workload state | `node scripts/deploy-desired-state-plan.mjs --plan --pretty` and `node scripts/deploy-desired-state-plan.mjs --promotion-commit --check` | Fold into `hwlab deploy plan --env dev --file deploy/deploy.json` with a promotion commit gate. | | Preflight artifact publish | `node scripts/dev-artifact-publish.mjs --preflight` | Keep as backend for `hwlab artifact publish --preflight`. | | Publish DEV images | `node scripts/dev-artifact-publish.mjs --publish` | CI job should run this and upload digest reports. | | Refresh catalog/desired state | `node scripts/refresh-artifact-catalog.mjs --target-ref origin/main --publish-report reports/dev-gate/dev-artifacts.json` | Make refresh an explicit CLI/CD step after publish. | | Apply DEV rollout | `node scripts/dev-deploy-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report` | Keep apply behind confirmation flags and route through CLI/CD approval. | | Roll back DEV Deployment | `kubectl -n hwlab-dev rollout undo deployment/` with explicit D601 kubeconfig | Add `hwlab deploy rollback --env dev --service --to-revision `. | | Verify status | `curl` checks plus `node scripts/d601-k3s-readonly-observability.mjs` | Add `hwlab deploy verify --env dev --write-report`. | ## Automation Direction The stable direction from [pikasTech/HWLAB#61](https://github.com/pikasTech/HWLAB/issues/61) and [pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116) is to converge manual operations into CLI plus `deploy/deploy.json`, then run that surface from UniDesk CI/CD: - render and verify frps/frpc from the deploy manifest; - publish images and write digest reports; - refresh catalog/workload desired state from the publish report; - apply DEV with immutable Job replacement policy; - verify `16666` Cloud Web and `16667/health/live` API; - invalidate or regenerate active reports after endpoint or artifact changes. UniDesk CI/CD is infrastructure only. It may schedule build/publish/deploy jobs and store artifacts, but it must not replace `hwlab-cloud-api`, `hwlab-cloud-web`, `hwlab-router`, `hwlab-patch-panel`, simulators, gateways, or agent services as the runtime being validated. ## Stable Sources - [docs/dev-artifact-publish.md](../dev-artifact-publish.md): artifact publish command and report contract. - [docs/dev-deploy-apply.md](../dev-deploy-apply.md): apply/report and Cloud Web manual rollout details. - [pikasTech/HWLAB#61](https://github.com/pikasTech/HWLAB/issues/61): manual rollout review and automation target. - [pikasTech/HWLAB#116](https://github.com/pikasTech/HWLAB/issues/116): deployment regularization stages and acceptance.