@h-ai/deploy 1.0.0-beta.16 → 1.0.0-beta.17
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 +2 -0
- package/README.ja.md +2 -0
- package/README.md +2 -0
- package/dist/deploy-runtime-env.mjs +13 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +64 -14
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.en.md
CHANGED
|
@@ -260,6 +260,8 @@ The deployment archive contains `apply.sh`, `APPLY.txt`, `manifest.json`, `confi
|
|
|
260
260
|
|
|
261
261
|
Node backends (Serv / SvelteKit SSR) read `<deployment-root>/config/.env.runtime` on every start. This single application file includes managed connections. Edit a field such as `HAI_STORAGE_PUBLICENDPOINT`, then restart the backend; fields override parent JSON within the same source. The configuration directory is mounted read-only at `/run/hai/config`, so atomic file replacement is visible on restart. Private proxy identity and Node startup options remain deployment settings. Static Web, native middleware environment, ports/mounts, and Nginx routes or limits require deployment. Web/middleware-only updates retain the file; partial backend updates preserve managed connections, while full updates use the new package with existing managed credentials. Back up edits and copy permanent settings into the source environment.
|
|
262
262
|
|
|
263
|
+
The outer `README.txt` and the archive’s `APPLY.txt` include the file index, environment precedence, names of variables in this bundle, and troubleshooting steps. The unpacked `config/.env.runtime` is release input, the deployment root holds the active file, and `releases/<ID>/` holds the release record. After rotating an external PostgreSQL password, update the project environment and deploy the backend. Packaging rejects conflicting URL and separate passwords. Use a full deployment to switch between external and bundled middleware.
|
|
264
|
+
|
|
263
265
|
Container packaging sets the listener to `0.0.0.0` and the port declared by the artifact, falling back to deployment settings when absent. It generates `HOST`, `PORT`, and the matching Serv fields. Loopback addresses and development ports in local `.env` files remain local settings. Update the artifact and deployment layout together when changing container ports.
|
|
264
266
|
|
|
265
267
|
Nginx dynamically tracks DNS changes for application and storage containers. The shared `.hai/proxy-start.sh` runs as an image entrypoint hook, preserves the image startup command, and reads resolvers from the container's `/etc/resolv.conf` and also watches certificate changes for HTTPS. Docker and Podman need no fixed DNS address. After editing runtime configuration and restarting the backend, the proxy reconnects automatically even if its IP changes.
|
package/README.ja.md
CHANGED
|
@@ -258,6 +258,8 @@ SSH 中断は最初に `remoteExecution: 'unknown'` とし、docker-ssh SDK は
|
|
|
258
258
|
|
|
259
259
|
Node バックエンド(Serv / SvelteKit SSR)は起動ごとに `<配備ディレクトリー>/config/.env.runtime` を読みます。管理接続も同じアプリ設定に統合します。`HAI_STORAGE_PUBLICENDPOINT` などを編集して再起動すると反映され、同じソースでは個別フィールドが親 JSON を上書きします。設定ディレクトリーを `/run/hai/config` に読み取り専用でマウントするため、ファイルのアトミック置換も次の起動で反映されます。非公開プロキシ識別と Node 起動引数は配備設定です。静的 Web、ネイティブ環境、ポート、マウント、Nginx の変更は再配備します。Web/ミドルウェアのみの更新は設定を維持し、バックエンドの部分更新は管理接続を維持、全量更新は新しい設定と既存の管理資格情報を使います。編集前にバックアップし、恒久的な値は元の環境にも反映してください。
|
|
260
260
|
|
|
261
|
+
外側の `README.txt` とアーカイブ内の `APPLY.txt` には、ファイル索引、環境設定の優先順位、今回の変数名、調査手順が含まれます。展開した `config/.env.runtime` は配備入力、配備ルートの同名ファイルは現在の実行設定、`releases/<ID>/` 内は配備記録です。外部 PostgreSQL のパスワード変更後はプロジェクトの環境設定を更新し、バックエンドを配備します。URL と個別項目のパスワードが競合する場合はパッケージ作成時に失敗します。外部と同梱の切り替えには全量配備が必要です。
|
|
262
|
+
|
|
261
263
|
コンテナーのパッケージ化では、待受アドレスを `0.0.0.0`、ポートを成果物の宣言値(未指定なら配置設定)として、`HOST`、`PORT` と Serv の対応フィールドを生成します。ローカル `.env` のループバックアドレスと開発ポートはローカル実行に使います。コンテナーポートの変更時は成果物と配置構成を更新して再配備してください。
|
|
262
264
|
|
|
263
265
|
Nginx はアプリとストレージのコンテナーの DNS 変更に動的に追従します。共通の `.hai/proxy-start.sh` はイメージの元の起動コマンドを維持する入口フックとして動作し、コンテナー内の `/etc/resolv.conf` からリゾルバーを読み、HTTPS では証明書更新も監視します。Docker と Podman の DNS アドレスを固定する必要はありません。実行時設定を編集してバックエンドを再起動した後、IP が変わってもプロキシは自動的に再接続します。
|
package/README.md
CHANGED
|
@@ -278,6 +278,8 @@ SSH 中断始终先记 `remoteExecution: 'unknown'`。docker-ssh SDK 用新连
|
|
|
278
278
|
|
|
279
279
|
Node 后端(Serv / SvelteKit SSR)每次启动读取服务器 `<部署目录>/config/.env.runtime`。应用配置与托管连接在此合并,修改 `HAI_STORAGE_PUBLICENDPOINT` 等细项后重启对应后端即可;同一来源的细项覆盖父 JSON。配置目录只读挂载到 `/run/hai/config`,编辑器原子替换文件也会被下一次启动读取。私有代理标记和 Node 启动参数由部署装配管理;静态 Web、中间件原生环境、端口/挂载、Nginx 路由与限额变更仍需部署。仅更新 Web/中间件保留当前应用配置;后端局部更新保留服务器托管连接,其余值来自新包,全量更新采用新包并按已有凭据状态定稿。手工修改先备份,长期配置同步回源环境。
|
|
280
280
|
|
|
281
|
+
每个部署包的外层 `README.txt` 和归档内 `APPLY.txt` 都包含文件索引、环境优先级、当前包的变量名和排障步骤。解包目录的 `config/.env.runtime` 是发布输入,部署根下的是当前运行配置,`releases/<ID>/` 下的是历史记录。外部 PostgreSQL 改密后更新项目源环境并发布后端。部署校验拒绝 URL 与分字段密码冲突,增量切换外部与随包中间件需要改用全量发布。
|
|
282
|
+
|
|
281
283
|
容器打包时,监听地址采用 `0.0.0.0`,端口采用制品声明值(未声明时采用部署配置),并生成 `HOST`、`PORT` 和 Serv 的对应细项。本机 `.env` 中的回环地址与开发端口继续用于本地运行。修改容器端口时更新制品与部署布局后重新部署。
|
|
282
284
|
|
|
283
285
|
Nginx 通过动态上游跟随应用和存储容器的 DNS 地址变化。共用的 `.hai/proxy-start.sh` 作为镜像入口钩子执行,保留镜像原有启动命令,并从容器 `/etc/resolv.conf` 读取解析器,HTTPS 时同时监视证书更新;Docker 与 Podman 均无需固定 DNS 地址。修改运行配置后重启后端,即使容器 IP 变化,代理也会自动恢复连接。
|
|
@@ -7,6 +7,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
7
7
|
import { parseEnv } from 'node:util'
|
|
8
8
|
|
|
9
9
|
const maximumBytes = 1024 * 1024
|
|
10
|
+
const refreshCookieSecure = 'HAI_SERV_REFRESH_COOKIE_SECURE'
|
|
10
11
|
|
|
11
12
|
/** 拒绝特殊文件、链接、超限与不可读文件,不输出秘密。 */
|
|
12
13
|
function readText(name) {
|
|
@@ -46,7 +47,7 @@ function readEnvironment(name) {
|
|
|
46
47
|
const text = readText(name)
|
|
47
48
|
const values = parseEnv(text)
|
|
48
49
|
const names = new Set()
|
|
49
|
-
for (const match of text.matchAll(/^(?:export\
|
|
50
|
+
for (const match of text.matchAll(/^[ \t]*(?:export[ \t]+)?([A-Z_]\w*)[ \t]*=[ \t]*('[^']*'|"(?:[^"\\]|\\.)*"|`[^`]*`|[^\r\n]*)/gim)) {
|
|
50
51
|
if (names.has(match[1]))
|
|
51
52
|
throw new Error('Duplicate environment variable')
|
|
52
53
|
names.add(match[1])
|
|
@@ -62,6 +63,13 @@ function readEnvironment(name) {
|
|
|
62
63
|
catch { throw new Error('Runtime environment file could not be parsed') }
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
/** 校验最终生效的独立进程开关,允许空值使用 Serv 默认策略。 */
|
|
67
|
+
function validateRefreshCookie(values) {
|
|
68
|
+
const value = values[refreshCookieSecure]
|
|
69
|
+
if (value && value !== 'true' && value !== 'false')
|
|
70
|
+
throw new Error(`Runtime environment file: ${refreshCookieSecure} must be true, false or empty`)
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
/** 清单只保存非敏感元数据,不把环境值放入错误消息。 */
|
|
66
74
|
function readManifest(name) {
|
|
67
75
|
if (name === '-')
|
|
@@ -159,6 +167,7 @@ function prepare(directory, previousManifest, previousEnvironment, credentialSta
|
|
|
159
167
|
if (state.PROJECT && project && state.PROJECT !== project.trim())
|
|
160
168
|
throw new Error('Managed middleware credential project mismatch')
|
|
161
169
|
applyManagedPasswords(next, bindings, state)
|
|
170
|
+
validateRefreshCookie(next)
|
|
162
171
|
incoming.metadata['managed-app-keys'] = `${keys.join('\n')}${keys.length ? '\n' : ''}`
|
|
163
172
|
incoming.metadata['managed-bindings'] = `${bindings}${bindings ? '\n' : ''}`
|
|
164
173
|
if (project)
|
|
@@ -183,10 +192,12 @@ else {
|
|
|
183
192
|
const inherited = Object.fromEntries(Object.entries(process.env).filter(([name, value]) => name.startsWith('HAI_') && value !== undefined))
|
|
184
193
|
for (const name of Object.keys(inherited).sort((left, right) => left.length - right.length)) {
|
|
185
194
|
for (const previous of Object.keys(values)) {
|
|
186
|
-
|
|
195
|
+
// 与 Core 来源合并保持一致:独立开关只允许同名变量覆盖。
|
|
196
|
+
if (previous !== refreshCookieSecure && previous.startsWith(`${name}_`))
|
|
187
197
|
delete values[previous]
|
|
188
198
|
}
|
|
189
199
|
values[name] = inherited[name]
|
|
190
200
|
}
|
|
201
|
+
validateRefreshCookie(values)
|
|
191
202
|
Object.assign(process.env, values)
|
|
192
203
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1072,7 +1072,7 @@ declare const deploy: DeployFunctions;
|
|
|
1072
1072
|
* const message = deployM('deploy_sshRequired')
|
|
1073
1073
|
* ```
|
|
1074
1074
|
*/
|
|
1075
|
-
declare const deployM: (key: "deploy_composeHostAddressInvalid" | "deploy_composeHostnameInvalid" | "deploy_composeHostnameConflict" | "deploy_composeProviderRequired" | "deploy_composeServiceUnavailable" | "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "deploy_uploadFailed" | "deploy_deployFailed" | "deploy_provisionFailed" | "deploy_adapterMissing" | "deploy_scanFailed" | "deploy_envVarFailed" | "deploy_credentialError" | "deploy_credentialInvalidKey" | "deploy_credentialSaved" | "deploy_credentialLoaded" | "deploy_configError" | "deploy_credentialMissing" | "deploy_apiError" | "deploy_fileUploadFailed" | "deploy_provisionNoResult" | "deploy_recoveryFailure" | "deploy_recoverySuggestion" | "deploy_commandTimeout" | "deploy_commandFailed" | "deploy_remoteConnectFailed" | "deploy_remoteRuntimeMissing" | "deploy_imageTransferFailed" | "deploy_healthCheckFailed" | "deploy_invalidEnvironment" | "deploy_environmentMissing" | "deploy_environmentReadFailed" | "deploy_environmentWriteFailed" | "deploy_multipleApplications" | "deploy_purposeSqlite" | "deploy_purposeDatabase" | "deploy_purposeMemory" | "deploy_purposeLocal" | "deploy_purposeCache" | "deploy_purposeStorage" | "deploy_purposeVector" | "deploy_purposeDisabled" | "deploy_purposeLdap" | "deploy_purposeConsole" | "deploy_purposeEmail" | "deploy_purposeSms" | "deploy_webProxyInvalid" | "deploy_webBaseConflict" | "deploy_storageProxyInvalid" | "deploy_storagePublicEndpointInvalid" | "deploy_storageBackendRequired" | "deploy_artifactInvalid" | "deploy_sshRequired" | "deploy_sshPasswordInvalid" | "deploy_sshAskpassFailed" | "deploy_sshAskpassCleanupFailed" | "deploy_targetAuth" | "deploy_targetPasswordEnv" | "deploy_bundleInstructions" | "deploy_bundleApplyGuide" | "deploy_bundleMetadata" | "deploy_targetHost" | "deploy_targetPort" | "deploy_targetUsername" | "deploy_targetIdentityFile" | "deploy_targetKnownHostsFile" | "deploy_targetStrictHostKeyChecking" | "deploy_targetConnectTimeoutSeconds" | "deploy_targetDirectory" | "deploy_targetBundle" | "deploy_bundleOnlyContainer" | "deploy_selectedContainerOnly" | "deploy_selectionInvalid" | "deploy_imageVersionRequired" | "deploy_bundleRuntimeRequired" | "deploy_bundleFailed" | "deploy_configFileInvalid" | "deploy_configFileUnreadable" | "deploy_bundleNameInvalid" | "deploy_localStopped" | "deploy_localUnknown" | "deploy_localNotStarted" | "deploy_commandOutputFailed" | "deploy_commandInputFailed" | "deploy_commandTreeActive" | "deploy_commandExecutionFailed" | "deploy_remoteUnknown" | "deploy_remoteFinished" | "deploy_bundleDirectoryExists" | "deploy_bundleFull" | "deploy_bundlePartial" | "deploy_bundleSelection" | "deploy_transportBodyLimitInvalid" | "deploy_transportKeyRingInvalid" | "deploy_uploadPasswordPrompt" | "deploy_uploadPasswordUnavailable" | "deploy_uploadPasswordCancelled" | "deploy_uploadPasswordInvalid" | "deploy_managedSecretsInvalid" | "deploy_secretImportFailed" | "deploy_projectNameRequired" | "deploy_projectNameOverrideRemoved" | "deploy_requestAccessInvalid" | "deploy_httpsPortsInvalid" | "deploy_httpsCertificateInvalid" | "deploy_bundleRuntime" | "deploy_bundleHttpOnly" | "deploy_bundleHttps" | "deploy_bundleAcme" | "deploy_bundleAccounts" | "deploy_bundleDirectories" | "deploy_downloadInvalid" | "deploy_imageSourceMissing" | "deploy_proxySystemUnsupported" | "deploy_middlewareFieldInvalid" | "deploy_middlewareFieldError" | "deploy_middlewareRequired" | "deploy_middlewareInteger" | "deploy_middlewareBoolean" | "deploy_middlewareUrl" | "deploy_middlewareS3Endpoint" | "deploy_middlewareTlsSyntax" | "deploy_middlewareMysqlTls" | "deploy_middlewarePostgresTls" | "deploy_middlewareHeaders" | "deploy_middlewareMethod" | "deploy_configResolutionFailed" | "deploy_reachEmptyProviderOverride" | "deploy_s3Engine", options?: _h_ai_core.MessageOptions) => string;
|
|
1075
|
+
declare const deployM: (key: "deploy_composeHostAddressInvalid" | "deploy_composeHostnameInvalid" | "deploy_composeHostnameConflict" | "deploy_composeProviderRequired" | "deploy_composeServiceUnavailable" | "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "deploy_uploadFailed" | "deploy_deployFailed" | "deploy_provisionFailed" | "deploy_adapterMissing" | "deploy_scanFailed" | "deploy_envVarFailed" | "deploy_credentialError" | "deploy_credentialInvalidKey" | "deploy_credentialSaved" | "deploy_credentialLoaded" | "deploy_configError" | "deploy_credentialMissing" | "deploy_apiError" | "deploy_fileUploadFailed" | "deploy_provisionNoResult" | "deploy_recoveryFailure" | "deploy_recoverySuggestion" | "deploy_commandTimeout" | "deploy_commandFailed" | "deploy_remoteConnectFailed" | "deploy_remoteRuntimeMissing" | "deploy_imageTransferFailed" | "deploy_healthCheckFailed" | "deploy_invalidEnvironment" | "deploy_environmentMissing" | "deploy_environmentReadFailed" | "deploy_environmentWriteFailed" | "deploy_multipleApplications" | "deploy_purposeSqlite" | "deploy_purposeDatabase" | "deploy_purposeMemory" | "deploy_purposeLocal" | "deploy_purposeCache" | "deploy_purposeStorage" | "deploy_purposeVector" | "deploy_purposeDisabled" | "deploy_purposeLdap" | "deploy_purposeConsole" | "deploy_purposeEmail" | "deploy_purposeSms" | "deploy_webProxyInvalid" | "deploy_webBaseConflict" | "deploy_storageProxyInvalid" | "deploy_storagePublicEndpointInvalid" | "deploy_storageBackendRequired" | "deploy_artifactInvalid" | "deploy_sshRequired" | "deploy_sshPasswordInvalid" | "deploy_sshAskpassFailed" | "deploy_sshAskpassCleanupFailed" | "deploy_targetAuth" | "deploy_targetPasswordEnv" | "deploy_bundleInstructions" | "deploy_bundleApplyGuide" | "deploy_bundleMetadata" | "deploy_targetHost" | "deploy_targetPort" | "deploy_targetUsername" | "deploy_targetIdentityFile" | "deploy_targetKnownHostsFile" | "deploy_targetStrictHostKeyChecking" | "deploy_targetConnectTimeoutSeconds" | "deploy_targetDirectory" | "deploy_targetBundle" | "deploy_bundleOnlyContainer" | "deploy_selectedContainerOnly" | "deploy_selectionInvalid" | "deploy_imageVersionRequired" | "deploy_bundleRuntimeRequired" | "deploy_bundleFailed" | "deploy_configFileInvalid" | "deploy_configFileUnreadable" | "deploy_bundleNameInvalid" | "deploy_localStopped" | "deploy_localUnknown" | "deploy_localNotStarted" | "deploy_commandOutputFailed" | "deploy_commandInputFailed" | "deploy_commandTreeActive" | "deploy_commandExecutionFailed" | "deploy_remoteUnknown" | "deploy_remoteFinished" | "deploy_bundleDirectoryExists" | "deploy_bundleFull" | "deploy_bundlePartial" | "deploy_bundleSelection" | "deploy_transportBodyLimitInvalid" | "deploy_transportKeyRingInvalid" | "deploy_uploadPasswordPrompt" | "deploy_uploadPasswordUnavailable" | "deploy_uploadPasswordCancelled" | "deploy_uploadPasswordInvalid" | "deploy_managedSecretsInvalid" | "deploy_secretImportFailed" | "deploy_projectNameRequired" | "deploy_projectNameOverrideRemoved" | "deploy_requestAccessInvalid" | "deploy_httpsPortsInvalid" | "deploy_httpsCertificateInvalid" | "deploy_bundleRuntime" | "deploy_refreshCookieSecureInvalid" | "deploy_postgresPasswordConflict" | "deploy_bundleVariables" | "deploy_bundleHttpOnly" | "deploy_bundleHttps" | "deploy_bundleAcme" | "deploy_bundleAccounts" | "deploy_bundleDirectories" | "deploy_downloadInvalid" | "deploy_imageSourceMissing" | "deploy_proxySystemUnsupported" | "deploy_middlewareFieldInvalid" | "deploy_middlewareFieldError" | "deploy_middlewareRequired" | "deploy_middlewareInteger" | "deploy_middlewareBoolean" | "deploy_middlewareUrl" | "deploy_middlewareS3Endpoint" | "deploy_middlewareTlsSyntax" | "deploy_middlewareMysqlTls" | "deploy_middlewarePostgresTls" | "deploy_middlewareHeaders" | "deploy_middlewareMethod" | "deploy_configResolutionFailed" | "deploy_reachEmptyProviderOverride" | "deploy_s3Engine", options?: _h_ai_core.MessageOptions) => string;
|
|
1076
1076
|
|
|
1077
1077
|
/**
|
|
1078
1078
|
* 部署中间件的后端与连接字段目录,供扫描、CLI 和容器规划共同使用。
|
package/dist/index.js
CHANGED
|
@@ -183,12 +183,15 @@ var en_US_default = {
|
|
|
183
183
|
deploy_requestAccessInvalid: "Invalid request access policy ({field}). Check fields, IP addresses, timezones and time windows. For a file reference, use readable YAML no larger than 1 MiB. Fix the configuration and create a new bundle.",
|
|
184
184
|
deploy_httpsPortsInvalid: "HTTP and HTTPS ports must differ; Let\u2019s Encrypt HTTP-01 requires host port 80.",
|
|
185
185
|
deploy_httpsCertificateInvalid: "Invalid HTTPS certificate. Check readable PEM files, matching unencrypted private key, validity dates and domain, then repackage.",
|
|
186
|
-
deploy_bundleRuntime: "
|
|
186
|
+
deploy_bundleRuntime: "Configuration files and activation\nconfig/.env.runtime in the unpacked bundle is this release's input. It contains application configuration and may include bundled middleware candidates. Change the project environment and rebuild the bundle. apply.sh verifies the unpacked content.\n{directory}/config/.env.runtime is the active configuration. Serv and SvelteKit SSR read it from the read-only /run/hai/config mount on each start.\nThe active file uses literal dotenv syntax and is limited to 1 MiB. Missing, unreadable, oversized, or duplicate assignments fail before startup.\n{directory}/releases/{deploymentId}/config/.env.runtime records this release. Updates that only select Web or middleware copy the configuration active at the time. Inspect the root file for the active value and the matching release for a historical value.\nA full deployment uses the new bundle configuration and reuses stored managed credentials. A partial update of the primary application takes external connections and application settings from the new bundle and keeps existing managed connections. A partial update that excludes the primary application keeps the active configuration. Switching between bundled and external middleware requires a full deployment.\nFor a temporary Node backend fix, back up and edit the active file, run docker restart <container> or podman restart <container>, and verify health and the affected feature. Put lasting changes in the project environment so the next backend release carries them. An explicit HAI_* value in the container process takes precedence.\nRedeploy changes to static Web or native middleware environments, ports, mounts, Node options, Nginx routes or limits, and HTTPS assembly. A website base path change also requires a rebuild.\nRecovery restores the active application file before restarting previous services. The database maintenance procedure handles password and data changes already made inside the database.",
|
|
187
|
+
deploy_refreshCookieSecureInvalid: "HAI_SERV_REFRESH_COOKIE_SECURE must be true, false, or empty. Check the selected environment and packaging process for this variable.",
|
|
188
|
+
deploy_postgresPasswordConflict: "External PostgreSQL has different passwords in HAI_DB_URL (or HAI_DB.url) and HAI_DB_PASSWORD (or HAI_DB.password). Use a complete URL or separate connection fields.",
|
|
189
|
+
deploy_bundleVariables: "Environment variables and troubleshooting (names only)\nTarget environment: {environment}. Packaging priority, highest first: packaging process, .env.{environment}.local, .env.local, .env.{environment}, .env, and application YAML defaults. --env-dir selects the source directory. A field overrides its parent JSON in the same source. Higher-priority parent JSON replaces older structured fields.\nNames in this bundle's config/.env.runtime (--plan lists source input names): {keys}\nHAI_SERV_REFRESH_COOKIE_SECURE is a standalone process flag. Only the same name overrides it. true enables Secure, false is for controlled intranet or VPN HTTP access, and empty or absent uses the Serv environment default (enabled in production). Set HAI_SERV_CORS_ORIGIN to the actual HTTP origin. Verify login and refresh after deployment.\nExample for controlled HTTP: set HAI_SERV_REFRESH_COOKIE_SECURE=false in .env.{environment}.local and configure the actual CORS origin. With a successful full deployment and a serv image artifact, run pnpm run deploy --env {environment} --bundle-only --yes --services serv from the project. Unpack on the server and run sh ./apply.sh.\nExternal PostgreSQL uses HAI_DB_URL (a complete connection string with required authentication) or HAI_DB_HOST, HAI_DB_PORT, HAI_DB_USER, HAI_DB_DATABASE, and HAI_DB_PASSWORD. A URL takes precedence. Update the effective form when changing credentials. After updating the database account and the source environment, deploy serv or a full bundle.\nHAI_CACHE_*, HAI_STORAGE_*, HAI_VECDB_*, and HAI_IAM_LDAP_* configure application connections. S3 uses separate endpoint and access credentials. External or cloud-provisioned services normally have no native container variables in this bundle.\nFor bundled PostgreSQL, DB_PASSWORD in managed-secrets.env supplies HAI_DB_URL for the application and POSTGRES_PASSWORD for the image. POSTGRES_PASSWORD initializes an empty data directory. Other bundled images may use MYSQL_*, RUSTFS_*, MINIO_*, or LDAP_*. Rotate existing-volume credentials in both the actual account and managed state. A container restart or recreation alone cannot rotate a database password.\nNODE_ENV selects the application environment. The delivery topology determines listen settings in HOST, PORT, and HAI_SERV_SERVER_*. NODE_OPTIONS and HAI_DEPLOY_PRIVATE_PROXY come from container assembly. HAI_DEPLOY_PROVIDER_SSH_PASSWORD is used by the uploader for SSH.\nProtect the archive, runtime configuration, credentials, private keys, and failure logs. When sharing with operators or AI, use variable names, sources, redacted errors, and the deployment ID.",
|
|
187
190
|
deploy_bundleHttpOnly: "HTTPS: disabled. This bundle exposes HTTP port {port}, contains no certificate attachment and will not request a certificate on the server.",
|
|
188
191
|
deploy_bundleHttps: "HTTPS: enabled, https://{domain}:{port}; mode {mode}.\nServer certificate: {certificates}/fullchain.pem; private key: {certificates}/privkey.pem. Mounted read-only at /etc/nginx/tls/.\nEdit expose.https in HAI_DEPLOY_PROVIDER in the packaging environment .env.{environment}.local, or the unshadowed hai.json.deploy.provider.expose.https. Enable/disable, mode, domain or port changes require a new full bundle; editing .env.runtime and restarting does not issue a certificate for a new domain.",
|
|
189
192
|
deploy_bundleAcme: "Persistent Certbot state: {state}; current certificate entry: {state}/live/{domain}. Packaging does not contact the CA; issuance runs during server deployment, followed by automatic renewal. Public port 80 and root /.well-known/acme-challenge/ must remain reachable independently of the business context path.",
|
|
190
193
|
deploy_bundleAccounts: "Initial account variables (names and sources only; passwords omitted):\n{sources}\nApplications with matching bootstrap logic use HAI_CONFIG_ADMIN_PASSWORD to create the config_admin configuration administrator. HAI_ADMIN_DEFAULT_PASSWORD, HAI_AUDIT_ADMIN_PASSWORD and HAI_BUSINESS_OPERATOR_PASSWORD belong to the other template roles.\nFullstack creation generates independent initial passwords per environment. Packaging reads the selected environment and process overrides; server deployment does not generate new application account passwords. Startup creates missing configured accounts; changing variables does not reset existing passwords or restore old roles. Custom applications without this bootstrap follow their own implementation.",
|
|
191
|
-
deploy_bundleDirectories: "
|
|
194
|
+
deploy_bundleDirectories: "File index (server paths use the actual deployment root, default {directory})\nDelivery README.txt gives an overview. deploy.sh and deploy.ps1 upload and apply over SSH. deploy-target.json selects the target, authentication, and directory. read-target.awk reads that file for scripts. deploy-local.sh unpacks and applies on the server.\nIn the archive, APPLY.txt describes manual deployment and configuration. apply.sh verifies, locks, imports, and starts services. manifest.json records artifacts, mode, selected services, and non-secret metadata. images/ carries OCI archives for import into the engine.\nThe archive's .hai/compose.json contains selected services. The installed copy is the complete merged snapshot. .hai/SHA256SUMS checks the original unpacked files. Server copies can change during configuration finalization and merge.\nCompose uses .hai/middleware-runtime.env for bundled containers. The file can be empty when no native settings are needed. Retained services may refer to an older release, so follow env_file in the effective Compose snapshot. apply.sh consumes .hai/managed-candidates.env for first-install candidates.\n.hai/runtime-env.mjs loads and finalizes the Node environment. Optional files include .hai/request-access.yml, .hai/web.conf, proxy scripts, and .hai/tls/ for access policies, reverse proxying, and HTTPS.\nServer incoming/ holds this upload and unpacked files. releases/ holds deployment and recovery records. Protect and back up managed-secrets.env, persistent-backends, and data volumes together. .deploy.lock coordinates deployment and credential operations.\ncurrent updates after server health checks pass. result-{deploymentId}.json records the outcome and recovery state, steps-{deploymentId}.jsonl records progress, and diagnostics-{deploymentId}.log contains private startup diagnostics on failure. Check active Compose references, mounts, and recovery needs before pruning old releases.",
|
|
192
195
|
deploy_downloadInvalid: "Invalid download source or proxy configuration. URLs must not contain credentials or query parameters.",
|
|
193
196
|
deploy_imageSourceMissing: "Custom image source has no mapping for registry: {registry}",
|
|
194
197
|
deploy_proxySystemUnsupported: "Static system proxy is unavailable, or only PAC/auto-discovery is configured. Use inherit with environment variables or a custom HTTP(S) URL.",
|
|
@@ -323,12 +326,15 @@ var ja_JP_default = {
|
|
|
323
326
|
deploy_requestAccessInvalid: "\u30EA\u30AF\u30A8\u30B9\u30C8\u30A2\u30AF\u30BB\u30B9\u8A2D\u5B9A\uFF08{field}\uFF09\u304C\u7121\u52B9\u3067\u3059\u3002\u30D5\u30A3\u30FC\u30EB\u30C9\u3001IP\u3001\u30BF\u30A4\u30E0\u30BE\u30FC\u30F3\u3001\u6642\u9593\u5E2F\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30D5\u30A1\u30A4\u30EB\u306F\u8AAD\u307F\u53D6\u308A\u53EF\u80FD\u306A 1 MiB \u4EE5\u4E0B\u306E YAML \u3092\u6307\u5B9A\u3057\u3001\u4FEE\u6B63\u5F8C\u306B\u518D\u30D1\u30C3\u30B1\u30FC\u30B8\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
324
327
|
deploy_httpsPortsInvalid: "HTTP \u3068 HTTPS \u306E\u30DD\u30FC\u30C8\u306F\u7570\u306A\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002Let\u2019s Encrypt HTTP-01 \u306B\u306F\u30DB\u30B9\u30C8\u306E\u30DD\u30FC\u30C8 80 \u304C\u5FC5\u8981\u3067\u3059\u3002",
|
|
325
328
|
deploy_httpsCertificateInvalid: "HTTPS \u8A3C\u660E\u66F8\u304C\u7121\u52B9\u3067\u3059\u3002PEM \u30D5\u30A1\u30A4\u30EB\u3001\u6697\u53F7\u5316\u3055\u308C\u3066\u3044\u306A\u3044\u79D8\u5BC6\u9375\u3068\u306E\u4E00\u81F4\u3001\u6709\u52B9\u671F\u9593\u3001\u30C9\u30E1\u30A4\u30F3\u3092\u78BA\u8A8D\u3057\u3001\u518D\u4F5C\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
326
|
-
deploy_bundleRuntime: "\
|
|
329
|
+
deploy_bundleRuntime: "\u8A2D\u5B9A\u30D5\u30A1\u30A4\u30EB\u3068\u53CD\u6620\u306E\u30BF\u30A4\u30DF\u30F3\u30B0\n\u5C55\u958B\u5148\u306E config/.env.runtime \u306F\u4ECA\u56DE\u306E\u914D\u5099\u5165\u529B\u3067\u3059\u3002\u30A2\u30D7\u30EA\u8A2D\u5B9A\u3068\u540C\u68B1\u30DF\u30C9\u30EB\u30A6\u30A7\u30A2\u306E\u5019\u88DC\u5024\u304C\u542B\u307E\u308C\u307E\u3059\u3002\u5909\u66F4\u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u74B0\u5883\u8A2D\u5B9A\u306B\u53CD\u6620\u3057\u3066\u518D\u30D1\u30C3\u30B1\u30FC\u30B8\u5316\u3057\u3066\u304F\u3060\u3055\u3044\u3002apply.sh \u304C\u5C55\u958B\u5185\u5BB9\u3092\u691C\u8A3C\u3057\u307E\u3059\u3002\n{directory}/config/.env.runtime \u306F\u73FE\u5728\u306E\u5B9F\u884C\u8A2D\u5B9A\u3067\u3059\u3002Serv \u3068 SvelteKit SSR \u306F\u8D77\u52D5\u3054\u3068\u306B\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u306E /run/hai/config \u30DE\u30A6\u30F3\u30C8\u304B\u3089\u8AAD\u307F\u8FBC\u307F\u307E\u3059\u3002\n\u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u306F dotenv \u306E\u30EA\u30C6\u30E9\u30EB\u69CB\u6587\u3092\u4F7F\u7528\u3057\u3001\u4E0A\u9650\u306F 1 MiB \u3067\u3059\u3002\u6B20\u843D\u3001\u8AAD\u307F\u53D6\u308A\u4E0D\u80FD\u3001\u91CD\u8907\u5B9A\u7FA9\u3001\u4E0A\u9650\u8D85\u904E\u306F\u30A2\u30D7\u30EA\u8D77\u52D5\u524D\u306B\u30A8\u30E9\u30FC\u306B\u306A\u308A\u307E\u3059\u3002\n{directory}/releases/{deploymentId}/config/.env.runtime \u306F\u4ECA\u56DE\u306E\u914D\u5099\u8A18\u9332\u3067\u3059\u3002Web \u307E\u305F\u306F\u30DF\u30C9\u30EB\u30A6\u30A7\u30A2\u306E\u307F\u66F4\u65B0\u3059\u308B\u5834\u5408\u306F\u5F53\u6642\u306E\u5B9F\u884C\u8A2D\u5B9A\u3092\u8A18\u9332\u3057\u307E\u3059\u3002\u73FE\u5728\u5024\u306F\u30EB\u30FC\u30C8\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u3001\u904E\u53BB\u306E\u5024\u306F\u8A72\u5F53\u3059\u308B release \u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u5168\u91CF\u914D\u5099\u3067\u306F\u65B0\u3057\u3044\u30A2\u30D7\u30EA\u8A2D\u5B9A\u3068\u65E2\u5B58\u306E\u7BA1\u7406\u8CC7\u683C\u60C5\u5831\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u4E3B\u30A2\u30D7\u30EA\u3092\u542B\u3080\u90E8\u5206\u66F4\u65B0\u3067\u306F\u65B0\u3057\u3044\u30A2\u30D7\u30EA\u8A2D\u5B9A\u3068\u5916\u90E8\u63A5\u7D9A\u3092\u9069\u7528\u3057\u3001\u65E2\u5B58\u306E\u7BA1\u7406\u63A5\u7D9A\u3092\u7DAD\u6301\u3057\u307E\u3059\u3002\u4E3B\u30A2\u30D7\u30EA\u3092\u542B\u307E\u306A\u3044\u90E8\u5206\u66F4\u65B0\u3067\u306F\u73FE\u5728\u306E\u8A2D\u5B9A\u3092\u7DAD\u6301\u3057\u307E\u3059\u3002\u5916\u90E8\u3068\u540C\u68B1\u306E\u5207\u308A\u66FF\u3048\u306B\u306F\u5168\u91CF\u914D\u5099\u304C\u5FC5\u8981\u3067\u3059\u3002\nNode \u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u306E\u4E00\u6642\u4FEE\u6B63\u3067\u306F\u3001\u73FE\u5728\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u3066\u7DE8\u96C6\u3057\u3001docker restart <\u30B3\u30F3\u30C6\u30CA\u30FC> \u307E\u305F\u306F podman restart <\u30B3\u30F3\u30C6\u30CA\u30FC> \u3092\u5B9F\u884C\u3057\u3066\u3001\u30D8\u30EB\u30B9\u3068\u5BFE\u8C61\u6A5F\u80FD\u3092\u78BA\u8A8D\u3057\u307E\u3059\u3002\u7D99\u7D9A\u3059\u308B\u5909\u66F4\u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u74B0\u5883\u8A2D\u5B9A\u306B\u3082\u53CD\u6620\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u30B3\u30F3\u30C6\u30CA\u30FC\u30D7\u30ED\u30BB\u30B9\u306B\u660E\u793A\u3057\u305F\u540C\u540D\u306E HAI_* \u304C\u512A\u5148\u3055\u308C\u307E\u3059\u3002\n\u9759\u7684 Web\u3001\u30DF\u30C9\u30EB\u30A6\u30A7\u30A2\u56FA\u6709\u306E\u74B0\u5883\u5909\u6570\u3001\u30DD\u30FC\u30C8\u3001\u30DE\u30A6\u30F3\u30C8\u3001Node \u8D77\u52D5\u5F15\u6570\u3001Nginx \u306E\u30EB\u30FC\u30C8\u3084\u5236\u9650\u3001HTTPS \u306E\u5909\u66F4\u306F\u518D\u914D\u5099\u3057\u307E\u3059\u3002\u30B5\u30A4\u30C8\u306E base \u30D1\u30B9\u5909\u66F4\u306B\u306F\u518D\u30D3\u30EB\u30C9\u3082\u5FC5\u8981\u3067\u3059\u3002\n\u969C\u5BB3\u5FA9\u65E7\u3067\u306F\u5B9F\u884C\u8A2D\u5B9A\u3092\u5148\u306B\u623B\u3057\u3001\u4EE5\u524D\u306E\u30B5\u30FC\u30D3\u30B9\u3092\u5FA9\u5143\u3057\u307E\u3059\u3002\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u5185\u3067\u5B9F\u884C\u6E08\u307F\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u3084\u30C7\u30FC\u30BF\u306E\u5909\u66F4\u306F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306E\u4FDD\u5B88\u624B\u9806\u3067\u6271\u3044\u307E\u3059\u3002",
|
|
330
|
+
deploy_refreshCookieSecureInvalid: "HAI_SERV_REFRESH_COOKIE_SECURE \u306B\u306F true\u3001false\u3001\u307E\u305F\u306F\u7A7A\u5024\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5BFE\u8C61\u74B0\u5883\u3068\u30D1\u30C3\u30B1\u30FC\u30B8\u4F5C\u6210\u30D7\u30ED\u30BB\u30B9\u306E\u540C\u540D\u5909\u6570\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
331
|
+
deploy_postgresPasswordConflict: "\u5916\u90E8 PostgreSQL \u306E HAI_DB_URL\uFF08\u307E\u305F\u306F HAI_DB.url\uFF09\u3068 HAI_DB_PASSWORD\uFF08\u307E\u305F\u306F HAI_DB.password\uFF09\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093\u3002\u5B8C\u5168\u306A\u63A5\u7D9A URL \u307E\u305F\u306F\u500B\u5225\u9805\u76EE\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
332
|
+
deploy_bundleVariables: "\u74B0\u5883\u5909\u6570\u3068\u8ABF\u67FB\uFF08\u540D\u524D\u306E\u307F\uFF09\n\u5BFE\u8C61\u74B0\u5883\u306F {environment} \u3067\u3059\u3002\u4F5C\u6210\u6642\u306E\u512A\u5148\u9806\u306F\u30D7\u30ED\u30BB\u30B9\u3001.env.{environment}.local\u3001.env.local\u3001.env.{environment}\u3001.env\u3001\u30A2\u30D7\u30EA YAML \u306E\u65E2\u5B9A\u5024\u3067\u3059\u3002--env-dir \u3067\u8AAD\u307F\u53D6\u308A\u5148\u3092\u9078\u3073\u307E\u3059\u3002\u540C\u3058\u30BD\u30FC\u30B9\u3067\u306F\u500B\u5225\u9805\u76EE\u304C\u89AA JSON \u3088\u308A\u512A\u5148\u3055\u308C\u3001\u4E0A\u4F4D\u306E\u89AA JSON \u306F\u4E0B\u4F4D\u306E\u69CB\u9020\u9805\u76EE\u3092\u7F6E\u304D\u63DB\u3048\u307E\u3059\u3002\n\u540C\u68B1\u306E config/.env.runtime \u306B\u542B\u307E\u308C\u308B\u5909\u6570\u540D\uFF08--plan \u306F\u5165\u529B\u5074\u306E\u540D\u524D\u3092\u8868\u793A\uFF09: {keys}\nHAI_SERV_REFRESH_COOKIE_SECURE \u306F\u72EC\u7ACB\u3057\u305F\u30D7\u30ED\u30BB\u30B9\u5909\u6570\u3067\u3001\u540C\u540D\u306E\u5024\u306E\u307F\u3067\u4E0A\u66F8\u304D\u3057\u307E\u3059\u3002true \u306F Secure \u3092\u6709\u52B9\u306B\u3057\u3001false \u306F\u7BA1\u7406\u3055\u308C\u305F\u30A4\u30F3\u30C8\u30E9\u30CD\u30C3\u30C8\u307E\u305F\u306F VPN \u306E HTTP \u7528\u3067\u3059\u3002\u7A7A\u5024\u3068\u672A\u8A2D\u5B9A\u306F Serv \u74B0\u5883\u306E\u65E2\u5B9A\u5024\uFF08\u672C\u756A\u3067\u306F\u6709\u52B9\uFF09\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u5B9F\u969B\u306E HTTP \u30AA\u30EA\u30B8\u30F3\u3092 HAI_SERV_CORS_ORIGIN \u306B\u8A2D\u5B9A\u3057\u3001\u914D\u5099\u5F8C\u306B\u30ED\u30B0\u30A4\u30F3\u3068\u66F4\u65B0\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u7BA1\u7406\u3055\u308C\u305F HTTP \u306E\u4F8B\u3067\u306F\u3001.env.{environment}.local \u306B HAI_SERV_REFRESH_COOKIE_SECURE=false \u3068\u5B9F\u969B\u306E CORS \u30AA\u30EA\u30B8\u30F3\u3092\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u5168\u91CF\u914D\u5099\u304C\u6210\u529F\u6E08\u307F\u3067 serv \u30A4\u30E1\u30FC\u30B8\u6210\u679C\u7269\u304C\u3042\u308B\u5834\u5408\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3067 pnpm run deploy --env {environment} --bundle-only --yes --services serv \u3092\u5B9F\u884C\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u3067\u5C55\u958B\u3057\u3066 sh ./apply.sh \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u5916\u90E8 PostgreSQL \u306F\u8A8D\u8A3C\u3092\u542B\u3080\u5B8C\u5168\u306A HAI_DB_URL\u3001\u307E\u305F\u306F HAI_DB_HOST\u3001HAI_DB_PORT\u3001HAI_DB_USER\u3001HAI_DB_DATABASE\u3001HAI_DB_PASSWORD \u3092\u4F7F\u7528\u3057\u307E\u3059\u3002URL \u304C\u512A\u5148\u3055\u308C\u307E\u3059\u3002\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u3068\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u74B0\u5883\u306E\u6709\u52B9\u306A\u8A2D\u5B9A\u3092\u66F4\u65B0\u3057\u3001serv \u307E\u305F\u306F\u5168\u91CF\u3092\u914D\u5099\u3057\u3066\u304F\u3060\u3055\u3044\u3002\nHAI_CACHE_*\u3001HAI_STORAGE_*\u3001HAI_VECDB_*\u3001HAI_IAM_LDAP_* \u306F\u30A2\u30D7\u30EA\u63A5\u7D9A\u7528\u3067\u3059\u3002S3 \u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3068\u30A2\u30AF\u30BB\u30B9\u30AD\u30FC\u306F\u500B\u5225\u306B\u8A2D\u5B9A\u3057\u307E\u3059\u3002\u5916\u90E8\u304A\u3088\u3073\u30AF\u30E9\u30A6\u30C9\u4E0A\u306E\u30B5\u30FC\u30D3\u30B9\u306B\u306F\u3001\u901A\u5E38\u3053\u306E\u30D0\u30F3\u30C9\u30EB\u306E\u30B3\u30F3\u30C6\u30CA\u30FC\u56FA\u6709\u5909\u6570\u306F\u3042\u308A\u307E\u305B\u3093\u3002\n\u540C\u68B1 PostgreSQL \u3067\u306F managed-secrets.env \u306E DB_PASSWORD \u304B\u3089\u30A2\u30D7\u30EA\u7528\u306E HAI_DB_URL \u3068\u30A4\u30E1\u30FC\u30B8\u7528\u306E POSTGRES_PASSWORD \u3092\u751F\u6210\u3057\u307E\u3059\u3002POSTGRES_PASSWORD \u306F\u7A7A\u306E\u30C7\u30FC\u30BF\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30FC\u3092\u521D\u671F\u5316\u3057\u307E\u3059\u3002\u4ED6\u306E\u540C\u68B1\u30A4\u30E1\u30FC\u30B8\u3067\u306F MYSQL_*\u3001RUSTFS_*\u3001MINIO_*\u3001LDAP_* \u304C\u4F7F\u308F\u308C\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u65E2\u5B58\u30DC\u30EA\u30E5\u30FC\u30E0\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u5909\u66F4\u306F\u5B9F\u969B\u306E\u30A2\u30AB\u30A6\u30F3\u30C8\u3068\u7BA1\u7406\u72B6\u614B\u3092\u540C\u671F\u3057\u307E\u3059\u3002\nNODE_ENV \u306F\u30A2\u30D7\u30EA\u306E\u5B9F\u884C\u74B0\u5883\u3067\u3059\u3002HOST\u3001PORT\u3001HAI_SERV_SERVER_* \u306E\u5F85\u53D7\u8A2D\u5B9A\u306F\u914D\u5099\u6642\u306B\u78BA\u5B9A\u3057\u307E\u3059\u3002NODE_OPTIONS \u3068 HAI_DEPLOY_PRIVATE_PROXY \u306F\u30B3\u30F3\u30C6\u30CA\u30FC\u306E\u69CB\u6210\u3067\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HAI_DEPLOY_PROVIDER_SSH_PASSWORD \u306F\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u5074\u306E SSH \u7528\u3067\u3059\u3002\n\u30A2\u30FC\u30AB\u30A4\u30D6\u3001\u5B9F\u884C\u8A2D\u5B9A\u3001\u8CC7\u683C\u60C5\u5831\u3001\u79D8\u5BC6\u9375\u3001\u969C\u5BB3\u30ED\u30B0\u306F\u975E\u516C\u958B\u3067\u4FDD\u7BA1\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u904B\u7528\u62C5\u5F53\u8005\u3084 AI \u3068\u5171\u6709\u3059\u308B\u969B\u306F\u5909\u6570\u540D\u3001\u53D6\u5F97\u5143\u3001\u79D8\u533F\u5316\u6E08\u307F\u306E\u30A8\u30E9\u30FC\u3001\u914D\u5099 ID \u306E\u307F\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
327
333
|
deploy_bundleHttpOnly: "HTTPS\uFF1A\u7121\u52B9\u3002HTTP \u30DD\u30FC\u30C8 {port} \u306E\u307F\u3092\u516C\u958B\u3057\u3001\u8A3C\u660E\u66F8\u306F\u540C\u68B1\u305B\u305A\u3001\u30B5\u30FC\u30D0\u30FC\u3067\u3082\u7533\u8ACB\u3057\u307E\u305B\u3093\u3002",
|
|
328
334
|
deploy_bundleHttps: "HTTPS\uFF1A\u6709\u52B9\u3001https://{domain}:{port}\u3001\u30E2\u30FC\u30C9 {mode}\u3002\n\u30B5\u30FC\u30D0\u30FC\u8A3C\u660E\u66F8\uFF1A{certificates}/fullchain.pem\u3001\u79D8\u5BC6\u9375\uFF1A{certificates}/privkey.pem\u3002\u30B3\u30F3\u30C6\u30CA\u306E /etc/nginx/tls/ \u306B\u8AAD\u307F\u53D6\u308A\u5C02\u7528\u3067\u30DE\u30A6\u30F3\u30C8\u3057\u307E\u3059\u3002\n\u914D\u5E03\u5143 .env.{environment}.local \u306E HAI_DEPLOY_PROVIDER \u5185 expose.https\u3001\u307E\u305F\u306F\u4E0A\u66F8\u304D\u3055\u308C\u3066\u3044\u306A\u3044 hai.json.deploy.provider.expose.https \u3092\u7DE8\u96C6\u3057\u307E\u3059\u3002\u6709\u52B9/\u7121\u52B9\u3001\u30E2\u30FC\u30C9\u3001\u30C9\u30E1\u30A4\u30F3\u3001\u30DD\u30FC\u30C8\u5909\u66F4\u306F\u65B0\u3057\u3044\u5168\u91CF\u914D\u5099\u304C\u5FC5\u8981\u3067\u3059\u3002.env.runtime \u306E\u7DE8\u96C6\u3068\u518D\u8D77\u52D5\u3067\u306F\u65B0\u30C9\u30E1\u30A4\u30F3\u306E\u8A3C\u660E\u66F8\u3092\u7533\u8ACB\u3057\u307E\u305B\u3093\u3002",
|
|
329
335
|
deploy_bundleAcme: "Certbot \u6C38\u7D9A\u72B6\u614B\uFF1A{state}\u3001\u73FE\u5728\u306E\u8A3C\u660E\u66F8\u5165\u53E3\uFF1A{state}/live/{domain}\u3002\u30D1\u30C3\u30B1\u30FC\u30B8\u6642\u306F CA \u306B\u63A5\u7D9A\u305B\u305A\u3001\u30B5\u30FC\u30D0\u30FC\u914D\u5099\u6642\u306B\u7533\u8ACB\u3057\u3001\u305D\u306E\u5F8C\u81EA\u52D5\u66F4\u65B0\u3057\u307E\u3059\u3002\u516C\u958B\u30DD\u30FC\u30C8 80 \u3068\u30EB\u30FC\u30C8 /.well-known/acme-challenge/ \u306F\u696D\u52D9 context path \u3068\u5225\u306B\u5230\u9054\u53EF\u80FD\u306B\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
330
336
|
deploy_bundleAccounts: "\u521D\u671F\u30A2\u30AB\u30A6\u30F3\u30C8\u5909\u6570\uFF08\u540D\u524D\u3068\u53D6\u5F97\u5143\u306E\u307F\u3001\u30D1\u30B9\u30EF\u30FC\u30C9\u975E\u8868\u793A\uFF09\uFF1A\n{sources}\n\u5BFE\u5FDC\u3059\u308B\u521D\u671F\u5316\u3092\u6301\u3064\u30A2\u30D7\u30EA\u3067\u306F HAI_CONFIG_ADMIN_PASSWORD \u304C config_admin \u8A2D\u5B9A\u7BA1\u7406\u8005\u3092\u4F5C\u6210\u3057\u307E\u3059\u3002HAI_ADMIN_DEFAULT_PASSWORD\u3001HAI_AUDIT_ADMIN_PASSWORD\u3001HAI_BUSINESS_OPERATOR_PASSWORD \u306F\u4ED6\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u5F79\u5272\u306B\u5BFE\u5FDC\u3057\u307E\u3059\u3002\nFullstack \u4F5C\u6210\u6642\u306B\u74B0\u5883\u3054\u3068\u306E\u72EC\u7ACB\u521D\u671F\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u751F\u6210\u3057\u3001\u914D\u5E03\u6642\u306F\u9078\u629E\u74B0\u5883\u3068\u30D7\u30ED\u30BB\u30B9\u4E0A\u66F8\u304D\u3092\u8AAD\u307F\u307E\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u914D\u5099\u3067\u65B0\u305F\u306B\u751F\u6210\u3057\u307E\u305B\u3093\u3002\u8A2D\u5B9A\u304C\u3042\u308B\u672A\u4F5C\u6210\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u8D77\u52D5\u6642\u306B\u4F5C\u308A\u3001\u65E2\u5B58\u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u3084\u5909\u66F4\u5F8C\u306E\u5F79\u5272\u306F\u5909\u6570\u5909\u66F4\u3067\u623B\u3057\u307E\u305B\u3093\u3002\u72EC\u81EA\u30A2\u30D7\u30EA\u306F\u5B9F\u88C5\u306B\u5F93\u3044\u307E\u3059\u3002",
|
|
331
|
-
deploy_bundleDirectories: "\u30B5\u30FC\u30D0\u30FC\
|
|
337
|
+
deploy_bundleDirectories: "\u30D5\u30A1\u30A4\u30EB\u7D22\u5F15\uFF08\u30B5\u30FC\u30D0\u30FC\u30D1\u30B9\u306F\u5B9F\u969B\u306E\u914D\u5099\u30EB\u30FC\u30C8\u57FA\u6E96\u3001\u65E2\u5B9A\u5024\u306F {directory}\uFF09\n\u4EA4\u4ED8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30FC\u306E README.txt \u306F\u6982\u8981\u3067\u3059\u3002deploy.sh \u3068 deploy.ps1 \u306F SSH \u3067\u8EE2\u9001\u3057\u3066\u9069\u7528\u3057\u307E\u3059\u3002deploy-target.json \u306F\u63A5\u7D9A\u5148\u3001\u8A8D\u8A3C\u3001\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u30FC\u3092\u6307\u5B9A\u3057\u3001read-target.awk \u306F\u30B9\u30AF\u30EA\u30D7\u30C8\u7528\u306E\u8AAD\u307F\u53D6\u308A\u51E6\u7406\u3067\u3059\u3002deploy-local.sh \u306F\u30B5\u30FC\u30D0\u30FC\u4E0A\u3067\u5C55\u958B\u3057\u3066\u9069\u7528\u3057\u307E\u3059\u3002\n\u30A2\u30FC\u30AB\u30A4\u30D6\u306E APPLY.txt \u306F\u624B\u52D5\u64CD\u4F5C\u3068\u8A2D\u5B9A\u306E\u8AAC\u660E\u3067\u3059\u3002apply.sh \u306F\u691C\u8A3C\u3001\u30ED\u30C3\u30AF\u3001\u30A4\u30F3\u30DD\u30FC\u30C8\u3001\u8D77\u52D5\u3092\u5B9F\u884C\u3057\u307E\u3059\u3002manifest.json \u306F\u6210\u679C\u7269\u3001\u914D\u5099\u30E2\u30FC\u30C9\u3001\u5BFE\u8C61\u30B5\u30FC\u30D3\u30B9\u3001\u975E\u6A5F\u5BC6\u30E1\u30BF\u30C7\u30FC\u30BF\u3092\u8A18\u9332\u3057\u307E\u3059\u3002images/ \u306E OCI \u30A2\u30FC\u30AB\u30A4\u30D6\u3092\u30A8\u30F3\u30B8\u30F3\u306B\u53D6\u308A\u8FBC\u307F\u307E\u3059\u3002\n\u30A2\u30FC\u30AB\u30A4\u30D6\u306E .hai/compose.json \u306F\u9078\u629E\u3057\u305F\u30B5\u30FC\u30D3\u30B9\u3092\u542B\u307F\u3001\u914D\u5099\u5F8C\u306F\u7D71\u5408\u6E08\u307F\u306E\u5B8C\u5168\u306A\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\u306B\u306A\u308A\u307E\u3059\u3002.hai/SHA256SUMS \u306F\u5143\u306E\u5C55\u958B\u5185\u5BB9\u3092\u691C\u8A3C\u3057\u307E\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u5074\u306E\u30B3\u30D4\u30FC\u306F\u8A2D\u5B9A\u78BA\u5B9A\u3084\u7D71\u5408\u6642\u306B\u5909\u66F4\u3055\u308C\u307E\u3059\u3002\n.hai/middleware-runtime.env \u306F\u540C\u68B1\u30B3\u30F3\u30C6\u30CA\u30FC\u7528\u306E Compose env_file \u3067\u3059\u3002\u5FC5\u8981\u306A\u56FA\u6709\u5909\u6570\u304C\u306A\u3051\u308C\u3070\u7A7A\u306B\u306A\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\u3002\u7DAD\u6301\u3057\u305F\u30B5\u30FC\u30D3\u30B9\u304C\u53E4\u3044 release \u3092\u53C2\u7167\u3059\u308B\u5834\u5408\u306F\u3001\u6709\u52B9\u306A Compose \u306E env_file \u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002apply.sh \u306F .hai/managed-candidates.env \u306E\u521D\u56DE\u7528\u5019\u88DC\u3092\u51E6\u7406\u3057\u307E\u3059\u3002\n.hai/runtime-env.mjs \u306F Node \u306E\u8A2D\u5B9A\u78BA\u5B9A\u3068\u8D77\u52D5\u6642\u306E\u8AAD\u307F\u8FBC\u307F\u3092\u62C5\u5F53\u3057\u307E\u3059\u3002.hai/request-access.yml\u3001.hai/web.conf\u3001\u30D7\u30ED\u30AD\u30B7\u30B9\u30AF\u30EA\u30D7\u30C8\u3001.hai/tls/ \u306F\u30A2\u30AF\u30BB\u30B9\u5236\u5FA1\u3001\u30EA\u30D0\u30FC\u30B9\u30D7\u30ED\u30AD\u30B7\u3001HTTPS \u7528\u306E\u4EFB\u610F\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002\n\u30B5\u30FC\u30D0\u30FC\u306E incoming/ \u306F\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3068\u5C55\u958B\u5185\u5BB9\u3001releases/ \u306F\u914D\u5099\u3068\u5FA9\u65E7\u306E\u8A18\u9332\u3092\u4FDD\u6301\u3057\u307E\u3059\u3002managed-secrets.env\u3001persistent-backends\u3001\u30C7\u30FC\u30BF\u30DC\u30EA\u30E5\u30FC\u30E0\u306F\u4E00\u7DD2\u306B\u4FDD\u8B77\u3057\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u307E\u3059\u3002.deploy.lock \u306F\u914D\u5099\u3068\u8CC7\u683C\u60C5\u5831\u64CD\u4F5C\u306E\u8ABF\u6574\u306B\u4F7F\u3044\u307E\u3059\u3002\n\u30B5\u30FC\u30D0\u30FC\u306E\u30D8\u30EB\u30B9\u30C1\u30A7\u30C3\u30AF\u901A\u904E\u5F8C\u306B current \u3092\u66F4\u65B0\u3057\u307E\u3059\u3002result-{deploymentId}.json \u306F\u7D50\u679C\u3068\u5FA9\u65E7\u72B6\u614B\u3001steps-{deploymentId}.jsonl \u306F\u9032\u884C\u72B6\u6CC1\u3001diagnostics-{deploymentId}.log \u306F\u8D77\u52D5\u5931\u6557\u6642\u306E\u975E\u516C\u958B\u8A3A\u65AD\u3067\u3059\u3002\u53E4\u3044 release \u306E\u6574\u7406\u524D\u306B\u73FE\u5728\u306E Compose \u306E\u53C2\u7167\u3001\u30DE\u30A6\u30F3\u30C8\u3001\u5FA9\u65E7\u306E\u8981\u4EF6\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
332
338
|
deploy_downloadInvalid: "\u53D6\u5F97\u5143\u307E\u305F\u306F\u30D7\u30ED\u30AD\u30B7\u8A2D\u5B9A\u304C\u7121\u52B9\u3067\u3059\u3002URL \u306B\u8A8D\u8A3C\u60C5\u5831\u3084\u30AF\u30A8\u30EA\u3092\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002",
|
|
333
339
|
deploy_imageSourceMissing: "\u30AB\u30B9\u30BF\u30E0\u53D6\u5F97\u5143\u306B\u30EC\u30B8\u30B9\u30C8\u30EA\u30FC\u306E\u5BFE\u5FDC\u8868\u304C\u3042\u308A\u307E\u305B\u3093\uFF1A{registry}",
|
|
334
340
|
deploy_proxySystemUnsupported: "\u9759\u7684\u30B7\u30B9\u30C6\u30E0\u30D7\u30ED\u30AD\u30B7\u3092\u53D6\u5F97\u3067\u304D\u306A\u3044\u304B\u3001PAC\uFF0F\u81EA\u52D5\u691C\u51FA\u306E\u307F\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u74B0\u5883\u5909\u6570\u3092 inherit \u3059\u308B\u304B\u3001custom HTTP(S) URL \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
@@ -463,12 +469,15 @@ var zh_CN_default = {
|
|
|
463
469
|
deploy_requestAccessInvalid: "\u8BF7\u6C42\u8BBF\u95EE\u7B56\u7565\u914D\u7F6E\u65E0\u6548\uFF08{field}\uFF09\u3002\u8BF7\u68C0\u67E5\u5B57\u6BB5\u3001IP\u3001\u65F6\u533A\u53CA\u65F6\u95F4\u7A97\u53E3\uFF1B\u5982\u5F15\u7528\u6587\u4EF6\uFF0C\u8BF7\u786E\u8BA4\u6587\u4EF6\u53EF\u8BFB\u3001\u683C\u5F0F\u4E3A YAML \u4E14\u4E0D\u8D85\u8FC7 1 MiB\u3002\u4FEE\u6B63\u540E\u91CD\u65B0\u6253\u5305\u3002",
|
|
464
470
|
deploy_httpsPortsInvalid: "HTTP \u4E0E HTTPS \u7AEF\u53E3\u5FC5\u987B\u4E0D\u540C\uFF1BLet\u2019s Encrypt \u7684 HTTP-01 \u5165\u53E3\u5FC5\u987B\u4F7F\u7528\u5BBF\u4E3B\u673A 80 \u7AEF\u53E3\u3002",
|
|
465
471
|
deploy_httpsCertificateInvalid: "HTTPS \u8BC1\u4E66\u65E0\u6548\uFF1A\u8BF7\u6838\u5BF9 PEM \u6587\u4EF6\u53EF\u8BFB\u3001\u8BC1\u4E66\u4E0E\u672A\u52A0\u5BC6\u79C1\u94A5\u5339\u914D\u3001\u8BC1\u4E66\u6709\u6548\u671F\u53CA\u57DF\u540D\uFF0C\u7136\u540E\u91CD\u65B0\u6253\u5305\u3002",
|
|
466
|
-
deploy_bundleRuntime: "\
|
|
472
|
+
deploy_bundleRuntime: "\u914D\u7F6E\u6587\u4EF6\u4E0E\u751F\u6548\u65F6\u673A\n\u89E3\u5305\u76EE\u5F55 config/.env.runtime \u662F\u672C\u5305\u8F93\u5165\uFF0C\u5305\u542B\u5E94\u7528\u914D\u7F6E\u548C\u53EF\u80FD\u7684\u968F\u5305\u4E2D\u95F4\u4EF6\u5019\u9009\u3002\u4FEE\u6539\u9879\u76EE\u6E90\u73AF\u5883\u540E\u91CD\u65B0\u6253\u5305\u3002apply.sh \u4F1A\u6821\u9A8C\u5F52\u6863\u5185\u5BB9\u3002\n{directory}/config/.env.runtime \u662F\u5F53\u524D\u8FD0\u884C\u914D\u7F6E\u3002Serv \u548C SvelteKit SSR \u6BCF\u6B21\u542F\u52A8\u4ECE\u53EA\u8BFB\u6302\u8F7D\u7684 /run/hai/config/.env.runtime \u8BFB\u53D6\u3002\n\u8FD0\u884C\u6587\u4EF6\u6309 dotenv \u5B57\u9762\u8BED\u6CD5\u8BFB\u53D6\uFF0C\u5927\u5C0F\u4E0A\u9650\u4E3A 1 MiB\u3002\u7F3A\u5931\u3001\u4E0D\u53EF\u8BFB\u3001\u91CD\u590D\u8D4B\u503C\u6216\u8D85\u9650\u65F6\u4F1A\u5728\u5E94\u7528\u542F\u52A8\u524D\u62A5\u9519\u3002\n{directory}/releases/{deploymentId}/config/.env.runtime \u662F\u672C\u6B21\u53D1\u5E03\u8BB0\u5F55\u3002\u4EC5\u66F4\u65B0 Web \u6216\u4E2D\u95F4\u4EF6\u65F6\uFF0C\u8BB0\u5F55\u91C7\u7528\u5F53\u65F6\u7684\u5F53\u524D\u914D\u7F6E\u3002\u67E5\u5F53\u524D\u503C\u7528\u90E8\u7F72\u6839\u6587\u4EF6\uFF0C\u67E5\u67D0\u6B21\u53D1\u5E03\u7528\u5BF9\u5E94 release\u3002\n\u5168\u91CF\u91C7\u7528\u65B0\u5305\u914D\u7F6E\u5E76\u590D\u7528\u670D\u52A1\u5668\u53D7\u7BA1\u5BC6\u7801\u3002\u5305\u542B\u4E3B\u5E94\u7528\u7684\u589E\u91CF\u91C7\u7528\u65B0\u5305\u7684\u5916\u90E8\u8FDE\u63A5\u548C\u5E94\u7528\u914D\u7F6E\uFF0C\u5E76\u4FDD\u7559\u65E2\u6709\u53D7\u7BA1\u8FDE\u63A5\u3002\u672A\u9009\u4E3B\u5E94\u7528\u7684\u589E\u91CF\u4FDD\u7559\u5F53\u524D\u914D\u7F6E\u3002\u5916\u90E8\u548C\u53D7\u7BA1\u4E4B\u95F4\u7684\u5207\u6362\u9700\u8981\u5168\u91CF\u53D1\u5E03\u3002\n\u4E34\u65F6\u4FEE\u590D Node \u540E\u7AEF\u914D\u7F6E\u65F6\uFF0C\u5907\u4EFD\u540E\u4FEE\u6539\u90E8\u7F72\u6839\u7684\u8FD0\u884C\u6587\u4EF6\uFF0C\u518D docker restart <\u5BB9\u5668\u540D> \u6216 podman restart <\u5BB9\u5668\u540D>\uFF0C\u9A8C\u8BC1\u5065\u5EB7\u548C\u76F8\u5173\u4E1A\u52A1\u3002\u957F\u671F\u4FEE\u6539\u5199\u56DE\u9879\u76EE\u6E90\u73AF\u5883\uFF0C\u5426\u5219\u4E0B\u6B21\u5305\u542B\u540E\u7AEF\u7684\u53D1\u5E03\u53EF\u80FD\u8986\u76D6\u3002\u5BB9\u5668\u8FDB\u7A0B\u663E\u5F0F\u4F20\u5165\u7684\u540C\u540D HAI_* \u4F18\u5148\u3002\n\u9759\u6001 Web\u3001\u4E2D\u95F4\u4EF6\u539F\u751F\u73AF\u5883\u3001\u7AEF\u53E3\u548C\u6302\u8F7D\u3001Node \u542F\u52A8\u53C2\u6570\u3001Nginx \u8DEF\u7531\u548C\u9650\u989D\u3001HTTPS \u88C5\u914D\u5747\u5728\u90E8\u7F72\u65F6\u751F\u6548\u3002\u7F51\u7AD9 base \u53D8\u66F4\u8FD8\u9700\u91CD\u5EFA\u3002\n\u5931\u8D25\u6062\u590D\u5148\u8FD8\u539F\u5E94\u7528\u8FD0\u884C\u6587\u4EF6\uFF0C\u518D\u6062\u590D\u65E7\u670D\u52A1\u3002\u6570\u636E\u5E93\u4E2D\u5DF2\u6267\u884C\u7684\u5BC6\u7801\u6216\u6570\u636E\u53D8\u66F4\u987B\u7531\u6570\u636E\u5E93\u7EF4\u62A4\u6D41\u7A0B\u5904\u7406\u3002",
|
|
473
|
+
deploy_refreshCookieSecureInvalid: "HAI_SERV_REFRESH_COOKIE_SECURE \u53EA\u63A5\u53D7 true\u3001false \u6216\u7A7A\u503C\u3002\u8BF7\u68C0\u67E5\u6240\u9009\u90E8\u7F72\u73AF\u5883\u53CA\u6253\u5305\u8FDB\u7A0B\u4E2D\u7684\u540C\u540D\u53D8\u91CF\u3002",
|
|
474
|
+
deploy_postgresPasswordConflict: "\u5916\u90E8 PostgreSQL \u7684 HAI_DB_URL\uFF08\u6216 HAI_DB.url\uFF09\u4E0E HAI_DB_PASSWORD\uFF08\u6216 HAI_DB.password\uFF09\u5BC6\u7801\u4E0D\u4E00\u81F4\u3002\u8BF7\u4F7F\u7528\u5B8C\u6574\u8FDE\u63A5\u4E32\u6216\u5206\u5B57\u6BB5\u914D\u7F6E\u3002",
|
|
475
|
+
deploy_bundleVariables: "\u73AF\u5883\u53D8\u91CF\u4E0E\u6392\u67E5\uFF08\u53EA\u5217\u540D\u79F0\uFF09\n\u6240\u9009\u73AF\u5883\u4E3A {environment}\u3002\u6253\u5305\u8F93\u5165\u4ECE\u9AD8\u5230\u4F4E\u4E3A\u6253\u5305\u8FDB\u7A0B\u3001.env.{environment}.local\u3001.env.local\u3001.env.{environment}\u3001.env\uFF0C\u7136\u540E\u662F\u5E94\u7528 YAML \u9ED8\u8BA4\u503C\u3002--env-dir \u9009\u62E9\u73AF\u5883\u6587\u4EF6\u76EE\u5F55\u3002\u540C\u6E90\u7EC6\u9879\u8986\u76D6\u7236 JSON\uFF0C\u8F83\u9AD8\u6765\u6E90\u7684\u7236 JSON \u66FF\u6362\u65E7\u7ED3\u6784\u7EC6\u9879\u3002\n\u672C\u5305 config/.env.runtime \u4E2D\u7684\u53D8\u91CF\u540D\uFF08--plan \u5217\u7684\u662F\u6E90\u73AF\u5883\u8F93\u5165\u952E\uFF09\uFF1A{keys}\nHAI_SERV_REFRESH_COOKIE_SECURE \u662F\u72EC\u7ACB\u8FDB\u7A0B\u5F00\u5173\uFF0C\u53EA\u7531\u540C\u540D\u53D8\u91CF\u8986\u76D6\u3002true \u542F\u7528 Secure\uFF0Cfalse \u4EC5\u7528\u4E8E\u53D7\u63A7\u5185\u7F51\u6216 VPN \u7684 HTTP \u5165\u53E3\uFF0C\u7A7A\u503C\u6216\u672A\u8BBE\u7F6E\u4F7F\u7528 Serv \u73AF\u5883\u9ED8\u8BA4\u7B56\u7565\uFF08\u751F\u4EA7\u5F00\u542F\uFF09\u3002HTTP \u5165\u53E3\u4ECD\u9700\u8BBE\u7F6E\u5B9E\u9645 HAI_SERV_CORS_ORIGIN\u3002\u90E8\u7F72\u540E\u786E\u8BA4\u767B\u5F55\u548C\u5237\u65B0\u3002\n\u793A\u4F8B\uFF1A\u5728\u53D7\u63A7 HTTP \u73AF\u5883\u7684 .env.{environment}.local \u4E2D\u5199 HAI_SERV_REFRESH_COOKIE_SECURE=false\uFF0C\u5E76\u8BBE\u7F6E\u5B9E\u9645\u7684 CORS Origin\u3002\u5DF2\u6709\u6210\u529F\u5168\u91CF\u548C serv \u955C\u50CF\u5236\u54C1\u65F6\uFF0C\u53EF\u5728\u9879\u76EE\u76EE\u5F55\u6267\u884C pnpm run deploy --env {environment} --bundle-only --yes --services serv\uFF0C\u7136\u540E\u5728\u670D\u52A1\u5668\u89E3\u5305\u5E76\u6267\u884C sh ./apply.sh\u3002\n\u5916\u90E8 PostgreSQL \u4F7F\u7528 HAI_DB_URL\uFF08\u5B8C\u6574\u8FDE\u63A5\u4E32\uFF0C\u542B\u6240\u9700\u8BA4\u8BC1\uFF09\u6216 HAI_DB_HOST\u3001HAI_DB_PORT\u3001HAI_DB_USER\u3001HAI_DB_DATABASE\u3001HAI_DB_PASSWORD\u3002URL \u4F1A\u4F18\u5148\uFF0C\u6539\u5BC6\u65F6\u66F4\u65B0\u751F\u6548\u7684\u914D\u7F6E\u65B9\u5F0F\u3002\u6570\u636E\u5E93\u8D26\u53F7\u548C\u6E90\u73AF\u5883\u6539\u597D\u540E\uFF0C\u91CD\u65B0\u53D1\u5E03 serv \u6216\u5168\u91CF\u53D1\u5E03\u3002\nHAI_CACHE_*\u3001HAI_STORAGE_*\u3001HAI_VECDB_* \u548C HAI_IAM_LDAP_* \u662F\u5E94\u7528\u8FDE\u63A5\u3002S3 \u5730\u5740\u4E0E\u8BBF\u95EE\u5BC6\u94A5\u5206\u522B\u914D\u7F6E\u3002\u5916\u90E8\u6216\u4E91\u5F00\u901A\u7684\u670D\u52A1\u7531\u5E94\u7528\u8FDE\u63A5\uFF0C\u901A\u5E38\u65E0\u672C\u5305\u7684\u955C\u50CF\u539F\u751F\u53D8\u91CF\u3002\n\u968F\u5305 PostgreSQL \u4ECE managed-secrets.env \u7684 DB_PASSWORD \u751F\u6210\u5E94\u7528\u8FDE\u63A5 HAI_DB_URL \u548C\u539F\u751F POSTGRES_PASSWORD\u3002POSTGRES_PASSWORD \u7528\u4E8E\u521D\u59CB\u5316\u7A7A\u6570\u636E\u76EE\u5F55\u3002\u5176\u4ED6\u968F\u5305\u955C\u50CF\u53EF\u80FD\u4F7F\u7528 MYSQL_*\u3001RUSTFS_*\u3001MINIO_* \u6216 LDAP_*\u3002\u5DF2\u6709\u5377\u7684\u8D26\u53F7\u8F6E\u6362\u9700\u8981\u540C\u6B65\u5B9E\u9645\u8D26\u53F7\u548C\u53D7\u7BA1\u72B6\u6001\u3002\u4EC5\u91CD\u542F\u6216\u91CD\u5EFA\u5BB9\u5668\u65E0\u6CD5\u5B8C\u6210\u6570\u636E\u5E93\u6362\u5BC6\u3002\nNODE_ENV \u5F71\u54CD\u5E94\u7528\u73AF\u5883\u3002HOST\u3001PORT \u548C HAI_SERV_SERVER_* \u7684\u76D1\u542C\u5730\u5740/\u7AEF\u53E3\u7531\u4EA4\u4ED8\u62D3\u6251\u5B9A\u7A3F\u3002NODE_OPTIONS \u548C HAI_DEPLOY_PRIVATE_PROXY \u5C5E\u4E8E\u5BB9\u5668\u88C5\u914D\u3002HAI_DEPLOY_PROVIDER_SSH_PASSWORD \u7531\u4E0A\u4F20\u7AEF\u7528\u4E8E SSH\uFF0C\u4E0E\u5E94\u7528\u8FDE\u63A5\u5206\u5F00\u3002\n\u5F52\u6863\u3001\u8FD0\u884C\u6587\u4EF6\u3001\u51ED\u636E\u3001\u79C1\u94A5\u548C\u6545\u969C\u65E5\u5FD7\u6309\u79C1\u6709\u8D44\u6599\u4FDD\u7BA1\u3002\u6392\u67E5\u6216\u4EA4\u7ED9 AI \u65F6\u53EA\u63D0\u4F9B\u53D8\u91CF\u540D\u3001\u6765\u6E90\u3001\u8131\u654F\u9519\u8BEF\u548C\u90E8\u7F72 ID\u3002",
|
|
467
476
|
deploy_bundleHttpOnly: "HTTPS\uFF1A\u672A\u542F\u7528\u3002\u672C\u5305\u4EC5\u53D1\u5E03 HTTP \u7AEF\u53E3 {port}\uFF0C\u6CA1\u6709\u8BC1\u4E66\u9644\u4EF6\uFF0C\u4E5F\u4E0D\u4F1A\u5728\u670D\u52A1\u5668\u7533\u8BF7\u8BC1\u4E66\u3002",
|
|
468
477
|
deploy_bundleHttps: "HTTPS\uFF1A\u5DF2\u542F\u7528\uFF0Chttps://{domain}:{port}\uFF1B\u6A21\u5F0F {mode}\u3002\n\u670D\u52A1\u5668\u8BC1\u4E66\uFF1A{certificates}/fullchain.pem\uFF1B\u79C1\u94A5\uFF1A{certificates}/privkey.pem\u3002\u5BB9\u5668\u53EA\u8BFB\u6302\u8F7D\u5230 /etc/nginx/tls/\u3002\n\u4FEE\u6539\u672C\u5730\u6253\u5305\u73AF\u5883 .env.{environment}.local \u7684 HAI_DEPLOY_PROVIDER \u4E2D expose.https\uFF0C\u6216\u672A\u88AB\u8986\u76D6\u7684 hai.json.deploy.provider.expose.https\u3002\u542F\u505C\u3001\u5207\u6362\u6A21\u5F0F/\u57DF\u540D/\u7AEF\u53E3\u540E\u751F\u6210\u65B0\u7684\u5168\u91CF\u90E8\u7F72\u5305\uFF1B\u4FEE\u6539 .env.runtime \u5E76\u91CD\u542F\u4E0D\u80FD\u89E6\u53D1\u65B0\u57DF\u540D\u7B7E\u53D1\u3002",
|
|
469
478
|
deploy_bundleAcme: "Certbot \u6301\u4E45\u72B6\u6001\uFF1A{state}\uFF1B\u5F53\u524D\u8BC1\u4E66\u5165\u53E3\uFF1A{state}/live/{domain}\u3002\u6253\u5305\u4E0D\u8BF7\u6C42 CA\uFF0C\u670D\u52A1\u5668\u90E8\u7F72\u65F6\u7533\u8BF7\uFF0C\u4E4B\u540E\u81EA\u52A8\u7EED\u671F\u3002\u516C\u7F51 80 \u7AEF\u53E3\u53CA\u6839\u8DEF\u5F84 /.well-known/acme-challenge/ \u5FC5\u987B\u53EF\u8FBE\uFF0C\u4E0D\u80FD\u53EA\u5141\u8BB8\u4E1A\u52A1 context path\u3002",
|
|
470
479
|
deploy_bundleAccounts: "\u521D\u59CB\u8D26\u53F7\u53D8\u91CF\uFF08\u53EA\u5217\u540D\u79F0\u548C\u6765\u6E90\uFF0C\u4E0D\u663E\u793A\u5BC6\u7801\uFF09\uFF1A\n{sources}\nHAI_CONFIG_ADMIN_PASSWORD \u4F9B\u6709\u76F8\u5E94\u5F15\u5BFC\u903B\u8F91\u7684\u5E94\u7528\u521B\u5EFA config_admin \u914D\u7F6E\u7BA1\u7406\u5458\uFF1BHAI_ADMIN_DEFAULT_PASSWORD\u3001HAI_AUDIT_ADMIN_PASSWORD\u3001HAI_BUSINESS_OPERATOR_PASSWORD \u5BF9\u5E94\u5176\u4ED6\u6A21\u677F\u804C\u8D23\u8D26\u53F7\u3002\nCLI \u521B\u5EFA Fullstack \u65F6\u4E3A\u5404\u73AF\u5883\u751F\u6210\u72EC\u7ACB\u521D\u59CB\u5BC6\u7801\uFF1B\u6253\u5305\u8BFB\u53D6\u6240\u9009\u73AF\u5883\u4E0E\u8FDB\u7A0B\u8986\u76D6\uFF0C\u4E0D\u4F1A\u56E0\u670D\u52A1\u5668\u90E8\u7F72\u518D\u751F\u6210\u5E94\u7528\u8D26\u53F7\u5BC6\u7801\u3002\u6709\u914D\u7F6E\u4E14\u8D26\u53F7\u7F3A\u5931\u65F6\u7531\u5E94\u7528\u542F\u52A8\u5F15\u5BFC\uFF1B\u5DF2\u6709\u8D26\u53F7\u4E0D\u4F1A\u56E0\u4FEE\u6539\u53D8\u91CF\u91CD\u7F6E\u5BC6\u7801\u6216\u6062\u590D\u65E7\u804C\u8D23\u3002\u65E0\u76F8\u5E94\u5F15\u5BFC\u903B\u8F91\u7684\u81EA\u5B9A\u4E49\u5E94\u7528\u4EE5\u81EA\u8EAB\u5B9E\u73B0\u4E3A\u51C6\u3002",
|
|
471
|
-
deploy_bundleDirectories: "\u670D\u52A1\u5668\
|
|
480
|
+
deploy_bundleDirectories: "\u6587\u4EF6\u7D22\u5F15\uFF08\u670D\u52A1\u5668\u8DEF\u5F84\u4EE5\u5B9E\u9645\u90E8\u7F72\u6839\u4E3A\u51C6\uFF0C\u9ED8\u8BA4 {directory}\uFF09\n\u4EA4\u4ED8\u76EE\u5F55 README.txt \u63D0\u4F9B\u603B\u89C8\u3002deploy.sh \u548C deploy.ps1 \u901A\u8FC7 SSH \u4F20\u8F93\u5E76\u6267\u884C\u3002deploy-target.json \u9009\u62E9\u76EE\u6807\u3001\u9274\u6743\u548C\u76EE\u5F55\uFF0Cread-target.awk \u4F9B\u811A\u672C\u8BFB\u53D6\u914D\u7F6E\u3002deploy-local.sh \u5728\u670D\u52A1\u5668\u672C\u5730\u89E3\u5305\u5E76\u6267\u884C\u3002\n\u5F52\u6863\u5185 APPLY.txt \u662F\u624B\u5DE5\u64CD\u4F5C\u548C\u914D\u7F6E\u8BF4\u660E\u3002apply.sh \u6821\u9A8C\u3001\u52A0\u9501\u3001\u5BFC\u5165\u5E76\u542F\u52A8\u3002manifest.json \u8BB0\u5F55\u5236\u54C1\u3001\u6A21\u5F0F\u3001\u9009\u4E2D\u670D\u52A1\u53CA\u975E\u654F\u611F\u5143\u6570\u636E\u3002images/ \u662F OCI \u955C\u50CF\u5F52\u6863\uFF0C\u5BFC\u5165\u540E\u955C\u50CF\u7531\u5F15\u64CE\u4FDD\u5B58\u3002\n\u5F52\u6863\u5185 .hai/compose.json \u8BB0\u5F55\u6240\u9009\u670D\u52A1\uFF0C\u5B89\u88C5\u540E\u7684\u540C\u540D\u6587\u4EF6\u662F\u5408\u5E76\u540E\u7684\u5B8C\u6574\u670D\u52A1\u5FEB\u7167\u3002.hai/SHA256SUMS \u7528\u4E8E\u6821\u9A8C\u539F\u59CB\u89E3\u5305\u5185\u5BB9\u3002\u670D\u52A1\u5668\u526F\u672C\u4F1A\u5728\u5B9A\u7A3F\u548C\u5408\u5E76\u65F6\u6539\u53D8\u3002\n.hai/middleware-runtime.env \u53EA\u4F9B\u968F\u5305\u4E2D\u95F4\u4EF6\u7684 Compose env_file \u4F7F\u7528\u3002\u65E0\u539F\u751F\u73AF\u5883\u65F6\u53EF\u4EE5\u4E3A\u7A7A\u3002\u589E\u91CF\u4FDD\u7559\u7684\u670D\u52A1\u53EF\u80FD\u5F15\u7528\u66F4\u65E9\u7684 release\uFF0C\u4EE5\u6709\u6548 Compose \u7684 env_file \u4E3A\u51C6\u3002.hai/managed-candidates.env \u662F\u9996\u6B21\u5B89\u88C5\u5019\u9009\uFF0C\u7531 apply.sh \u6D88\u8D39\u3002\n.hai/runtime-env.mjs \u662F Node \u542F\u52A8\u52A0\u8F7D\u5668\u548C\u914D\u7F6E\u5B9A\u7A3F\u811A\u672C\u3002\u6309\u9700\u5305\u542B .hai/request-access.yml\u3001.hai/web.conf\u3001\u4EE3\u7406\u811A\u672C\u548C .hai/tls/ \u7B49\u8BBF\u95EE\u7B56\u7565\u3001\u53CD\u5411\u4EE3\u7406\u548C HTTPS \u8D44\u4EA7\u3002\n\u670D\u52A1\u5668 incoming/ \u4FDD\u5B58\u672C\u6B21\u4E0A\u4F20\u548C\u89E3\u5305\u5185\u5BB9\u3002releases/ \u4FDD\u5B58\u53D1\u5E03\u4E0E\u6062\u590D\u8BB0\u5F55\u3002managed-secrets.env\u3001persistent-backends \u548C\u6570\u636E\u5377\u6210\u5957\u4FDD\u62A4\u4E0E\u5907\u4EFD\uFF0C.deploy.lock \u4F9B\u90E8\u7F72\u548C\u51ED\u636E\u64CD\u4F5C\u534F\u8C03\u3002\ncurrent \u5728\u670D\u52A1\u5668\u5065\u5EB7\u68C0\u67E5\u901A\u8FC7\u540E\u66F4\u65B0\u3002result-{deploymentId}.json \u8BB0\u5F55\u7ED3\u679C\u548C\u6062\u590D\u72B6\u6001\uFF0Csteps-{deploymentId}.jsonl \u8BB0\u5F55\u6B65\u9AA4\uFF0Cdiagnostics-{deploymentId}.log \u5728\u542F\u52A8\u5931\u8D25\u65F6\u63D0\u4F9B\u79C1\u6709\u8BCA\u65AD\u3002\u6E05\u7406\u65E7 release \u524D\u6838\u5BF9\u5F53\u524D Compose\u3001\u6D3B\u52A8\u6302\u8F7D\u4E0E\u6062\u590D\u9700\u8981\u3002",
|
|
472
481
|
deploy_downloadInvalid: "\u4E0B\u8F7D\u6E90\u6216\u4EE3\u7406\u914D\u7F6E\u65E0\u6548\uFF0C\u5730\u5740\u4E0D\u80FD\u5305\u542B\u8BA4\u8BC1\u4FE1\u606F\u6216\u67E5\u8BE2\u53C2\u6570\u3002",
|
|
473
482
|
deploy_imageSourceMissing: "\u81EA\u5B9A\u4E49\u955C\u50CF\u6E90\u7F3A\u5C11\u4ED3\u5E93\u6620\u5C04\uFF1A{registry}",
|
|
474
483
|
deploy_proxySystemUnsupported: "\u65E0\u6CD5\u8BFB\u53D6\u8BE5\u7CFB\u7EDF\u7684\u9759\u6001\u4EE3\u7406\uFF0C\u6216\u7CFB\u7EDF\u4EC5\u63D0\u4F9B PAC/\u81EA\u52A8\u53D1\u73B0\u3002\u8BF7\u4F7F\u7528 inherit \u73AF\u5883\u53D8\u91CF\u6216 custom HTTP(S) \u5730\u5740\u3002",
|
|
@@ -6221,6 +6230,8 @@ function generatedVariables(values) {
|
|
|
6221
6230
|
continue;
|
|
6222
6231
|
const text = typeof value === "string" ? value : value === null || typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
6223
6232
|
generated[name] = text;
|
|
6233
|
+
if (name === "HAI_SERV_REFRESH_COOKIE_SECURE")
|
|
6234
|
+
continue;
|
|
6224
6235
|
const module = /^HAI_([A-Z0-9]+)(?:_|$)/.exec(name)?.[1]?.toLowerCase();
|
|
6225
6236
|
if (!module || !shapes[module])
|
|
6226
6237
|
continue;
|
|
@@ -7106,7 +7117,7 @@ deployment_metadata_init() {
|
|
|
7106
7117
|
deployment_metadata_file() {
|
|
7107
7118
|
metadata_directory=$1
|
|
7108
7119
|
metadata_name=$2
|
|
7109
|
-
case "$metadata_name" in layout|health-paths|image-list|dependencies|managed-project|managed-bindings|managed-volumes|managed-app-keys|state-backends|storage-routing|web-base-path|node-runtime|proxy-service|https) ;; *) printf 'Unknown deployment metadata field.\n' >&2; return 1;; esac
|
|
7120
|
+
case "$metadata_name" in layout|health-paths|image-list|dependencies|managed-project|managed-bindings|managed-volumes|managed-app-keys|unmanaged-app-keys|state-backends|storage-routing|web-base-path|node-runtime|proxy-service|https) ;; *) printf 'Unknown deployment metadata field.\n' >&2; return 1;; esac
|
|
7110
7121
|
test -f "$metadata_directory/manifest.json" && test ! -L "$metadata_directory/manifest.json" || return 1
|
|
7111
7122
|
metadata_identity=$(printf '%s' "$metadata_directory" | sha256sum | awk '{print $1}')
|
|
7112
7123
|
metadata_cached="$metadata_work/$metadata_identity-$metadata_name"
|
|
@@ -8725,6 +8736,23 @@ fi
|
|
|
8725
8736
|
resolve_backend_state "$root" "$source_dir" "$runtime" "$previous" check
|
|
8726
8737
|
if [ "$partial" = true ]; then
|
|
8727
8738
|
test -n "$previous" || { printf 'Partial deployment requires a successful full installation. Deploy a complete bundle first.\n' >&2; exit 1; }
|
|
8739
|
+
# 比较完整连接计划,而不是增量 Compose 中携带的服务子集。
|
|
8740
|
+
case " $selected " in
|
|
8741
|
+
*' @@PRIMARY@@ '*)
|
|
8742
|
+
installed_keys=$(deployment_metadata_file "$root/releases/$previous" managed-app-keys)
|
|
8743
|
+
incoming_keys=$(deployment_metadata_file "$source_dir" managed-app-keys)
|
|
8744
|
+
unmanaged_keys=$(deployment_metadata_file "$source_dir" unmanaged-app-keys)
|
|
8745
|
+
if ! LC_ALL=C awk '
|
|
8746
|
+
!NF {next}
|
|
8747
|
+
FILENAME == ARGV[1] {installed[$0]=1; next}
|
|
8748
|
+
FILENAME == ARGV[2] {if (!($0 in installed)) exit 1; next}
|
|
8749
|
+
$0 in installed {exit 1}
|
|
8750
|
+
' "$installed_keys" "$incoming_keys" "$unmanaged_keys"; then
|
|
8751
|
+
printf 'Managed middleware connections changed. Use a full deployment to switch between bundled and external middleware.\n' >&2
|
|
8752
|
+
exit 1
|
|
8753
|
+
fi
|
|
8754
|
+
;;
|
|
8755
|
+
esac
|
|
8728
8756
|
# 目录属于完整Web拓扑;旧版本缺省为根目录,服务增量不能意外丢失或改变既有目录。
|
|
8729
8757
|
current_web_base=$(deployment_json read metadata.web-base-path string "$source_dir/manifest.json")
|
|
8730
8758
|
previous_web_base=$(deployment_json read metadata.web-base-path string "$root/releases/$previous/manifest.json")
|
|
@@ -9510,8 +9538,10 @@ async function createDeploymentBundle(options) {
|
|
|
9510
9538
|
files.push(`images/${file}`);
|
|
9511
9539
|
imageList.push(`${file} ${reference}`);
|
|
9512
9540
|
}
|
|
9513
|
-
|
|
9514
|
-
|
|
9541
|
+
const applicationEnvironment = readFileSync(join(directory, ".env.runtime"), "utf8");
|
|
9542
|
+
put("config/.env.runtime", applicationEnvironment);
|
|
9543
|
+
const updatesApp = selected.includes(artifact.primaryService);
|
|
9544
|
+
if (updatesApp && existsSync(join(directory, "request-access.yml")))
|
|
9515
9545
|
put(".hai/request-access.yml", readFileSync(join(directory, "request-access.yml"), "utf8"));
|
|
9516
9546
|
if (nodeRuntime)
|
|
9517
9547
|
put(".hai/runtime-env.mjs", readFileSync(new URL("./deploy-runtime-env.mjs", import.meta.url), "utf8"));
|
|
@@ -9547,10 +9577,13 @@ async function createDeploymentBundle(options) {
|
|
|
9547
9577
|
"proxy-service": options.hasWebConfig ? options.proxyService ?? "web" : "",
|
|
9548
9578
|
"https": options.httpsAssets?.https ?? "",
|
|
9549
9579
|
"managed-project": managed["managed-project"],
|
|
9550
|
-
|
|
9580
|
+
// 未选应用时只带容器原生绑定,保持当前发布的应用连接归属。
|
|
9581
|
+
"managed-bindings": updatesApp ? managed["managed-bindings"] : managed["managed-bindings"].replace(/^.* prefix\n/gm, ""),
|
|
9551
9582
|
"managed-volumes": managed["managed-volumes"],
|
|
9552
|
-
"managed-app-keys": `${[...new Set(options.managedAppKeys)].join("\n")}
|
|
9553
|
-
|
|
9583
|
+
"managed-app-keys": updatesApp ? `${[...new Set(options.managedAppKeys)].join("\n")}
|
|
9584
|
+
` : "\n",
|
|
9585
|
+
"unmanaged-app-keys": updatesApp ? `${[...new Set(options.unmanagedAppKeys)].join("\n")}
|
|
9586
|
+
` : "\n",
|
|
9554
9587
|
"state-backends": backend["state-backends"]
|
|
9555
9588
|
};
|
|
9556
9589
|
put("manifest.json", `${JSON.stringify({ ...artifact, bundleFormat: 2, images: artifact.images.filter((image) => references.has(image.imageRef)), deploymentId: options.deploymentId, selectedServices: selected, partial: options.partial, metadata }, null, 2)}
|
|
@@ -9563,12 +9596,13 @@ async function createDeploymentBundle(options) {
|
|
|
9563
9596
|
const instructions = `${selection}
|
|
9564
9597
|
${deployM("deploy_bundleInstructions", { params: instructionParams })}`;
|
|
9565
9598
|
const runtimeGuide = deployM("deploy_bundleRuntime", { params: { directory: serverDirectory, deploymentId: options.deploymentId } });
|
|
9599
|
+
const variableGuide = deployM("deploy_bundleVariables", { params: { environment, keys: Object.keys(core.config.parseEnv(applicationEnvironment)).sort().join(", ") || "\u2014" } });
|
|
9566
9600
|
const https = config.expose.https;
|
|
9567
9601
|
const certificates = https?.type === "files" ? `${serverDirectory}/releases/${options.deploymentId}/.hai/tls` : `${serverDirectory}/https/certificates/${https?.domain}`;
|
|
9568
9602
|
const httpsGuide = https ? deployM("deploy_bundleHttps", { params: { domain: https.domain, port: https.port, mode: https.type, certificates, environment } }) + (https.type === "letsencrypt" ? `
|
|
9569
9603
|
${deployM("deploy_bundleAcme", { params: { state: `${serverDirectory}/https/acme`, domain: https.domain } })}` : "") : deployM("deploy_bundleHttpOnly", { params: { port: config.expose.hostPort } });
|
|
9570
9604
|
const accountGuide = deployM("deploy_bundleAccounts", { params: { sources: options.accountSources || "\u2014" } });
|
|
9571
|
-
const guides = [runtimeGuide, httpsGuide, accountGuide, deployM("deploy_bundleDirectories", { params: { directory: serverDirectory, deploymentId: options.deploymentId } })].join("\n\n");
|
|
9605
|
+
const guides = [runtimeGuide, variableGuide, httpsGuide, accountGuide, deployM("deploy_bundleDirectories", { params: { directory: serverDirectory, deploymentId: options.deploymentId } })].join("\n\n");
|
|
9572
9606
|
const bundleMetadata = deployM("deploy_bundleMetadata", { params: { version: artifact.appVersion, buildId: artifact.buildId, deploymentId: options.deploymentId, compose: ".hai/compose.json" } });
|
|
9573
9607
|
const manualGuide = deployM("deploy_bundleApplyGuide", { params: { file: shellArgument(basename(output)), directory: serverDirectory, target: shellArgument(serverDirectory), runtime: config.remote.runtime, deploymentId: options.deploymentId } });
|
|
9574
9608
|
put("APPLY.txt", `${bundleMetadata}
|
|
@@ -9576,7 +9610,7 @@ ${selection}
|
|
|
9576
9610
|
|
|
9577
9611
|
${manualGuide}
|
|
9578
9612
|
|
|
9579
|
-
${
|
|
9613
|
+
${guides}
|
|
9580
9614
|
`);
|
|
9581
9615
|
const readme = `${bundleMetadata}
|
|
9582
9616
|
${instructions}
|
|
@@ -10560,6 +10594,21 @@ function createDockerSshProvider(config, container) {
|
|
|
10560
10594
|
if (gateway)
|
|
10561
10595
|
healthPaths.push("/_hai/gateway-health");
|
|
10562
10596
|
const updatesApp = options?.selectedServices ? options.selectedServices.includes(primaryService) : !!app;
|
|
10597
|
+
const cookieSecure = env.HAI_SERV_REFRESH_COOKIE_SECURE;
|
|
10598
|
+
if (updatesApp && cookieSecure && cookieSecure !== "true" && cookieSecure !== "false")
|
|
10599
|
+
return err(HaiDeployError.CONFIG_ERROR, deployM("deploy_refreshCookieSecureInvalid"));
|
|
10600
|
+
if (updatesApp && !sidecar.services.includes("db") && !provisionEnv.HAI_DB) {
|
|
10601
|
+
const database = scan.middlewares?.find((item) => item.service === "db" && item.backend === "postgresql")?.config;
|
|
10602
|
+
if (typeof database?.url === "string" && database.url && typeof database.password === "string" && database.password) {
|
|
10603
|
+
try {
|
|
10604
|
+
const url2 = new URL(database.url);
|
|
10605
|
+
const urlPassword = url2.searchParams.getAll("password").at(-1) || decodeURIComponent(url2.password);
|
|
10606
|
+
if (urlPassword !== database.password)
|
|
10607
|
+
return err(HaiDeployError.CONFIG_ERROR, deployM("deploy_postgresPasswordConflict"));
|
|
10608
|
+
} catch {
|
|
10609
|
+
}
|
|
10610
|
+
}
|
|
10611
|
+
}
|
|
10563
10612
|
const serverPath = join(appDir, "config", "_serv.yml");
|
|
10564
10613
|
const server = existsSync(serverPath) || hasWebProxy ? loadDeploymentConfig("serv", serverPath, env) : ok({});
|
|
10565
10614
|
if (!server.success)
|
|
@@ -10773,6 +10822,7 @@ function createDockerSshProvider(config, container) {
|
|
|
10773
10822
|
storageRouting,
|
|
10774
10823
|
containerPort,
|
|
10775
10824
|
managedAppKeys: Object.keys(sidecar.env),
|
|
10825
|
+
unmanagedAppKeys: scan.middlewares?.filter((item) => !Object.hasOwn(sidecar.env, item.envPrefix)).map((item) => item.envPrefix),
|
|
10776
10826
|
accountSources: describeDeploymentVariableSources(options?.envDir ?? scan.envDir ?? appDir, options?.environment ?? "prod", env, ["HAI_ADMIN_DEFAULT_PASSWORD", "HAI_AUDIT_ADMIN_PASSWORD", "HAI_CONFIG_ADMIN_PASSWORD", "HAI_BUSINESS_OPERATOR_PASSWORD"]),
|
|
10777
10827
|
healthPaths,
|
|
10778
10828
|
httpsAssets,
|