@h-ai/deploy 0.1.0-alpha.65 → 0.1.0-alpha.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +80 -143
- package/README.ja.md +81 -144
- package/README.md +112 -145
- package/dist/index.d.ts +61 -26
- package/dist/index.js +956 -506
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -1,201 +1,138 @@
|
|
|
1
1
|
# @h-ai/deploy
|
|
2
2
|
|
|
3
|
-
[简体中文](
|
|
3
|
+
[简体中文](README.md) | [English](README.en.md) | [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Introduction
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Deploy existing images or Vercel prebuilt output, including complete offline bundles, selected service updates, SSH automation and platform upload scripts. The SDK consumes artifacts; CLI --build explicitly orchestrates build then deployment.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Core features
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| `vercel` | SvelteKit with adapter-vercel | Build, upload, set environment variables and wait for deployment; requires internet |
|
|
11
|
+
- Build, package, upload over SSH, start services and check access from one CLI command.
|
|
12
|
+
- Include application and self-hosted middleware images, or update selected services.
|
|
13
|
+
- Deliver offline tar bundles with Windows/Linux/macOS operator scripts, step results and recovery on failure.
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
- Select an environment and require `.env.<mode>` before choosing defaults, custom connections or keep unchanged per middleware. Complete environments can skip all middleware processing.
|
|
18
|
-
- Compose supports PostgreSQL, MySQL, Redis, RustFS/MinIO, Qdrant, pgvector, Chroma, OpenLDAP and Mailpit. SQLite, memory, local and LanceDB use their respective local storage. Mailpit captures test mail only.
|
|
19
|
-
- Cloud provisioning supports Neon, Upstash, Cloudflare R2, Resend and Alibaba Cloud SMS. R2 needs existing S3 credentials, Resend a verified sender domain, and SMS approved signatures/templates. Use custom connections for other backends.
|
|
15
|
+
## Getting started
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
### Prepare build artifacts
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
Projects include deployment tooling by default; use `hai create my-app --no-deploy` to opt out. The deployment SDK is a development dependency and is excluded from runtime images.
|
|
24
20
|
|
|
25
|
-
|
|
21
|
+
```sh
|
|
22
|
+
pnpm build
|
|
23
|
+
pnpm build --target docker
|
|
24
|
+
pnpm build --target docker --images web
|
|
25
|
+
pnpm build --target desktop --platform windows --arch x64
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
#### Build options
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
`--target` selects compile (default), docker or desktop. `--images app|web|app,web` selects images. `--runtime auto|podman|docker` selects the local engine; auto prefers reachable Podman. `--network` overrides build networking, `--no-http-proxy` disables inherited Podman proxies, and `--sqlite-prebuild-mirror` selects a trusted HTTP(S) binary mirror. Native `--platform` and `--arch` require the matching host SDK and Rust toolchain. Builds do not load deployment environments or runtime secrets.
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
#### Describe packaging in hai.build.json
|
|
30
33
|
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
pnpm.cmd exec hai --help
|
|
34
|
+
```json
|
|
35
|
+
{ "images": [{ "name": "app", "context": ".", "dockerfile": "images/app.Dockerfile", "containerPort": 3000 }, { "name": "web", "context": ".", "dockerfile": "images/web.Dockerfile", "containerPort": 8080 }] }
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
|
|
38
|
+
Each image has its own Dockerfile. Web runtime assets live in images/web/. Dockerfiles retain internal build/runtime stages; configuration does not select stages. Omit absent images and add desktop directories only for native projects.
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
Dependency inputs are prepared under images/dependencies/ from package manifests, local archives and patches. Combine pnpm store caching with stable dependency layers. Source changes should reuse downloaded packages. Empty caches still permit online builds. Windows node_modules cannot supply Linux native dependencies. Offline builds additionally require base images, tools and matching ABI/architecture/libc binaries.
|
|
39
41
|
|
|
40
|
-
-
|
|
41
|
-
- Local `ssh` and `scp`, noninteractive key/agent authentication and the server host fingerprint.
|
|
42
|
-
- Remote Docker/Podman with its `compose` command. The SSH user must run containers and write the deployment directory. Windows must reach SSH and the exposed application port.
|
|
43
|
-
- `config/_deploy.yml` in the target package and `.env.prod` or `.env.test` in the environment directory. Missing environment files stop deployment.
|
|
42
|
+
The root package.json.version identifies the application. `.hai/build/docker/<buildId>/` contains manifest format 3, selected image archives and SHA-256. partial marks incremental builds and hasWeb records topology. appContainerPort and webContainerPort retain explicitly configured app/web listening ports, including the image left out of a partial build. Omitted ports keep the deployment defaults. Rebuilding the same application version is allowed; unique build IDs/image references distinguish contents. Publish the local build pointer only after all exports succeed. Pin base images, middleware and tools; do not use latest.
|
|
44
43
|
|
|
45
|
-
###
|
|
44
|
+
### Deploy artifacts
|
|
46
45
|
|
|
47
|
-
|
|
46
|
+
#### Prepare the environment and destination
|
|
47
|
+
|
|
48
|
+
Prepare `.env.<environment>` and the service config/_deploy.yml. Fullstack deploy scripts point to packages/<project>-serv; API workspaces use apps/<project>-service. Artifact lookup remains rooted at the build configuration.
|
|
48
49
|
|
|
49
50
|
```yaml
|
|
50
51
|
provider:
|
|
51
52
|
type: docker-ssh
|
|
53
|
+
expose:
|
|
54
|
+
hostPort: 18080
|
|
52
55
|
container:
|
|
53
|
-
runtime: docker
|
|
54
56
|
s3Engine: rustfs
|
|
55
|
-
services: {}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Replace the host, user, ports and key path for your environment. Never commit `.env.local`:
|
|
59
|
-
|
|
60
|
-
```dotenv
|
|
61
|
-
HAI_DEPLOY_PROVIDER='{"type":"docker-ssh","ssh":{"host":"10.0.0.20","port":22,"username":"deploy","identityFile":"C:/Users/me/.ssh/hai_deploy"},"remote":{"baseDir":"/opt/hai/apps","runtime":"docker"},"expose":{"type":"port","containerPort":3000,"hostPort":18080}}'
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Alternatively, the wizard asks for missing target details, saves them in `.env.local` and reuses them. Store private key paths only. Edit `HAI_DEPLOY_PROVIDER` to switch a complete target.
|
|
65
|
-
|
|
66
|
-
Precedence: `.env` → `.env.<mode>` → `.env.local` → process environment. Parent JSON such as `HAI_DB` overrides child variables. `.env.example` documents all fields and enums. Commit `.env` and `.env.dev/test/prod`; keep real credentials in `.env.local`. Fullstack's first start also needs a private `HAI_ADMIN_DEFAULT_PASSWORD` satisfying the IAM password policy.
|
|
67
|
-
|
|
68
|
-
Fullstack production also requires an explicit Web Origin in `.env.prod`, such as `HAI_SERV_CORS_ORIGIN=https://app.hai.internal`; the default `*` prevents production startup. Production refresh cookies use Secure, so Web/API need trusted HTTPS endpoints. Exposing HTTP ports alone does not validate complete login/session refresh.
|
|
69
|
-
|
|
70
|
-
### 3. Deploy
|
|
71
|
-
|
|
72
|
-
From the fullstack root, replace the service directory:
|
|
73
|
-
|
|
74
|
-
```powershell
|
|
75
|
-
pnpm.cmd exec hai deploy packages/my-app-serv --env prod --env-dir .
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The wizard shows the effective backend and purpose. Defaults generate Compose services/volumes; custom connections omit that middleware container. Keep unchanged is offered only when the target environment file explicitly declares complete configuration. Public values go to the selected environment file, credentials to `.env.local`, with redacted output.
|
|
79
|
-
|
|
80
|
-
When all database, cache and storage connections are already configured:
|
|
81
|
-
|
|
82
|
-
```powershell
|
|
83
|
-
pnpm.cmd exec hai deploy packages/my-app-serv --env prod --env-dir . --yes --skip-middleware
|
|
84
57
|
```
|
|
85
58
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
`--project-name <name>` sets the name; an explicit environment adds a suffix. **`--skip-build` currently skips only Vercel application builds. docker-ssh always builds an image and has no option to deploy a specified existing image directly.** Failures return a nonzero exit code.
|
|
89
|
-
|
|
90
|
-
## docker-ssh execution and files
|
|
91
|
-
|
|
92
|
-
1. Use the target package's Dockerfile, or generate a fallback with the workspace root as context. Fullstack service packages use the fallback by default, not the root Web target.
|
|
93
|
-
2. Build the image locally and export a tar with `docker/podman save`.
|
|
94
|
-
3. Check the remote engine and Compose over SSH, upload the tar with SCP, then run `load` remotely.
|
|
95
|
-
4. Generate `compose.yml`, `.env.runtime` and `start-<mode>.sh` locally and upload each to `<baseDir>/<projectName>-<mode>/`. These are separate from the image archive; no single Compose bundle is uploaded and no source build runs on Linux.
|
|
96
|
-
5. The remote script sets `HAI_DEPLOY_ENVIRONMENT`/`HAI_CORE_ENV` and runs `compose --env-file .env.runtime ... up -d`. The SDK checks native `/health` or SvelteKit `/` from the local machine before succeeding.
|
|
97
|
-
|
|
98
|
-
Local artifacts live in the target package's Git-ignored `.hai/deploy/<mode>/`. Remote `.env.runtime` uses mode `600`. Retain local artifacts for repeat deployment: keep unchanged preserves services/volumes from the previous local Compose, not arbitrary server-side Compose definitions. Exclude private environment files and deployment archives from image contexts.
|
|
99
|
-
|
|
100
|
-
## Fully offline deployment
|
|
101
|
-
|
|
102
|
-
Offline means no internet; Windows and Linux must still communicate over an internal SSH/HTTP network. Vercel and cloud provisioning are unavailable.
|
|
103
|
-
|
|
104
|
-
### Materials to bring in advance
|
|
105
|
-
|
|
106
|
-
| Location | Requirements |
|
|
107
|
-
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
108
|
-
| Windows tools | Compatible Node (for example a supported Node 24), pnpm 12.11.2, installed CLI/SDK and transitive dependencies, OpenSSH, initialized and runnable Linux container engine |
|
|
109
|
-
| Project | Complete source, pinned lockfile, environment files and private credentials; `pnpm.cmd exec hai --help` must work offline. Avoid on-demand `npx` / `pnpm dlx` downloads |
|
|
110
|
-
| Linux | Docker CLI/Engine, Compose plugin (`docker compose version` works), authorized SSH key, container permissions, writable deployment directory, ports and disk space. Host Node/pnpm are unnecessary for running images |
|
|
111
|
-
| Images | API, Web and middleware images matching Linux CPU architecture and exact Compose names/tags; import with `docker load -i <archive.tar>` |
|
|
112
|
-
| Application | PostgreSQL database/account, Redis connection/password, RustFS keys/bucket and initial administrator password. Existing services must already run and be reachable from the app container; `localhost` means that container |
|
|
59
|
+
The wizard asks for server address, SSH user, optional key/fingerprint files and public port using readable labels. Reuse valid settings; local connection settings go to .env.local, private keys are referenced by path. Bundle-only does not require SSH.
|
|
113
60
|
|
|
114
|
-
|
|
61
|
+
#### Configure only the middleware the application needs
|
|
115
62
|
|
|
116
|
-
|
|
63
|
+
Runtime lockfile dependencies and configuration determine middleware. Choose defaults, custom connections or keep settings. --skip-middleware skips configuration/provisioning. SQLite, memory cache and local storage need no external images. Complete bundles automatically include self-hosted middleware images. External services still require reachable destinations; cloud provisioning is not an offline operation.
|
|
117
64
|
|
|
118
|
-
|
|
65
|
+
#### Deployment options
|
|
119
66
|
|
|
120
|
-
|
|
67
|
+
--env/--env-dir select configuration. --build builds selected application images before packaging. --services selects Compose services; --artifact-dir selects existing artifacts. --bundle-only creates a tar and platform scripts without SSH. --runtime selects the local build/export engine; --output selects the version-suffixed archive name. --yes uses valid settings without interaction and reports missing required values.
|
|
121
68
|
|
|
122
|
-
|
|
69
|
+
#### When the machines can connect: automatic deployment
|
|
123
70
|
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
71
|
+
```sh
|
|
72
|
+
pnpm run deploy --env prod --build
|
|
73
|
+
pnpm run deploy --env prod --artifact-dir .hai/build/docker/<buildId>
|
|
74
|
+
pnpm run deploy --env prod --build --services web
|
|
128
75
|
```
|
|
129
76
|
|
|
130
|
-
|
|
77
|
+
Partial updates require a successful full server installation and matching ports/layout. Merge selected services into the server's successful baseline; preserve unselected services, settings and volumes. The deployment script first removes only the selected old containers by project and service labels, retaining their volumes. It then runs `compose up -d --no-deps --no-build --pull never --no-recreate web` to create replacements while other containers keep running, without project-wide down. storage-init is a one-time S3 bucket initialization task, executed only when storage initialization is selected.
|
|
131
78
|
|
|
132
|
-
|
|
133
|
-
FROM my-app-api:offline
|
|
134
|
-
```
|
|
79
|
+
Here `-d` starts in the background; `--no-deps` leaves dependencies untouched; `--no-build` prevents server builds; `--pull never` forbids registry pulls; `--no-recreate` preserves containers that still exist; the selected old containers were already removed by the script, so their replacements are created. `web` is a Compose service name, not an image tag; separate multiple services with spaces.
|
|
135
80
|
|
|
136
|
-
|
|
81
|
+
`storage-init` uses the application's S3 SDK to wait for storage and create a missing bucket without deleting data. Start storage first, then run `compose up --no-deps --no-build --pull never --force-recreate --exit-code-from storage-init storage-init`. Start selected application services only after initialization exits with zero. For partial updates, the script first removes the old storage-init container and uses `--no-recreate` instead of `--force-recreate` here, preserving running application containers. Updating only `storage` still requires an artifact containing the `app` image for initialization. If the most recent build contains only Web, select the original complete artifact with `--artifact-dir`, or run `pnpm build --target docker --images app` first. This image is used for initialization without updating the running `app` service.
|
|
137
82
|
|
|
138
|
-
|
|
83
|
+
#### When the machines cannot connect: copy a bundle
|
|
139
84
|
|
|
140
85
|
```sh
|
|
141
|
-
|
|
142
|
-
docker run -d --name my-app-web-prod --restart unless-stopped -p 18081:8080 -e PUBLIC_API_BASE=https://api.hai.internal my-app-web:offline
|
|
86
|
+
pnpm run deploy --env prod --build --bundle-only --output release-prod.tar
|
|
143
87
|
```
|
|
144
88
|
|
|
145
|
-
|
|
89
|
+
Application 1.2.3 produces release-prod-1.2.3.tar and an adjacent -deploy/ directory. The tar includes selected application/middleware images, configurations, private environment files, checksums, README and apply.sh. Run deploy.ps1 on Windows or deploy.sh on Linux/macOS to upload using saved SSH settings and execute the same server workflow. After moving to another computer or operating system, update both the private key and known-hosts paths to files on that computer. On Windows, edit deploy-target.json; on Linux/macOS, set HAI_DEPLOY_IDENTITY_FILE and HAI_DEPLOY_KNOWN_HOSTS_FILE.
|
|
146
90
|
|
|
147
|
-
|
|
91
|
+
On isolated Linux servers, extract into a separate package directory and run `sh apply.sh`, optionally passing the deployment root. Every failed step exits nonzero. Image loading, service startup and HTTP checks are distinct steps. result-<deploymentId>.json records the result; current changes only after successful checks. Reapplying the same deployment ID stops clearly; a newly generated bundle for the same application version is allowed. Failed updates attempt to restore selected containers and configuration while preserving data volumes and diagnostics. Data already written by the application is not rolled back.
|
|
148
92
|
|
|
149
|
-
|
|
93
|
+
#### Before going fully offline
|
|
150
94
|
|
|
151
|
-
|
|
95
|
+
Complete bundles include self-hosted middleware archives and matching architecture; server startup never pulls images. Linux needs Docker/Podman, Docker Compose v2 or podman-compose 1.6.0+ (supports --pull never), sh, tar, sha256sum, awk, curl and filesystem/container permissions. Protect private bundle contents. Keep volume identities stable across versions. Verify actual offline startup, login, refresh, restart and persistence. HTTPS, certificates, DNS and external services need separate preparation.
|
|
152
96
|
|
|
153
|
-
|
|
154
|
-
|
|
97
|
+
### SDK
|
|
98
|
+
|
|
99
|
+
```ts
|
|
155
100
|
import { deploy } from '@h-ai/deploy'
|
|
156
101
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
finally {
|
|
175
|
-
await deploy.close()
|
|
176
|
-
}
|
|
102
|
+
const initialized = await deploy.init({ provider: { type: 'docker-ssh', expose: { hostPort: 18080 } } })
|
|
103
|
+
if (!initialized.success)
|
|
104
|
+
throw new Error(initialized.error.message)
|
|
105
|
+
try {
|
|
106
|
+
const result = await deploy.deployApp('./packages/demo-serv', {
|
|
107
|
+
environment: 'prod',
|
|
108
|
+
envDir: '.',
|
|
109
|
+
bundleOnly: true,
|
|
110
|
+
artifactDir: './.hai/build/docker/<buildId>',
|
|
111
|
+
runtime: 'auto',
|
|
112
|
+
})
|
|
113
|
+
if (!result.success)
|
|
114
|
+
throw new Error(result.error.message)
|
|
115
|
+
// result.data.bundlePath / instructions; packaged does not mean server ready.
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
await deploy.close()
|
|
177
119
|
}
|
|
178
120
|
```
|
|
179
121
|
|
|
180
|
-
|
|
122
|
+
`selectedServices: ['web']` selects a partial update. `onProgress` receives actual packaging/server stages. `deploy.scan` and `deploy.credentials.*` are available before init. Check HaiResult.success before using data. Vercel uploads existing .vercel/output through the prebuilt API and requires internet; it does not provide offline or Compose partial deployment.
|
|
181
123
|
|
|
182
|
-
|
|
124
|
+
## Development and testing
|
|
183
125
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
pnpm
|
|
190
|
-
pnpm
|
|
191
|
-
pnpm.cmd --filter @h-ai/deploy build
|
|
192
|
-
pnpm.cmd --filter @h-ai/deploy test
|
|
193
|
-
pnpm.cmd check:skills
|
|
126
|
+
```sh
|
|
127
|
+
pnpm --filter @h-ai/deploy typecheck
|
|
128
|
+
pnpm --filter @h-ai/deploy lint
|
|
129
|
+
pnpm --filter @h-ai/deploy build
|
|
130
|
+
pnpm --filter @h-ai/deploy test
|
|
131
|
+
pnpm --filter @h-ai/cli test:scaffold-gates
|
|
132
|
+
pnpm --filter @h-ai/cli test:deploy-gates
|
|
194
133
|
```
|
|
195
134
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
For deployment changes, also run CLI typecheck/lint/build/test and `pnpm.cmd --filter @h-ai/cli test:deploy-gates`: current package archives → generated fullstack → Podman/SSH → health, environment, login and repeat deployment. This needs a local engine and OpenSSH; first fixture setup downloads images and OS/Node dependencies, so it is not an offline acceptance test. Template changes also require `pnpm.cmd --filter @h-ai/cli test:scaffold-gates`. Unit tests do not prove cloud resource creation; validate paid cloud operations separately. Keep logs/screenshots/reports in Git-ignored `tmp/` or `test-results/`.
|
|
135
|
+
Run actual generated projects and SSH/manual deployment, including an isolated registry environment, incremental updates, damaged archives, same-version releases and failed health checks. Clean only test-owned projects, images, containers, logs and processes in finally/teardown.
|
|
199
136
|
|
|
200
137
|
## License
|
|
201
138
|
|