kastell 1.4.0 → 1.5.2
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.md +56 -16
- package/README.tr.md +49 -16
- package/SECURITY.md +93 -6
- package/dist/adapters/coolify.d.ts +4 -3
- package/dist/adapters/coolify.d.ts.map +1 -1
- package/dist/adapters/coolify.js +106 -37
- package/dist/adapters/coolify.js.map +1 -1
- package/dist/adapters/dokploy.d.ts +5 -3
- package/dist/adapters/dokploy.d.ts.map +1 -1
- package/dist/adapters/dokploy.js +114 -37
- package/dist/adapters/dokploy.js.map +1 -1
- package/dist/adapters/factory.d.ts +1 -0
- package/dist/adapters/factory.d.ts.map +1 -1
- package/dist/adapters/factory.js +20 -0
- package/dist/adapters/factory.js.map +1 -1
- package/dist/adapters/interface.d.ts +12 -2
- package/dist/adapters/interface.d.ts.map +1 -1
- package/dist/adapters/shared.d.ts +13 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/shared.js +75 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/commands/add.js +4 -4
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/audit.d.ts +19 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +134 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/auth.d.ts +6 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +78 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/destroy.d.ts.map +1 -1
- package/dist/commands/destroy.js +1 -2
- package/dist/commands/destroy.js.map +1 -1
- package/dist/commands/domain.d.ts.map +1 -1
- package/dist/commands/domain.js +9 -0
- package/dist/commands/domain.js.map +1 -1
- package/dist/commands/firewall.d.ts +1 -1
- package/dist/commands/firewall.d.ts.map +1 -1
- package/dist/commands/firewall.js +5 -3
- package/dist/commands/firewall.js.map +1 -1
- package/dist/commands/health.d.ts.map +1 -1
- package/dist/commands/health.js +11 -4
- package/dist/commands/health.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/interactive.d.ts.map +1 -1
- package/dist/commands/interactive.js +23 -0
- package/dist/commands/interactive.js.map +1 -1
- package/dist/commands/maintain.d.ts.map +1 -1
- package/dist/commands/maintain.js +98 -190
- package/dist/commands/maintain.js.map +1 -1
- package/dist/commands/restore.d.ts.map +1 -1
- package/dist/commands/restore.js +58 -140
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/snapshot.d.ts.map +1 -1
- package/dist/commands/snapshot.js +5 -0
- package/dist/commands/snapshot.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +18 -11
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/transfer.d.ts.map +1 -1
- package/dist/commands/transfer.js +14 -0
- package/dist/commands/transfer.js.map +1 -1
- package/dist/constants.d.ts +4 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +8 -3
- package/dist/constants.js.map +1 -1
- package/dist/core/audit/checks/auth.d.ts +7 -0
- package/dist/core/audit/checks/auth.d.ts.map +1 -0
- package/dist/core/audit/checks/auth.js +123 -0
- package/dist/core/audit/checks/auth.js.map +1 -0
- package/dist/core/audit/checks/docker.d.ts +8 -0
- package/dist/core/audit/checks/docker.d.ts.map +1 -0
- package/dist/core/audit/checks/docker.js +155 -0
- package/dist/core/audit/checks/docker.js.map +1 -0
- package/dist/core/audit/checks/filesystem.d.ts +7 -0
- package/dist/core/audit/checks/filesystem.d.ts.map +1 -0
- package/dist/core/audit/checks/filesystem.js +117 -0
- package/dist/core/audit/checks/filesystem.js.map +1 -0
- package/dist/core/audit/checks/firewall.d.ts +7 -0
- package/dist/core/audit/checks/firewall.d.ts.map +1 -0
- package/dist/core/audit/checks/firewall.js +88 -0
- package/dist/core/audit/checks/firewall.js.map +1 -0
- package/dist/core/audit/checks/index.d.ts +22 -0
- package/dist/core/audit/checks/index.d.ts.map +1 -0
- package/dist/core/audit/checks/index.js +63 -0
- package/dist/core/audit/checks/index.js.map +1 -0
- package/dist/core/audit/checks/kernel.d.ts +7 -0
- package/dist/core/audit/checks/kernel.d.ts.map +1 -0
- package/dist/core/audit/checks/kernel.js +113 -0
- package/dist/core/audit/checks/kernel.js.map +1 -0
- package/dist/core/audit/checks/logging.d.ts +7 -0
- package/dist/core/audit/checks/logging.d.ts.map +1 -0
- package/dist/core/audit/checks/logging.js +110 -0
- package/dist/core/audit/checks/logging.js.map +1 -0
- package/dist/core/audit/checks/network.d.ts +7 -0
- package/dist/core/audit/checks/network.d.ts.map +1 -0
- package/dist/core/audit/checks/network.js +118 -0
- package/dist/core/audit/checks/network.js.map +1 -0
- package/dist/core/audit/checks/ssh.d.ts +7 -0
- package/dist/core/audit/checks/ssh.d.ts.map +1 -0
- package/dist/core/audit/checks/ssh.js +109 -0
- package/dist/core/audit/checks/ssh.js.map +1 -0
- package/dist/core/audit/checks/updates.d.ts +7 -0
- package/dist/core/audit/checks/updates.d.ts.map +1 -0
- package/dist/core/audit/checks/updates.js +97 -0
- package/dist/core/audit/checks/updates.js.map +1 -0
- package/dist/core/audit/commands.d.ts +28 -0
- package/dist/core/audit/commands.d.ts.map +1 -0
- package/dist/core/audit/commands.js +165 -0
- package/dist/core/audit/commands.js.map +1 -0
- package/dist/core/audit/fix.d.ts +46 -0
- package/dist/core/audit/fix.d.ts.map +1 -0
- package/dist/core/audit/fix.js +146 -0
- package/dist/core/audit/fix.js.map +1 -0
- package/dist/core/audit/formatters/badge.d.ts +11 -0
- package/dist/core/audit/formatters/badge.d.ts.map +1 -0
- package/dist/core/audit/formatters/badge.js +46 -0
- package/dist/core/audit/formatters/badge.js.map +1 -0
- package/dist/core/audit/formatters/index.d.ts +22 -0
- package/dist/core/audit/formatters/index.d.ts.map +1 -0
- package/dist/core/audit/formatters/index.js +38 -0
- package/dist/core/audit/formatters/index.js.map +1 -0
- package/dist/core/audit/formatters/json.d.ts +8 -0
- package/dist/core/audit/formatters/json.d.ts.map +1 -0
- package/dist/core/audit/formatters/json.js +9 -0
- package/dist/core/audit/formatters/json.js.map +1 -0
- package/dist/core/audit/formatters/report.d.ts +14 -0
- package/dist/core/audit/formatters/report.d.ts.map +1 -0
- package/dist/core/audit/formatters/report.js +156 -0
- package/dist/core/audit/formatters/report.js.map +1 -0
- package/dist/core/audit/formatters/summary.d.ts +10 -0
- package/dist/core/audit/formatters/summary.d.ts.map +1 -0
- package/dist/core/audit/formatters/summary.js +45 -0
- package/dist/core/audit/formatters/summary.js.map +1 -0
- package/dist/core/audit/formatters/terminal.d.ts +11 -0
- package/dist/core/audit/formatters/terminal.d.ts.map +1 -0
- package/dist/core/audit/formatters/terminal.js +92 -0
- package/dist/core/audit/formatters/terminal.js.map +1 -0
- package/dist/core/audit/history.d.ts +22 -0
- package/dist/core/audit/history.d.ts.map +1 -0
- package/dist/core/audit/history.js +108 -0
- package/dist/core/audit/history.js.map +1 -0
- package/dist/core/audit/index.d.ts +17 -0
- package/dist/core/audit/index.d.ts.map +1 -0
- package/dist/core/audit/index.js +59 -0
- package/dist/core/audit/index.js.map +1 -0
- package/dist/core/audit/quickwin.d.ts +16 -0
- package/dist/core/audit/quickwin.d.ts.map +1 -0
- package/dist/core/audit/quickwin.js +67 -0
- package/dist/core/audit/quickwin.js.map +1 -0
- package/dist/core/audit/scoring.d.ts +21 -0
- package/dist/core/audit/scoring.d.ts.map +1 -0
- package/dist/core/audit/scoring.js +44 -0
- package/dist/core/audit/scoring.js.map +1 -0
- package/dist/core/audit/types.d.ts +47 -0
- package/dist/core/audit/types.d.ts.map +1 -0
- package/dist/core/audit/types.js +6 -0
- package/dist/core/audit/types.js.map +1 -0
- package/dist/core/audit/watch.d.ts +19 -0
- package/dist/core/audit/watch.d.ts.map +1 -0
- package/dist/core/audit/watch.js +104 -0
- package/dist/core/audit/watch.js.map +1 -0
- package/dist/core/auth.d.ts +6 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +80 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/backup.d.ts.map +1 -1
- package/dist/core/backup.js +52 -85
- package/dist/core/backup.js.map +1 -1
- package/dist/core/deploy.d.ts +10 -1
- package/dist/core/deploy.d.ts.map +1 -1
- package/dist/core/deploy.js +296 -260
- package/dist/core/deploy.js.map +1 -1
- package/dist/core/firewall.d.ts +5 -2
- package/dist/core/firewall.d.ts.map +1 -1
- package/dist/core/firewall.js +14 -5
- package/dist/core/firewall.js.map +1 -1
- package/dist/core/logs.d.ts.map +1 -1
- package/dist/core/logs.js +5 -4
- package/dist/core/logs.js.map +1 -1
- package/dist/core/maintain.d.ts +1 -1
- package/dist/core/maintain.d.ts.map +1 -1
- package/dist/core/maintain.js +4 -4
- package/dist/core/maintain.js.map +1 -1
- package/dist/core/manage.d.ts +1 -1
- package/dist/core/manage.d.ts.map +1 -1
- package/dist/core/manage.js +20 -9
- package/dist/core/manage.js.map +1 -1
- package/dist/core/status.d.ts +1 -1
- package/dist/core/status.d.ts.map +1 -1
- package/dist/core/status.js +7 -4
- package/dist/core/status.js.map +1 -1
- package/dist/core/tokenBuffer.d.ts +5 -0
- package/dist/core/tokenBuffer.d.ts.map +1 -0
- package/dist/core/tokenBuffer.js +36 -0
- package/dist/core/tokenBuffer.js.map +1 -0
- package/dist/core/tokens.d.ts +4 -0
- package/dist/core/tokens.d.ts.map +1 -1
- package/dist/core/tokens.js +24 -1
- package/dist/core/tokens.js.map +1 -1
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/serverAudit.d.ts +15 -0
- package/dist/mcp/tools/serverAudit.d.ts.map +1 -0
- package/dist/mcp/tools/serverAudit.js +68 -0
- package/dist/mcp/tools/serverAudit.js.map +1 -0
- package/dist/mcp/tools/serverInfo.d.ts.map +1 -1
- package/dist/mcp/tools/serverInfo.js +27 -15
- package/dist/mcp/tools/serverInfo.js.map +1 -1
- package/dist/mcp/tools/serverManage.js +2 -2
- package/dist/mcp/tools/serverManage.js.map +1 -1
- package/dist/mcp/tools/serverSecure.d.ts.map +1 -1
- package/dist/mcp/tools/serverSecure.js +10 -6
- package/dist/mcp/tools/serverSecure.js.map +1 -1
- package/dist/providers/base.d.ts +13 -0
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +27 -0
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/digitalocean.d.ts.map +1 -1
- package/dist/providers/digitalocean.js +27 -27
- package/dist/providers/digitalocean.js.map +1 -1
- package/dist/providers/hetzner.d.ts.map +1 -1
- package/dist/providers/hetzner.js +28 -28
- package/dist/providers/hetzner.js.map +1 -1
- package/dist/providers/linode.d.ts.map +1 -1
- package/dist/providers/linode.js +28 -29
- package/dist/providers/linode.js.map +1 -1
- package/dist/providers/vultr.d.ts.map +1 -1
- package/dist/providers/vultr.js +27 -27
- package/dist/providers/vultr.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/cloudInit.d.ts +0 -1
- package/dist/utils/cloudInit.d.ts.map +1 -1
- package/dist/utils/cloudInit.js +1 -71
- package/dist/utils/cloudInit.js.map +1 -1
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +23 -2
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/ssh.d.ts +9 -1
- package/dist/utils/ssh.d.ts.map +1 -1
- package/dist/utils/ssh.js +24 -11
- package/dist/utils/ssh.js.map +1 -1
- package/dist/utils/updateCheck.js +1 -1
- package/dist/utils/updateCheck.js.map +1 -1
- package/dist/utils/yamlConfig.d.ts.map +1 -1
- package/dist/utils/yamlConfig.js +4 -1
- package/dist/utils/yamlConfig.js.map +1 -1
- package/package.json +7 -3
- package/dist/utils/logo.d.ts +0 -2
- package/dist/utils/logo.d.ts.map +0 -1
- package/dist/utils/logo.js +0 -10
- package/dist/utils/logo.js.map +0 -1
package/README.md
CHANGED
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|

|
|
15
15
|

|
|
16
16
|
[](https://socket.dev/npm/package/kastell)
|
|
17
|
-
[](https://kastell.dev)
|
|
18
|
-
|
|
19
17
|
## Why Kastell Exists
|
|
20
18
|
|
|
21
19
|
Most self-hosted servers break because:
|
|
@@ -45,7 +43,7 @@ Running `kastell` without any arguments launches an **interactive search menu**
|
|
|
45
43
|
██║ ██╗ ██║ ██║ ███████║ ██║ ███████╗███████╗███████╗
|
|
46
44
|
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚══════╝╚══════╝
|
|
47
45
|
|
|
48
|
-
KASTELL v1.
|
|
46
|
+
KASTELL v1.5.2 · Your infrastructure, fortified.
|
|
49
47
|
|
|
50
48
|
$ kastell init --template production → deploy a new server
|
|
51
49
|
$ kastell status --all → check all servers
|
|
@@ -150,6 +148,22 @@ kastell secure setup my-server # SSH hardening + fail2ban
|
|
|
150
148
|
kastell domain add my-server --domain example.com # Set domain + SSL
|
|
151
149
|
```
|
|
152
150
|
|
|
151
|
+
### Security Audit
|
|
152
|
+
```bash
|
|
153
|
+
kastell audit my-server # Full security audit (9 categories, 46+ checks)
|
|
154
|
+
kastell audit my-server --json # JSON output for automation
|
|
155
|
+
kastell audit my-server --threshold 70 # Exit code 1 if score below threshold
|
|
156
|
+
kastell audit my-server --fix # Interactive fix mode (prompts per severity)
|
|
157
|
+
kastell audit my-server --fix --dry-run # Preview fixes without executing
|
|
158
|
+
kastell audit my-server --watch # Re-audit every 5 min, show only changes
|
|
159
|
+
kastell audit my-server --watch 60 # Custom interval (60 seconds)
|
|
160
|
+
kastell audit --host root@1.2.3.4 # Audit unregistered server
|
|
161
|
+
kastell audit my-server --badge # SVG badge output
|
|
162
|
+
kastell audit my-server --report html # Full HTML report
|
|
163
|
+
kastell audit my-server --score-only # Just the score (CI-friendly)
|
|
164
|
+
kastell audit my-server --summary # Compact dashboard view
|
|
165
|
+
```
|
|
166
|
+
|
|
153
167
|
### Monitor & Debug
|
|
154
168
|
```bash
|
|
155
169
|
kastell monitor my-server # CPU, RAM, disk usage
|
|
@@ -163,20 +177,20 @@ kastell doctor # Check local environment
|
|
|
163
177
|
|
|
164
178
|
| Provider | Status | Regions | Starting Price |
|
|
165
179
|
|----------|--------|---------|---------------|
|
|
166
|
-
| [Hetzner Cloud](https://hetzner.cloud) | Stable | EU, US |
|
|
180
|
+
| [Hetzner Cloud](https://hetzner.cloud) | Stable | EU, US | ~€4/mo |
|
|
167
181
|
| [DigitalOcean](https://digitalocean.com) | Stable | Global | ~$18/mo |
|
|
168
|
-
| [Vultr](https://vultr.com) | Stable | Global | ~$
|
|
169
|
-
| [Linode (Akamai)](https://linode.com) | Beta | Global | ~$
|
|
182
|
+
| [Vultr](https://vultr.com) | Stable | Global | ~$12/mo |
|
|
183
|
+
| [Linode (Akamai)](https://linode.com) | Beta | Global | ~$12/mo |
|
|
170
184
|
|
|
171
|
-
> Prices reflect the
|
|
185
|
+
> Prices reflect the cheapest plan with at least 2 GB RAM (required by Coolify and Dokploy). Bare mode has no minimum requirements -- plans start from ~$2.50/mo depending on provider. You can choose a different size during setup. Linode support is in beta -- community testing welcome.
|
|
172
186
|
|
|
173
187
|
## Supported Platforms
|
|
174
188
|
|
|
175
|
-
| Platform | Mode Flag | Description |
|
|
176
|
-
|
|
177
|
-
| Coolify | `--mode coolify` (default) | Docker-based PaaS |
|
|
178
|
-
| Dokploy | `--mode dokploy` | Docker Swarm-based PaaS |
|
|
179
|
-
| Bare | `--mode bare` | Generic VPS
|
|
189
|
+
| Platform | Mode Flag | Min RAM | Min CPU | Description |
|
|
190
|
+
|----------|-----------|---------|---------|-------------|
|
|
191
|
+
| Coolify | `--mode coolify` (default) | 2 GB | 2 vCPU | Docker-based PaaS (port 8000) |
|
|
192
|
+
| Dokploy | `--mode dokploy` | 2 GB | 2 vCPU | Docker Swarm-based PaaS (port 3000) |
|
|
193
|
+
| Bare | `--mode bare` | — | — | Generic VPS, no platform overhead |
|
|
180
194
|
|
|
181
195
|
Kastell uses a **PlatformAdapter** architecture -- the same commands (`update`, `maintain`, `logs`, `health`) work across all platforms. The platform is stored in your server record and auto-detected on each command.
|
|
182
196
|
|
|
@@ -294,15 +308,41 @@ Available tools:
|
|
|
294
308
|
| `server_secure` | secure, firewall, domain | SSH hardening, firewall rules, domain/SSL management (10 subcommands) |
|
|
295
309
|
| `server_backup` | backup, snapshot | Backup/restore databases and create/manage VPS snapshots |
|
|
296
310
|
| `server_provision` | create | Provision new servers on cloud providers |
|
|
311
|
+
| `server_audit` | audit | Run security audit with summary/json/score output formats |
|
|
297
312
|
|
|
298
313
|
> All destructive operations (destroy, restore, snapshot-delete, provision, restart, maintain, snapshot-create) require `SAFE_MODE=false` to execute.
|
|
299
314
|
|
|
315
|
+
## CI/CD Integration
|
|
316
|
+
|
|
317
|
+
Use `kastell audit` in your CI pipeline to enforce security baselines:
|
|
318
|
+
|
|
319
|
+
```yaml
|
|
320
|
+
# .github/workflows/security-audit.yml
|
|
321
|
+
name: Security Audit
|
|
322
|
+
on:
|
|
323
|
+
schedule:
|
|
324
|
+
- cron: '0 6 * * 1' # Weekly Monday 6 AM
|
|
325
|
+
workflow_dispatch:
|
|
326
|
+
jobs:
|
|
327
|
+
audit:
|
|
328
|
+
runs-on: ubuntu-latest
|
|
329
|
+
steps:
|
|
330
|
+
- uses: actions/checkout@v4
|
|
331
|
+
- run: npm install -g kastell
|
|
332
|
+
- run: kastell audit --host root@${{ secrets.SERVER_IP }} --threshold 70 --json > audit-result.json
|
|
333
|
+
- uses: actions/upload-artifact@v4
|
|
334
|
+
with:
|
|
335
|
+
name: audit-report
|
|
336
|
+
path: audit-result.json
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
The `--threshold` flag causes a non-zero exit code when the score falls below the target, failing the CI job automatically.
|
|
340
|
+
|
|
300
341
|
## What's Next
|
|
301
342
|
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
-
|
|
305
|
-
- Plugin ecosystem for AI IDEs (v2.0)
|
|
343
|
+
- kastell.dev website
|
|
344
|
+
- Guard daemon and fleet management
|
|
345
|
+
- Plugin ecosystem for AI IDEs
|
|
306
346
|
|
|
307
347
|
## Philosophy
|
|
308
348
|
|
package/README.tr.md
CHANGED
|
@@ -14,8 +14,6 @@
|
|
|
14
14
|

|
|
15
15
|

|
|
16
16
|
[](https://socket.dev/npm/package/kastell)
|
|
17
|
-
[](https://kastell.dev)
|
|
18
|
-
|
|
19
17
|
## Kastell Neden Var?
|
|
20
18
|
|
|
21
19
|
Self-hosted sunucuların çoğu şu nedenlerle çöker:
|
|
@@ -45,7 +43,7 @@ npx kastell
|
|
|
45
43
|
██║ ██╗ ██║ ██║ ███████║ ██║ ███████╗███████╗███████╗
|
|
46
44
|
╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚══════╝╚══════╝╚══════╝
|
|
47
45
|
|
|
48
|
-
KASTELL v1.
|
|
46
|
+
KASTELL v1.5.1 · Your infrastructure, fortified.
|
|
49
47
|
|
|
50
48
|
$ kastell init --template production → deploy a new server
|
|
51
49
|
$ kastell status --all → check all servers
|
|
@@ -150,6 +148,22 @@ kastell secure setup sunucum # SSH sıkılaştırma + fail2ban
|
|
|
150
148
|
kastell domain add sunucum --domain ornek.com # Domain + SSL ayarla
|
|
151
149
|
```
|
|
152
150
|
|
|
151
|
+
### Güvenlik Denetimi
|
|
152
|
+
```bash
|
|
153
|
+
kastell audit sunucum # Tam güvenlik denetimi (9 kategori, 46+ kontrol)
|
|
154
|
+
kastell audit sunucum --json # Otomasyon için JSON çıktısı
|
|
155
|
+
kastell audit sunucum --threshold 70 # Skor eşiğin altındaysa exit code 1
|
|
156
|
+
kastell audit sunucum --fix # İnteraktif düzeltme modu (önem derecesine göre)
|
|
157
|
+
kastell audit sunucum --fix --dry-run # Düzeltmeleri çalıştırmadan önizle
|
|
158
|
+
kastell audit sunucum --watch # 5 dk aralıkla tekrar denetle, sadece değişiklikleri göster
|
|
159
|
+
kastell audit sunucum --watch 60 # Özel aralık (60 saniye)
|
|
160
|
+
kastell audit --host root@1.2.3.4 # Kayıtlı olmayan sunucuyu denetle
|
|
161
|
+
kastell audit sunucum --badge # SVG rozet çıktısı
|
|
162
|
+
kastell audit sunucum --report html # Tam HTML raporu
|
|
163
|
+
kastell audit sunucum --score-only # Sadece skor (CI uyumlu)
|
|
164
|
+
kastell audit sunucum --summary # Kompakt özet görünümü
|
|
165
|
+
```
|
|
166
|
+
|
|
153
167
|
### İzleme ve Hata Ayıklama
|
|
154
168
|
```bash
|
|
155
169
|
kastell monitor sunucum # CPU, RAM, disk kullanımı
|
|
@@ -163,20 +177,20 @@ kastell doctor # Yerel ortam kontrolü
|
|
|
163
177
|
|
|
164
178
|
| Sağlayıcı | Durum | Bölgeler | Başlangıç Fiyatı |
|
|
165
179
|
|-----------|-------|----------|------------------|
|
|
166
|
-
| [Hetzner Cloud](https://hetzner.cloud) | Kararlı | Avrupa, ABD |
|
|
180
|
+
| [Hetzner Cloud](https://hetzner.cloud) | Kararlı | Avrupa, ABD | ~€4/ay |
|
|
167
181
|
| [DigitalOcean](https://digitalocean.com) | Kararlı | Küresel | ~$18/ay |
|
|
168
|
-
| [Vultr](https://vultr.com) | Kararlı | Küresel | ~$
|
|
169
|
-
| [Linode (Akamai)](https://linode.com) | Beta | Küresel | ~$
|
|
182
|
+
| [Vultr](https://vultr.com) | Kararlı | Küresel | ~$12/ay |
|
|
183
|
+
| [Linode (Akamai)](https://linode.com) | Beta | Küresel | ~$12/ay |
|
|
170
184
|
|
|
171
|
-
> Fiyatlar
|
|
185
|
+
> Fiyatlar en az 2 GB RAM'e sahip en ucuz planı yansıtır (Coolify ve Dokploy gereksinimi). Bare modda minimum gereksinim yoktur -- sağlayıcıya göre ~$2.50/ay'dan başlayan planlar kullanılabilir. Kurulum sırasında farklı boyut seçebilirsiniz. Linode desteği beta aşamasındadır -- topluluk testleri memnuniyetle karşılanır.
|
|
172
186
|
|
|
173
187
|
## Desteklenen Platformlar
|
|
174
188
|
|
|
175
|
-
| Platform | Mod Bayrağı | Açıklama |
|
|
176
|
-
|
|
177
|
-
| Coolify | `--mode coolify` (varsayılan) | Docker tabanlı PaaS |
|
|
178
|
-
| Dokploy | `--mode dokploy` | Docker Swarm tabanlı PaaS |
|
|
179
|
-
| Bare | `--mode bare` | Genel VPS
|
|
189
|
+
| Platform | Mod Bayrağı | Min RAM | Min CPU | Açıklama |
|
|
190
|
+
|----------|-------------|---------|---------|----------|
|
|
191
|
+
| Coolify | `--mode coolify` (varsayılan) | 2 GB | 2 vCPU | Docker tabanlı PaaS (port 8000) |
|
|
192
|
+
| Dokploy | `--mode dokploy` | 2 GB | 2 vCPU | Docker Swarm tabanlı PaaS (port 3000) |
|
|
193
|
+
| Bare | `--mode bare` | — | — | Genel VPS, platform yükü yok |
|
|
180
194
|
|
|
181
195
|
Kastell **PlatformAdapter** mimarisini kullanır -- aynı komutlar (`update`, `maintain`, `logs`, `health`) tüm platformlarda çalışır. Platform sunucu kaydınızda saklanır ve her komutta otomatik algılanır.
|
|
182
196
|
|
|
@@ -294,15 +308,34 @@ Mevcut araçlar:
|
|
|
294
308
|
| `server_secure` | secure, firewall, domain | SSH sıkılaştırma, güvenlik duvarı kuralları, domain/SSL yönetimi (10 alt komut) |
|
|
295
309
|
| `server_backup` | backup, snapshot | Veritabanı yedekle/geri yükle ve VPS snapshot oluştur/yönet |
|
|
296
310
|
| `server_provision` | create | Bulut sağlayıcılarda yeni sunucu oluştur |
|
|
311
|
+
| `server_audit` | audit | Güvenlik denetimi çalıştır (summary/json/score çıktı formatları) |
|
|
297
312
|
|
|
298
313
|
> Tüm yıkıcı işlemler (destroy, restore, snapshot-delete, provision, restart, maintain, snapshot-create) çalıştırılmak için `SAFE_MODE=false` gerektirir.
|
|
299
314
|
|
|
315
|
+
`kastell audit` komutunu CI pipeline'ınızda güvenlik eşiği zorunluluğu için kullanın:
|
|
316
|
+
|
|
317
|
+
```yaml
|
|
318
|
+
# .github/workflows/security-audit.yml
|
|
319
|
+
name: Güvenlik Denetimi
|
|
320
|
+
on:
|
|
321
|
+
schedule:
|
|
322
|
+
- cron: '0 6 * * 1' # Her Pazartesi 06:00
|
|
323
|
+
jobs:
|
|
324
|
+
audit:
|
|
325
|
+
runs-on: ubuntu-latest
|
|
326
|
+
steps:
|
|
327
|
+
- run: npx -y kastell audit --host root@${{ secrets.SERVER_IP }} --threshold 70 --json > audit-result.json
|
|
328
|
+
- uses: actions/upload-artifact@v4
|
|
329
|
+
with:
|
|
330
|
+
name: audit-report
|
|
331
|
+
path: audit-result.json
|
|
332
|
+
```
|
|
333
|
+
|
|
300
334
|
## Gelecek Planlar
|
|
301
335
|
|
|
302
|
-
-
|
|
303
|
-
-
|
|
304
|
-
-
|
|
305
|
-
- AI IDE'ler için plugin ekosistemi (v2.0)
|
|
336
|
+
- kastell.dev web sitesi
|
|
337
|
+
- Guard daemon ve fleet yönetimi
|
|
338
|
+
- AI IDE'ler için plugin ekosistemi
|
|
306
339
|
|
|
307
340
|
## Felsefe
|
|
308
341
|
|
package/SECURITY.md
CHANGED
|
@@ -24,9 +24,11 @@ Response time: Within 48 hours
|
|
|
24
24
|
## Security Architecture
|
|
25
25
|
|
|
26
26
|
### Token Handling (A2 — Sensitive Data Exposure)
|
|
27
|
-
-
|
|
27
|
+
- Token resolution chain: OS keychain (primary) -> environment variable (fallback) -> undefined
|
|
28
28
|
- Supported env vars: `HETZNER_TOKEN`, `DIGITALOCEAN_TOKEN`, `VULTR_TOKEN`, `LINODE_TOKEN`
|
|
29
|
-
-
|
|
29
|
+
- `kastell auth set <provider>` stores tokens in OS keychain (Windows Credential Manager, macOS Keychain, Linux Secret Service)
|
|
30
|
+
- Tokens are never written to disk in plaintext
|
|
31
|
+
- API tokens collected via interactive secure prompts (masked input) when neither keychain nor env var is available
|
|
30
32
|
- `sanitizedEnv()` strips all keys containing TOKEN, SECRET, PASSWORD, CREDENTIAL from child process environments before every `spawn`/`spawnSync`/`exec` call
|
|
31
33
|
- Provider errors sanitized via `stripSensitiveData()` — removes Authorization headers, request data, response headers, and non-whitelisted response body fields from axios errors before they propagate via error cause chains
|
|
32
34
|
|
|
@@ -102,13 +104,98 @@ All production dependencies use audited, versioned packages:
|
|
|
102
104
|
- Linode API v4 (via Axios, HTTPS)
|
|
103
105
|
- Model Context Protocol SDK (`@modelcontextprotocol/sdk`) for MCP server
|
|
104
106
|
- Zod for runtime input validation
|
|
105
|
-
- Coolify installed via `curl -fsSL
|
|
107
|
+
- Coolify installed via download-then-execute pattern: `curl -fsSL URL -o /tmp/install.sh && bash /tmp/install.sh` (prevents partial execution on network failure)
|
|
106
108
|
|
|
107
109
|
### Dev Dependencies
|
|
108
|
-
|
|
110
|
+
No known vulnerabilities (minimatch pinned to ^10.2.4 via npm overrides).
|
|
109
111
|
|
|
110
112
|
Security scan: https://socket.dev/npm/package/kastell
|
|
111
113
|
|
|
112
|
-
##
|
|
114
|
+
## Token Security
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
### OS Keychain Integration
|
|
117
|
+
|
|
118
|
+
Kastell stores provider API tokens in the OS keychain using `@napi-rs/keyring`:
|
|
119
|
+
|
|
120
|
+
- **Windows:** Windows Credential Manager
|
|
121
|
+
- **macOS:** Keychain
|
|
122
|
+
- **Linux:** Secret Service (GNOME Keyring, KWallet)
|
|
123
|
+
|
|
124
|
+
Use `kastell auth set <provider>` to store tokens securely. Use `kastell auth list` to see which providers have stored tokens (token values are never displayed). Use `kastell auth remove <provider>` to delete a stored token.
|
|
125
|
+
|
|
126
|
+
In CI/headless environments where no keychain is available, Kastell automatically falls back to environment variables.
|
|
127
|
+
|
|
128
|
+
### Subprocess Security
|
|
129
|
+
|
|
130
|
+
All child processes spawned by Kastell use `sanitizedEnv()` which strips TOKEN, SECRET, PASSWORD, and CREDENTIAL environment variables. This prevents accidental token leakage to SSH sessions and other subprocesses.
|
|
131
|
+
|
|
132
|
+
### Disabling Core Dumps (Recommended for MCP/Long-Running Mode)
|
|
133
|
+
|
|
134
|
+
Core dumps can expose in-memory tokens. Disable on production servers:
|
|
135
|
+
|
|
136
|
+
**Linux:**
|
|
137
|
+
- `ulimit -c 0` (current session)
|
|
138
|
+
- `echo "* hard core 0" >> /etc/security/limits.conf` (permanent)
|
|
139
|
+
|
|
140
|
+
**macOS:**
|
|
141
|
+
- `launchctl limit core 0 0`
|
|
142
|
+
|
|
143
|
+
### Swap Encryption (Recommended)
|
|
144
|
+
|
|
145
|
+
Unencrypted swap can expose in-memory tokens when pages are swapped to disk.
|
|
146
|
+
|
|
147
|
+
- **Linux:** Use encrypted swap (`cryptsetup` or `dm-crypt`)
|
|
148
|
+
- **macOS:** Encrypted by default with FileVault
|
|
149
|
+
- **Windows:** BitLocker encrypts the entire volume including pagefile
|
|
150
|
+
|
|
151
|
+
## Known Limitations & Accepted Risks
|
|
152
|
+
|
|
153
|
+
### 1. SSH Trust-On-First-Use (TOFU)
|
|
154
|
+
|
|
155
|
+
All SSH connections use `StrictHostKeyChecking=accept-new`. This automatically trusts the host key on first connection. A MITM attack during the very first SSH connection to a newly provisioned server would succeed silently.
|
|
156
|
+
|
|
157
|
+
**Why accepted:** Newly provisioned servers have unknown host keys — there is no known-good key to verify against. This is inherent to any server provisioning tool. Subsequent connections verify the stored key, so only the first connection is vulnerable.
|
|
158
|
+
|
|
159
|
+
**Mitigation:**
|
|
160
|
+
- Servers are provisioned via authenticated cloud provider APIs (HTTPS + API token), reducing the likelihood of a MITM during the narrow window between provision and first SSH connection.
|
|
161
|
+
- Set `KASTELL_STRICT_HOST_KEY=true` to reject unknown host keys entirely. This requires manual host key management but eliminates TOFU risk.
|
|
162
|
+
|
|
163
|
+
### 2. Health Checks Over HTTP
|
|
164
|
+
|
|
165
|
+
Coolify (`http://IP:8000`) and Dokploy (`http://IP:3000`) health checks use unencrypted HTTP. No sensitive data is sent — only an HTTP status code is checked.
|
|
166
|
+
|
|
167
|
+
**Why accepted:** Fresh Coolify/Dokploy installations only listen on HTTP. HTTPS requires a domain + SSL certificate, which is configured after initial setup via `kastell domain-set --ssl`.
|
|
168
|
+
|
|
169
|
+
**Mitigation:** When a domain is configured via `kastell domain add --domain example.com`, health checks automatically try HTTPS first, falling back to HTTP only if HTTPS fails. The domain is stored in the server record for persistent HTTPS health checks.
|
|
170
|
+
|
|
171
|
+
**Recommendation:** Always configure a domain with SSL for production access: `kastell domain add <server> --domain example.com`
|
|
172
|
+
|
|
173
|
+
### 3. API Token In-Memory Exposure
|
|
174
|
+
|
|
175
|
+
Provider API tokens are held as class properties in memory for the lifetime of the process.
|
|
176
|
+
|
|
177
|
+
**CLI mode (low risk):** Process runs for seconds, then exits. Token is freed with the process.
|
|
178
|
+
|
|
179
|
+
**MCP mode (elevated risk):** MCP server runs for hours. Token stays in memory and could theoretically be exposed via heap dump, core dump, or debugger attachment.
|
|
180
|
+
|
|
181
|
+
**Why accepted:** Node.js strings are immutable and managed by V8's garbage collector — there is no reliable way to zero a string in memory. Alternative approaches (Buffer-based token storage) would require changing all axios header construction and provide marginal benefit since `process.env` also holds the token in memory.
|
|
182
|
+
|
|
183
|
+
**Mitigations in place:**
|
|
184
|
+
- `sanitizedEnv()` strips tokens from all child process environments
|
|
185
|
+
- `stripSensitiveData()` removes Authorization headers from error objects
|
|
186
|
+
- Provider instances are not cached across MCP tool calls — each call creates a fresh instance, allowing GC to collect the previous one
|
|
187
|
+
- Tokens are never written to disk
|
|
188
|
+
|
|
189
|
+
**Future consideration:** Getter pattern that reads from `process.env` on each API call instead of storing as class property — reduces in-memory copies but does not eliminate the underlying exposure since `process.env` itself holds the value.
|
|
190
|
+
|
|
191
|
+
### 4. Remote Install Scripts
|
|
192
|
+
|
|
193
|
+
Coolify and Dokploy are installed via remote shell scripts downloaded over HTTPS. A compromised CDN or DNS hijack could serve a malicious install script.
|
|
194
|
+
|
|
195
|
+
**Why accepted:** This is the official installation method provided by both Coolify and Dokploy upstream projects. There are no published checksums to verify against.
|
|
196
|
+
|
|
197
|
+
**Mitigations in place:**
|
|
198
|
+
- HTTPS transport security (TLS certificate validation)
|
|
199
|
+
- Download-then-execute pattern (prevents partial execution on network interruption)
|
|
200
|
+
- **Script validation before execution:** Downloaded scripts are verified to start with a shebang (`#!`) and have a minimum size (>100 bytes) before being executed. A truncated, empty, or non-script response will be rejected.
|
|
201
|
+
- Install scripts are downloaded to `/tmp/` and cleaned up after execution
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, UpdateResult } from "./interface.js";
|
|
1
|
+
import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, PlatformRestoreResult, UpdateResult } from "./interface.js";
|
|
2
|
+
import type { BackupManifest } from "../types/index.js";
|
|
2
3
|
export declare class CoolifyAdapter implements PlatformAdapter {
|
|
3
4
|
readonly name = "coolify";
|
|
4
5
|
getCloudInit(serverName: string): string;
|
|
5
|
-
healthCheck(ip: string): Promise<HealthResult>;
|
|
6
|
+
healthCheck(ip: string, domain?: string): Promise<HealthResult>;
|
|
6
7
|
createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
|
|
8
|
+
restoreBackup(ip: string, backupPath: string, _manifest: BackupManifest): Promise<PlatformRestoreResult>;
|
|
7
9
|
getStatus(ip: string): Promise<PlatformStatusResult>;
|
|
8
10
|
update(ip: string): Promise<UpdateResult>;
|
|
9
|
-
getLogCommand(lines: number, follow: boolean): string;
|
|
10
11
|
private buildPgDumpCommand;
|
|
11
12
|
private buildConfigTarCommand;
|
|
12
13
|
private buildCleanupCommand;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coolify.d.ts","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"coolify.d.ts","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAmBxD,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAuElC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAuF1B,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,qBAAqB,CAAC;IAkI3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAM/C,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}
|
package/dist/adapters/coolify.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
1
|
import { mkdirSync, writeFileSync } from "fs";
|
|
3
2
|
import { join } from "path";
|
|
4
3
|
import { COOLIFY_UPDATE_CMD } from "../constants.js";
|
|
5
4
|
import { assertValidIp, sshExec } from "../utils/ssh.js";
|
|
6
|
-
import { formatTimestamp, getBackupDir, scpDownload, } from "../core/backup.js";
|
|
5
|
+
import { formatTimestamp, getBackupDir, scpDownload, scpUpload, buildStopCoolifyCommand, buildStartCoolifyCommand, buildStartDbCommand, buildRestoreDbCommand, buildRestoreConfigCommand, buildCleanupCommand, tryRestartCoolify, } from "../core/backup.js";
|
|
7
6
|
import { getErrorMessage, mapSshError, sanitizeStderr } from "../utils/errorMapper.js";
|
|
7
|
+
import { sharedHealthCheck, sharedUpdate, sharedGetStatus } from "./shared.js";
|
|
8
8
|
export class CoolifyAdapter {
|
|
9
9
|
name = "coolify";
|
|
10
10
|
getCloudInit(serverName) {
|
|
@@ -40,7 +40,7 @@ apt-get update -y
|
|
|
40
40
|
|
|
41
41
|
# Install Coolify
|
|
42
42
|
echo "Installing Coolify..."
|
|
43
|
-
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
|
|
43
|
+
curl -fsSL https://cdn.coollabs.io/coolify/install.sh -o /tmp/coolify-install.sh && head -c2 /tmp/coolify-install.sh | grep -q "#!" && [ "$(wc -c < /tmp/coolify-install.sh)" -gt 100 ] && bash /tmp/coolify-install.sh && rm -f /tmp/coolify-install.sh
|
|
44
44
|
|
|
45
45
|
# Wait for services
|
|
46
46
|
echo "Waiting for Coolify services to start..."
|
|
@@ -77,18 +77,8 @@ echo "Please wait 3-5 more minutes for Coolify to fully initialize."
|
|
|
77
77
|
echo "Then access your instance at: http://YOUR_SERVER_IP:8000"
|
|
78
78
|
`;
|
|
79
79
|
}
|
|
80
|
-
async healthCheck(ip) {
|
|
81
|
-
|
|
82
|
-
try {
|
|
83
|
-
await axios.get(`http://${ip}:8000`, {
|
|
84
|
-
timeout: 5000,
|
|
85
|
-
validateStatus: () => true,
|
|
86
|
-
});
|
|
87
|
-
return { status: "running" };
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
return { status: "not reachable" };
|
|
91
|
-
}
|
|
80
|
+
async healthCheck(ip, domain) {
|
|
81
|
+
return sharedHealthCheck(ip, 8000, domain);
|
|
92
82
|
}
|
|
93
83
|
async createBackup(ip, serverName, provider) {
|
|
94
84
|
assertValidIp(ip);
|
|
@@ -156,44 +146,123 @@ echo "Then access your instance at: http://YOUR_SERVER_IP:8000"
|
|
|
156
146
|
};
|
|
157
147
|
}
|
|
158
148
|
}
|
|
159
|
-
async
|
|
160
|
-
assertValidIp(ip);
|
|
161
|
-
const versionResult = await sshExec(ip, this.buildVersionCommand());
|
|
162
|
-
const platformVersion = versionResult.code === 0 ? versionResult.stdout.trim() : "unknown";
|
|
163
|
-
const health = await this.healthCheck(ip);
|
|
164
|
-
return {
|
|
165
|
-
platformVersion,
|
|
166
|
-
status: health.status,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
async update(ip) {
|
|
149
|
+
async restoreBackup(ip, backupPath, _manifest) {
|
|
170
150
|
assertValidIp(ip);
|
|
151
|
+
const steps = [];
|
|
171
152
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
153
|
+
// Upload backup files (before stopping Coolify -- safe to fail here)
|
|
154
|
+
const dbUpload = await scpUpload(ip, join(backupPath, "coolify-backup.sql.gz"), "/tmp/coolify-backup.sql.gz");
|
|
155
|
+
if (dbUpload.code !== 0) {
|
|
156
|
+
return {
|
|
157
|
+
success: false,
|
|
158
|
+
steps: [
|
|
159
|
+
{
|
|
160
|
+
name: "Upload database backup",
|
|
161
|
+
status: "failure",
|
|
162
|
+
error: sanitizeStderr(dbUpload.stderr),
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
error: "Failed to upload database backup",
|
|
166
|
+
};
|
|
175
167
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
168
|
+
steps.push({ name: "Upload database backup", status: "success" });
|
|
169
|
+
const configUpload = await scpUpload(ip, join(backupPath, "coolify-config.tar.gz"), "/tmp/coolify-config.tar.gz");
|
|
170
|
+
if (configUpload.code !== 0) {
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
steps: [
|
|
174
|
+
...steps,
|
|
175
|
+
{
|
|
176
|
+
name: "Upload config backup",
|
|
177
|
+
status: "failure",
|
|
178
|
+
error: sanitizeStderr(configUpload.stderr),
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
error: "Failed to upload config backup",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
steps.push({ name: "Upload config backup", status: "success" });
|
|
185
|
+
// Step 1: Stop Coolify
|
|
186
|
+
const stopResult = await sshExec(ip, buildStopCoolifyCommand());
|
|
187
|
+
if (stopResult.code !== 0) {
|
|
188
|
+
steps.push({
|
|
189
|
+
name: "Stop Coolify",
|
|
190
|
+
status: "failure",
|
|
191
|
+
error: sanitizeStderr(stopResult.stderr),
|
|
192
|
+
});
|
|
193
|
+
return { success: false, steps, error: "Failed to stop Coolify" };
|
|
194
|
+
}
|
|
195
|
+
steps.push({ name: "Stop Coolify", status: "success" });
|
|
196
|
+
// Step 2: Start DB only
|
|
197
|
+
const dbStartResult = await sshExec(ip, buildStartDbCommand());
|
|
198
|
+
if (dbStartResult.code !== 0) {
|
|
199
|
+
steps.push({
|
|
200
|
+
name: "Start database",
|
|
201
|
+
status: "failure",
|
|
202
|
+
error: sanitizeStderr(dbStartResult.stderr),
|
|
203
|
+
});
|
|
204
|
+
await tryRestartCoolify(ip);
|
|
205
|
+
return { success: false, steps, error: "Failed to start database" };
|
|
206
|
+
}
|
|
207
|
+
steps.push({ name: "Start database", status: "success" });
|
|
208
|
+
// Step 3: Restore database
|
|
209
|
+
const restoreDbResult = await sshExec(ip, buildRestoreDbCommand());
|
|
210
|
+
if (restoreDbResult.code !== 0) {
|
|
211
|
+
steps.push({
|
|
212
|
+
name: "Restore database",
|
|
213
|
+
status: "failure",
|
|
214
|
+
error: sanitizeStderr(restoreDbResult.stderr),
|
|
215
|
+
});
|
|
216
|
+
await tryRestartCoolify(ip);
|
|
217
|
+
return { success: false, steps, error: "Database restore failed" };
|
|
218
|
+
}
|
|
219
|
+
steps.push({ name: "Restore database", status: "success" });
|
|
220
|
+
// Step 4: Restore config
|
|
221
|
+
const restoreConfigResult = await sshExec(ip, buildRestoreConfigCommand());
|
|
222
|
+
if (restoreConfigResult.code !== 0) {
|
|
223
|
+
steps.push({
|
|
224
|
+
name: "Restore config",
|
|
225
|
+
status: "failure",
|
|
226
|
+
error: sanitizeStderr(restoreConfigResult.stderr),
|
|
227
|
+
});
|
|
228
|
+
await tryRestartCoolify(ip);
|
|
229
|
+
return { success: false, steps, error: "Config restore failed" };
|
|
230
|
+
}
|
|
231
|
+
steps.push({ name: "Restore config", status: "success" });
|
|
232
|
+
// Step 5: Start Coolify
|
|
233
|
+
const startResult = await sshExec(ip, buildStartCoolifyCommand());
|
|
234
|
+
if (startResult.code !== 0) {
|
|
235
|
+
steps.push({
|
|
236
|
+
name: "Start Coolify",
|
|
237
|
+
status: "failure",
|
|
238
|
+
error: sanitizeStderr(startResult.stderr),
|
|
239
|
+
});
|
|
240
|
+
return { success: false, steps, error: "Failed to start Coolify" };
|
|
241
|
+
}
|
|
242
|
+
steps.push({ name: "Start Coolify", status: "success" });
|
|
243
|
+
// Cleanup remote (best-effort)
|
|
244
|
+
await sshExec(ip, buildCleanupCommand()).catch(() => { });
|
|
245
|
+
return { success: true, steps };
|
|
181
246
|
}
|
|
182
247
|
catch (error) {
|
|
183
248
|
const hint = mapSshError(error, ip);
|
|
184
249
|
return {
|
|
185
250
|
success: false,
|
|
251
|
+
steps,
|
|
186
252
|
error: getErrorMessage(error),
|
|
187
253
|
...(hint ? { hint } : {}),
|
|
188
254
|
};
|
|
189
255
|
}
|
|
190
256
|
}
|
|
191
|
-
|
|
192
|
-
return
|
|
257
|
+
async getStatus(ip) {
|
|
258
|
+
return sharedGetStatus(ip, this.buildVersionCommand(), 8000);
|
|
259
|
+
}
|
|
260
|
+
async update(ip) {
|
|
261
|
+
return sharedUpdate(ip, COOLIFY_UPDATE_CMD);
|
|
193
262
|
}
|
|
194
263
|
// ─── Private Helpers ────────────────────────────────────────────────────────
|
|
195
264
|
buildPgDumpCommand() {
|
|
196
|
-
return "docker exec coolify-db pg_dump -U coolify -d coolify | gzip > /tmp/coolify-backup.sql.gz";
|
|
265
|
+
return "set -o pipefail && docker exec coolify-db pg_dump -U coolify -d coolify | gzip > /tmp/coolify-backup.sql.gz";
|
|
197
266
|
}
|
|
198
267
|
buildConfigTarCommand() {
|
|
199
268
|
return "tar czf /tmp/coolify-config.tar.gz -C /data/coolify/source .env docker-compose.yml docker-compose.prod.yml 2>/dev/null || tar czf /tmp/coolify-config.tar.gz -C /data/coolify/source .env docker-compose.yml";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coolify.js","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"coolify.js","sourceRoot":"","sources":["../../src/adapters/coolify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, UpdateResult } from "./interface.js";
|
|
1
|
+
import type { PlatformAdapter, HealthResult, PlatformStatusResult, PlatformBackupResult, PlatformRestoreResult, UpdateResult } from "./interface.js";
|
|
2
|
+
import type { BackupManifest } from "../types/index.js";
|
|
2
3
|
export declare class DokployAdapter implements PlatformAdapter {
|
|
3
4
|
readonly name = "dokploy";
|
|
4
5
|
getCloudInit(serverName: string): string;
|
|
5
|
-
healthCheck(ip: string): Promise<HealthResult>;
|
|
6
|
+
healthCheck(ip: string, domain?: string): Promise<HealthResult>;
|
|
6
7
|
createBackup(ip: string, serverName: string, provider: string): Promise<PlatformBackupResult>;
|
|
8
|
+
restoreBackup(ip: string, backupPath: string, _manifest: BackupManifest): Promise<PlatformRestoreResult>;
|
|
7
9
|
getStatus(ip: string): Promise<PlatformStatusResult>;
|
|
8
10
|
update(ip: string): Promise<UpdateResult>;
|
|
9
|
-
|
|
11
|
+
private tryRestartDokploy;
|
|
10
12
|
private buildPgDumpCommand;
|
|
11
13
|
private buildConfigTarCommand;
|
|
12
14
|
private buildCleanupCommand;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dokploy.d.ts","sourceRoot":"","sources":["../../src/adapters/dokploy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dokploy.d.ts","sourceRoot":"","sources":["../../src/adapters/dokploy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAYxD,qBAAa,cAAe,YAAW,eAAe;IACpD,QAAQ,CAAC,IAAI,aAAa;IAE1B,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IA4ElC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;IAwF1B,aAAa,CACjB,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,qBAAqB,CAAC;IA2I3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIpD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;YAMjC,iBAAiB;IAQ/B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;CAG5B"}
|