@stacksjs/ts-cloud 0.5.17 → 0.5.19
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/dist/bin/cli.js +639 -601
- package/dist/deploy/dashboard-data.d.ts +1 -1
- package/dist/deploy/hooks.d.ts +25 -0
- package/dist/deploy/management-dashboard.d.ts +4 -4
- package/dist/deploy/quick-deploy.d.ts +25 -0
- package/dist/drivers/hetzner/driver.d.ts +1 -1
- package/dist/drivers/shared/backups.d.ts +12 -0
- package/dist/drivers/shared/compute-ops.d.ts +10 -1
- package/dist/drivers/shared/laravel-deploy.d.ts +8 -0
- package/dist/drivers/shared/monitoring.d.ts +15 -7
- package/dist/drivers/shared/nginx-vhost.d.ts +19 -0
- package/dist/drivers/shared/php-fpm-pool.d.ts +34 -0
- package/dist/index.js +225 -41
- package/dist/security/pre-deploy-scanner.d.ts +1 -1
- package/dist/ui/index.html +205 -68
- package/dist/ui/server/backups.html +205 -68
- package/dist/ui/server/deployments.html +205 -68
- package/dist/ui/server/metrics.html +205 -68
- package/dist/ui/server/services.html +205 -68
- package/dist/ui/server/sites.html +205 -68
- package/dist/ui/server/ssh-keys.html +205 -68
- package/dist/ui/server/workers.html +205 -68
- package/dist/ui/serverless/assets.html +205 -68
- package/dist/ui/serverless/cost.html +205 -68
- package/dist/ui/serverless/data.html +205 -68
- package/dist/ui/serverless/deployments.html +205 -68
- package/dist/ui/serverless/firewall.html +205 -68
- package/dist/ui/serverless/functions.html +205 -68
- package/dist/ui/serverless/metrics.html +205 -68
- package/dist/ui/serverless/queues.html +205 -68
- package/dist/ui/serverless/scheduler.html +205 -68
- package/dist/ui/serverless/secrets.html +205 -68
- package/dist/ui/serverless.html +205 -68
- package/package.json +3 -3
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* this to `TSCLOUD_DASHBOARD_DATA` and the pages' `<script server>` blocks read
|
|
5
5
|
* it at build time (falling back to representative sample data per-field/per-page
|
|
6
6
|
* when a value isn't present). Every gather is wrapped so one failing source only
|
|
7
|
-
* drops its own slice — the rest still render live. See `ui/pages/*`.
|
|
7
|
+
* drops its own slice — the rest still render live. See `packages/ui/pages/*`.
|
|
8
8
|
*/
|
|
9
9
|
import type { CloudConfig, EnvironmentType } from '@ts-cloud/core';
|
|
10
10
|
/** A loosely-typed bag — the pages read named slices, missing ones fall back. */
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy lifecycle hooks (`config.hooks`): `beforeBuild` / `afterBuild` /
|
|
3
|
+
* `beforeDeploy` / `afterDeploy`. Each hook is either a shell command (string,
|
|
4
|
+
* run on the deploying machine) or an async function called with the config.
|
|
5
|
+
* Mirrors Forge/Envoyer-style deploy hooks, but they run locally around the
|
|
6
|
+
* `cloud deploy` lifecycle (server-side steps belong in `site.deployScript`).
|
|
7
|
+
*/
|
|
8
|
+
import type { CloudConfig } from '@ts-cloud/core';
|
|
9
|
+
export type LifecycleHook = string | ((config: CloudConfig) => void | Promise<void>) | undefined;
|
|
10
|
+
export type HookName = 'beforeBuild' | 'afterBuild' | 'beforeDeploy' | 'afterDeploy';
|
|
11
|
+
export interface HookLogger {
|
|
12
|
+
step?: (message: string) => void;
|
|
13
|
+
error?: (message: string) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run a single lifecycle hook. A string is executed as a shell command (inherits
|
|
17
|
+
* stdio, runs in `cwd`); a function is awaited. Throws if a string hook exits
|
|
18
|
+
* non-zero so the caller can abort the deploy. No-op when the hook is unset.
|
|
19
|
+
*/
|
|
20
|
+
export declare function runHook(hook: LifecycleHook, config: CloudConfig, name: HookName, logger?: HookLogger, cwd?: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Run a named hook from `config.hooks`, returning false if a string hook fails
|
|
23
|
+
* (so the deploy command can stop). Logs the failure via `logger.error`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function runConfigHook(config: CloudConfig, name: HookName, logger?: HookLogger, cwd?: string): Promise<boolean>;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Auto-deploy of the ts-cloud management dashboard (the `@ts-cloud/ui` stx app)
|
|
3
3
|
* on every server provision/deploy.
|
|
4
4
|
*
|
|
5
|
-
* Resolves the UI directory (the repo's local `ui/`, else the prebuilt
|
|
6
|
-
* ships inside the installed package at `dist/ui`), derives a `dashboard.<apex>`
|
|
5
|
+
* Resolves the UI directory (the repo's local `packages/ui/`, else the prebuilt
|
|
6
|
+
* UI that ships inside the installed package at `dist/ui`), derives a `dashboard.<apex>`
|
|
7
7
|
* host, and injects it into `config.sites` as a server-static site. It is served
|
|
8
8
|
* behind htpasswd ONLY when `TS_CLOUD_UI_PASSWORD` is set; when it is not, the
|
|
9
9
|
* dashboard is served without auth (no password is invented).
|
|
@@ -21,8 +21,8 @@ export interface EnsureDashboardLogger {
|
|
|
21
21
|
warn: (msg: string) => void;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Resolve the UI source to ship. Prefers the repo's local `ui/` (built
|
|
25
|
-
* deploy machine), then the prebuilt UI bundled in the installed package.
|
|
24
|
+
* Resolve the UI source to ship. Prefers the repo's local `packages/ui/` (built
|
|
25
|
+
* on the deploy machine), then the prebuilt UI bundled in the installed package.
|
|
26
26
|
* Returns `{ uiRoot, build }` or null when no UI is available.
|
|
27
27
|
*/
|
|
28
28
|
export declare function resolveUiSource(cwd: string): {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quick Deploy (Forge's push-to-deploy): generate a CI pipeline for the app's
|
|
3
|
+
* git provider that runs `cloud deploy` on push to the deploy branch. ts-cloud
|
|
4
|
+
* deploys from the operator's machine/CI (git-clone-on-server), so the modern
|
|
5
|
+
* equivalent of Forge's deploy webhook is a provider-native pipeline rather than
|
|
6
|
+
* an inbound webhook — keyed off `site.repository.provider`.
|
|
7
|
+
*/
|
|
8
|
+
import type { CloudConfig } from '@ts-cloud/core';
|
|
9
|
+
export interface QuickDeployFile {
|
|
10
|
+
/** Repo-relative path to write the pipeline to. */
|
|
11
|
+
path: string;
|
|
12
|
+
/** File contents. */
|
|
13
|
+
content: string;
|
|
14
|
+
/** Resolved git provider. */
|
|
15
|
+
provider: 'github' | 'gitlab' | 'bitbucket';
|
|
16
|
+
/** Branch the pipeline triggers on. */
|
|
17
|
+
branch: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the CI pipeline file for the config's git provider, or `null` when no
|
|
21
|
+
* site has a github/gitlab/bitbucket repository (the `custom` provider and
|
|
22
|
+
* webhook-less setups have no native pipeline to generate). `environment`
|
|
23
|
+
* selects which `cloud deploy <env>` runs.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildQuickDeployCi(config: CloudConfig, environment?: string): QuickDeployFile | null;
|
|
@@ -108,7 +108,7 @@ export declare class HetznerDriver implements CloudDriver {
|
|
|
108
108
|
* `/dev/null`): the box is identified + trusted via the Hetzner API, and
|
|
109
109
|
* providers recycle public IPs, so a stale `known_hosts` entry from a prior
|
|
110
110
|
* (now-deleted) server would otherwise abort the deploy with
|
|
111
|
-
*
|
|
111
|
+
* `REMOTE HOST IDENTIFICATION HAS CHANGED`.
|
|
112
112
|
*/
|
|
113
113
|
private static readonly SSH_HOST_KEY_OPTS;
|
|
114
114
|
private sshBaseArgs;
|
|
@@ -26,3 +26,15 @@ export interface BackupProvisionOptions {
|
|
|
26
26
|
* disabled. Assumes the box can install Bun (to run `ts-backups`).
|
|
27
27
|
*/
|
|
28
28
|
export declare function buildBackupProvisionScript(options: BackupProvisionOptions): string[];
|
|
29
|
+
export interface BackupRestoreOptions {
|
|
30
|
+
/** Specific dump file on the box (absolute path). Default: newest matching dump. */
|
|
31
|
+
from?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the commands that restore a database from a ts-backups dump on the box.
|
|
35
|
+
* With no `from`, the newest dump under {@link BACKUP_OUTPUT_DIR} matching the
|
|
36
|
+
* database name is used. Handles plain `.sql` and gzipped `.sql.gz`. MySQL/
|
|
37
|
+
* MariaDB restore over the root unix socket; Postgres via `psql -U postgres`.
|
|
38
|
+
* Returns `[]` when the database has no name.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildBackupRestoreScript(database: DatabaseConfig | undefined, options?: BackupRestoreOptions): string[];
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* with the shared generators, and runs it on every box — mirroring how
|
|
8
8
|
* {@link import('./compute-deploy').deploySiteRelease} drives a deploy.
|
|
9
9
|
*/
|
|
10
|
-
import type { CloudDriver, EnvironmentType, RemoteDeployInstanceResult } from '@ts-cloud/core';
|
|
10
|
+
import type { CloudDriver, DatabaseConfig, EnvironmentType, RemoteDeployInstanceResult } from '@ts-cloud/core';
|
|
11
11
|
export interface ComputeOpsLogger {
|
|
12
12
|
info(message: string): void;
|
|
13
13
|
warn(message: string): void;
|
|
@@ -57,3 +57,12 @@ export declare function runComputeRecipe(ctx: ComputeOpsContext, options: {
|
|
|
57
57
|
script: string[];
|
|
58
58
|
user?: string;
|
|
59
59
|
}): Promise<ComputeOpsResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Restore a database from a ts-backups dump on the box (Forge's backup restore).
|
|
62
|
+
* Runs the restore on the project's servers; with no `from`, the newest matching
|
|
63
|
+
* dump is used. Returns per-server output.
|
|
64
|
+
*/
|
|
65
|
+
export declare function restoreDatabaseBackup(ctx: ComputeOpsContext, options: {
|
|
66
|
+
database: DatabaseConfig | undefined;
|
|
67
|
+
from?: string;
|
|
68
|
+
}): Promise<ComputeOpsResult>;
|
|
@@ -40,6 +40,14 @@ export interface LaravelDeployOptions {
|
|
|
40
40
|
* Composer `auth.json` and/or `.npmrc`. Quoted heredocs keep tokens literal.
|
|
41
41
|
*/
|
|
42
42
|
export declare function buildCredentialFiles(releaseDir: string, creds?: SiteCredentialsConfig): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Post-deploy health check (Forge-style): once the release is live, hit the
|
|
45
|
+
* site through nginx on localhost (with the site's `Host` header) and fail the
|
|
46
|
+
* deploy if it doesn't return 2xx/3xx within a few retries. A redirect (e.g.
|
|
47
|
+
* the certbot HTTP→HTTPS 301) counts as healthy — nginx is up and routing.
|
|
48
|
+
* Returns `[]` when no `healthCheck.path` (or domain) is configured.
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildHealthCheckScript(site: SiteConfig): string[];
|
|
43
51
|
/**
|
|
44
52
|
* Build the full remote shell script for a PHP/Laravel git deploy, expanding the
|
|
45
53
|
* release macros. Requires `site.repository` to be set.
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Lightweight server monitoring, mirroring Forge's
|
|
2
|
+
* Lightweight server monitoring + resource alerts, mirroring Forge's server
|
|
3
|
+
* metrics and notifications.
|
|
3
4
|
*
|
|
4
|
-
* Dependency-free: a small shell collector reads load average, memory,
|
|
5
|
-
* disk
|
|
6
|
-
* every minute via a systemd timer. The
|
|
7
|
-
*
|
|
5
|
+
* Dependency-free: a small shell collector reads load average, memory, swap,
|
|
6
|
+
* disk, uptime, network throughput, and per-service TCP health, then writes a
|
|
7
|
+
* JSON snapshot to {@link METRICS_PATH} every minute via a systemd timer. The
|
|
8
|
+
* ts-cloud UI (and any operator tooling) reads that file for at-a-glance health.
|
|
9
|
+
*
|
|
10
|
+
* When alert thresholds are configured (CPU load per core, memory %, disk %),
|
|
11
|
+
* the collector calls the on-box `ts-cloud-notify` helper on each OK→alert
|
|
12
|
+
* transition (and once more on recovery), so channels aren't spammed every
|
|
13
|
+
* minute the box stays hot.
|
|
8
14
|
*/
|
|
15
|
+
import type { ComputeMonitoringConfig } from '@ts-cloud/core';
|
|
9
16
|
/** Where the metrics snapshot is written. */
|
|
10
17
|
export declare const METRICS_PATH = "/var/lib/ts-cloud/metrics.json";
|
|
11
18
|
/**
|
|
12
19
|
* Build the commands that install the metrics collector + systemd timer.
|
|
13
|
-
*
|
|
20
|
+
* Accepts `true`/`false` or a {@link ComputeMonitoringConfig} (with alert
|
|
21
|
+
* thresholds). Idempotent. Returns `[]` when disabled.
|
|
14
22
|
*/
|
|
15
|
-
export declare function buildMonitoringScript(
|
|
23
|
+
export declare function buildMonitoringScript(monitoring?: boolean | ComputeMonitoringConfig): string[];
|
|
@@ -41,6 +41,12 @@ export interface NginxVhostOptions {
|
|
|
41
41
|
webDirectory?: string;
|
|
42
42
|
/** PHP version selecting the php-fpm socket. @default '8.3' */
|
|
43
43
|
phpVersion?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Override the `fastcgi_pass` target (e.g. an isolated site's dedicated
|
|
46
|
+
* php-fpm pool — see {@link import('./php-fpm-pool').phpFpmPoolListen}).
|
|
47
|
+
* Defaults to the shared php-fpm listen address for {@link phpVersion}.
|
|
48
|
+
*/
|
|
49
|
+
fastcgiPass?: string;
|
|
44
50
|
/** `from path` → `to URL` 301 redirects. */
|
|
45
51
|
redirects?: Record<string, string>;
|
|
46
52
|
/**
|
|
@@ -71,6 +77,19 @@ export interface NginxVhostOptions {
|
|
|
71
77
|
serverSnippet?: string[];
|
|
72
78
|
/** `client_max_body_size` override for this vhost (e.g. `'256M'`). */
|
|
73
79
|
clientMaxBodySize?: string;
|
|
80
|
+
/** Emit an HSTS header. `true` = 1yr + includeSubDomains; object customizes. */
|
|
81
|
+
hsts?: boolean | {
|
|
82
|
+
maxAge?: number;
|
|
83
|
+
includeSubDomains?: boolean;
|
|
84
|
+
preload?: boolean;
|
|
85
|
+
};
|
|
86
|
+
/** `ssl_protocols` for the custom-cert :443 block. */
|
|
87
|
+
tlsProtocols?: string[];
|
|
88
|
+
/** Per-site IP allow/deny (Forge "Security Rules"). */
|
|
89
|
+
security?: {
|
|
90
|
+
allow?: string[];
|
|
91
|
+
deny?: string[];
|
|
92
|
+
};
|
|
74
93
|
}
|
|
75
94
|
/** Path of the htpasswd file for a site. */
|
|
76
95
|
export declare function htpasswdPath(siteName: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Directory pantry's php-fpm master scans for extra pool configs (`include`). */
|
|
2
|
+
export declare const PHP_FPM_POOL_DIR = "/var/lib/pantry/php-fpm/pool.d";
|
|
3
|
+
/** Dedicated Linux user (and group) the site's php-fpm pool runs as. */
|
|
4
|
+
export declare function siteUser(siteName: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Deterministic per-site php-fpm listen port in `[9100, 9499]`. Stable for a
|
|
7
|
+
* given site name (stateless generation), so redeploys reuse the same port.
|
|
8
|
+
*/
|
|
9
|
+
export declare function phpFpmPoolPort(siteName: string): number;
|
|
10
|
+
/** The `fastcgi_pass` target for an isolated site's dedicated pool. */
|
|
11
|
+
export declare function phpFpmPoolListen(siteName: string): string;
|
|
12
|
+
export interface PhpFpmPoolOptions {
|
|
13
|
+
/** Site key — names the pool, user, and config file. */
|
|
14
|
+
siteName: string;
|
|
15
|
+
/** Site root (`/var/www/<site>`) — owned by the site user and the open_basedir jail. */
|
|
16
|
+
appBase: string;
|
|
17
|
+
/** Max worker processes for the pool. @default 10 */
|
|
18
|
+
maxChildren?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Render the php-fpm pool config for an isolated site: a named pool running as
|
|
22
|
+
* the site's dedicated user, listening on its per-site port, jailed to its own
|
|
23
|
+
* directory tree (`open_basedir`) plus `/tmp`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function buildPhpFpmPoolConf(options: PhpFpmPoolOptions): string;
|
|
26
|
+
/**
|
|
27
|
+
* Build the shell commands that set up an isolated site's php-fpm pool: create
|
|
28
|
+
* the dedicated system user/group, give www-data (nginx) group access so it can
|
|
29
|
+
* still read static files, take ownership of the site tree, write the pool conf
|
|
30
|
+
* into pantry's pool include dir, and restart php-fpm so the pool comes up.
|
|
31
|
+
*
|
|
32
|
+
* Idempotent — re-runnable on every deploy.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildPhpFpmPoolScript(options: PhpFpmPoolOptions): string[];
|