Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c9eb0653d | |||
| ed6a35eb86 | |||
| 242677404b | |||
| 8c6159c596 | |||
| c210507951 | |||
| 0799efadae |
29
.gitignore
vendored
29
.gitignore
vendored
@@ -1,3 +1,30 @@
|
|||||||
|
.nogit/
|
||||||
|
|
||||||
|
# artifacts
|
||||||
|
coverage/
|
||||||
|
public/
|
||||||
|
|
||||||
|
# installs
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# caches
|
||||||
|
.yarn/
|
||||||
|
.cache/
|
||||||
|
.rpt2_cache
|
||||||
|
|
||||||
|
# builds
|
||||||
|
dist/
|
||||||
|
dist_*/
|
||||||
|
|
||||||
|
# rust
|
||||||
|
rust/target/
|
||||||
|
dist_rust/
|
||||||
|
|
||||||
|
# AI
|
||||||
|
.claude/
|
||||||
|
.serena/
|
||||||
|
|
||||||
|
#------# custom
|
||||||
# Deno
|
# Deno
|
||||||
.deno/
|
.deno/
|
||||||
deno.lock
|
deno.lock
|
||||||
@@ -50,4 +77,4 @@ logs/
|
|||||||
*.log
|
*.log
|
||||||
|
|
||||||
.playwright-mcp
|
.playwright-mcp
|
||||||
./dist/
|
./dist/
|
||||||
@@ -7,7 +7,12 @@
|
|||||||
"outputMode": "base64ts",
|
"outputMode": "base64ts",
|
||||||
"bundler": "esbuild",
|
"bundler": "esbuild",
|
||||||
"production": true,
|
"production": true,
|
||||||
"includeFiles": [{"from": "./html/index.html", "to": "index.html"}]
|
"includeFiles": [
|
||||||
|
{
|
||||||
|
"from": "./html/index.html",
|
||||||
|
"to": "index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -40,7 +45,12 @@
|
|||||||
"bundler": "esbuild",
|
"bundler": "esbuild",
|
||||||
"production": true,
|
"production": true,
|
||||||
"watchPatterns": ["./ts_web/**/*", "./html/**/*"],
|
"watchPatterns": ["./ts_web/**/*", "./html/**/*"],
|
||||||
"includeFiles": [{"from": "./html/index.html", "to": "index.html"}]
|
"includeFiles": [
|
||||||
|
{
|
||||||
|
"from": "./html/index.html",
|
||||||
|
"to": "index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"watchers": [
|
"watchers": [
|
||||||
@@ -53,5 +63,17 @@
|
|||||||
"runOnStart": true
|
"runOnStart": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"@git.zone/cli": {
|
||||||
|
"projectType": "denoSaaS",
|
||||||
|
"module": {
|
||||||
|
"githost": "code.foss.global",
|
||||||
|
"gitscope": "serve.zone",
|
||||||
|
"gitrepo": "onebox",
|
||||||
|
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
|
||||||
|
"npmPackagename": "@serve.zone/onebox",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@ship.zone/szci": {}
|
||||||
}
|
}
|
||||||
154
changelog.md
154
changelog.md
@@ -1,6 +1,31 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-24 - 1.24.2 - fix(deps)
|
||||||
|
bump runtime and build tool dependencies
|
||||||
|
|
||||||
|
- update @design.estate/dees-catalog to ^3.49.0
|
||||||
|
- update development tooling packages @git.zone/tsbundle, @git.zone/tsdeno, and @git.zone/tswatch
|
||||||
|
|
||||||
|
## 2026-03-24 - 1.24.1 - fix(repo)
|
||||||
|
migrate smart build config to .smartconfig.json and tidy repository metadata
|
||||||
|
|
||||||
|
- Rename npmextra.json to .smartconfig.json and extend it with CLI project metadata for the repository.
|
||||||
|
- Mark the package as private and add an empty pnpm overrides block in package.json.
|
||||||
|
- Expand .gitignore to cover common build artifacts, caches, install directories, and local tooling folders.
|
||||||
|
- Reformat changelog and README files for cleaner spacing and Markdown table alignment without changing documented behavior.
|
||||||
|
|
||||||
|
## 2026-03-24 - 1.24.0 - feat(backup)
|
||||||
|
|
||||||
|
add containerarchive-backed backup storage, restore, download, and pruning support
|
||||||
|
|
||||||
|
- add database support for archive snapshot IDs and stored size tracking for backups
|
||||||
|
- initialize and close the backup archive during onebox lifecycle startup and shutdown
|
||||||
|
- allow backup download and restore flows to work with archive snapshots as well as legacy file-based backups
|
||||||
|
- schedule daily archive pruning based on the most generous configured retention policy
|
||||||
|
- replace smarts3 with smartstorage for registry-backed S3-compatible storage
|
||||||
|
|
||||||
## 2026-03-21 - 1.23.0 - feat(appstore)
|
## 2026-03-21 - 1.23.0 - feat(appstore)
|
||||||
|
|
||||||
add remote app store templates with service upgrades and Redis/MariaDB platform support
|
add remote app store templates with service upgrades and Redis/MariaDB platform support
|
||||||
|
|
||||||
- introduces an App Store manager, API handlers, shared request types, and web UI flow for browsing remote templates and deploying services from template metadata
|
- introduces an App Store manager, API handlers, shared request types, and web UI flow for browsing remote templates and deploying services from template metadata
|
||||||
@@ -8,6 +33,7 @@ add remote app store templates with service upgrades and Redis/MariaDB platform
|
|||||||
- adds Redis and MariaDB platform service providers with provisioning plus backup and restore support, and exposes their requirements through service creation and app template config
|
- adds Redis and MariaDB platform service providers with provisioning plus backup and restore support, and exposes their requirements through service creation and app template config
|
||||||
|
|
||||||
## 2026-03-18 - 1.22.2 - fix(web-ui)
|
## 2026-03-18 - 1.22.2 - fix(web-ui)
|
||||||
|
|
||||||
stabilize app store service creation flow and add Ghost sqlite defaults
|
stabilize app store service creation flow and add Ghost sqlite defaults
|
||||||
|
|
||||||
- Defers App Store navigation to the services view to avoid destroying the current view during the deploy event handler.
|
- Defers App Store navigation to the services view to avoid destroying the current view during the deploy event handler.
|
||||||
@@ -16,10 +42,11 @@ stabilize app store service creation flow and add Ghost sqlite defaults
|
|||||||
- Removes obsolete Gitea CI and npm publish workflow definitions.
|
- Removes obsolete Gitea CI and npm publish workflow definitions.
|
||||||
|
|
||||||
## 2026-03-18 - 1.22.1 - fix(repo)
|
## 2026-03-18 - 1.22.1 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-18 - 1.22.0 - feat(web-appstore)
|
## 2026-03-18 - 1.22.0 - feat(web-appstore)
|
||||||
|
|
||||||
add an App Store view for quick service deployment from curated templates
|
add an App Store view for quick service deployment from curated templates
|
||||||
|
|
||||||
- adds a new App Store tab to the web UI with curated Docker app templates
|
- adds a new App Store tab to the web UI with curated Docker app templates
|
||||||
@@ -28,6 +55,7 @@ add an App Store view for quick service deployment from curated templates
|
|||||||
- updates @serve.zone/catalog to ^2.8.0 to support the new app store view
|
- updates @serve.zone/catalog to ^2.8.0 to support the new app store view
|
||||||
|
|
||||||
## 2026-03-18 - 1.21.0 - feat(opsserver)
|
## 2026-03-18 - 1.21.0 - feat(opsserver)
|
||||||
|
|
||||||
add container workspace API and backend execution environment for services
|
add container workspace API and backend execution environment for services
|
||||||
|
|
||||||
- introduces typed workspace handlers for reading, writing, listing, creating, removing, and executing commands inside service containers
|
- introduces typed workspace handlers for reading, writing, listing, creating, removing, and executing commands inside service containers
|
||||||
@@ -35,6 +63,7 @@ add container workspace API and backend execution environment for services
|
|||||||
- extends Docker exec lookup to resolve Swarm service container IDs when a direct container ID is unavailable
|
- extends Docker exec lookup to resolve Swarm service container IDs when a direct container ID is unavailable
|
||||||
|
|
||||||
## 2026-03-17 - 1.20.0 - feat(ops-dashboard)
|
## 2026-03-17 - 1.20.0 - feat(ops-dashboard)
|
||||||
|
|
||||||
stream user service logs to the ops dashboard and resolve service containers for Docker log streaming
|
stream user service logs to the ops dashboard and resolve service containers for Docker log streaming
|
||||||
|
|
||||||
- add typed socket support for pushing live user service log entries to the web app
|
- add typed socket support for pushing live user service log entries to the web app
|
||||||
@@ -44,58 +73,61 @@ stream user service logs to the ops dashboard and resolve service containers for
|
|||||||
- bump @serve.zone/catalog to ^2.7.0
|
- bump @serve.zone/catalog to ^2.7.0
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.12 - fix(repo)
|
## 2026-03-17 - 1.19.12 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.11 - fix(repo)
|
## 2026-03-17 - 1.19.11 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.10 - fix(repo)
|
## 2026-03-17 - 1.19.10 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.9 - fix(repo)
|
## 2026-03-17 - 1.19.9 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.8 - fix(repo)
|
## 2026-03-17 - 1.19.8 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.7 - fix(repo)
|
## 2026-03-17 - 1.19.7 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.6 - fix(repository)
|
## 2026-03-17 - 1.19.6 - fix(repository)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.5 - fix(repo)
|
## 2026-03-17 - 1.19.5 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-17 - 1.19.4 - fix(repository)
|
## 2026-03-17 - 1.19.4 - fix(repository)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.19.3 - fix(repo)
|
## 2026-03-16 - 1.19.3 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.19.2 - fix(docs)
|
## 2026-03-16 - 1.19.2 - fix(docs)
|
||||||
|
|
||||||
remove outdated UI screenshot assets from project documentation
|
remove outdated UI screenshot assets from project documentation
|
||||||
|
|
||||||
- Deletes multiple PNG screenshots that documented previous dashboard, service form, and hello-world states.
|
- Deletes multiple PNG screenshots that documented previous dashboard, service form, and hello-world states.
|
||||||
- Reduces repository clutter by removing obsolete image assets no longer needed in docs.
|
- Reduces repository clutter by removing obsolete image assets no longer needed in docs.
|
||||||
|
|
||||||
## 2026-03-16 - 1.19.1 - fix(dashboard)
|
## 2026-03-16 - 1.19.1 - fix(dashboard)
|
||||||
|
|
||||||
add updated dashboard screenshots for refresh and resource usage states
|
add updated dashboard screenshots for refresh and resource usage states
|
||||||
|
|
||||||
- Adds new dashboard screenshots covering post-refresh, resource usage, and populated data views.
|
- Adds new dashboard screenshots covering post-refresh, resource usage, and populated data views.
|
||||||
- Updates visual assets to document current dashboard behavior and UI states.
|
- Updates visual assets to document current dashboard behavior and UI states.
|
||||||
|
|
||||||
## 2026-03-16 - 1.19.1 - fix(dashboard)
|
## 2026-03-16 - 1.19.1 - fix(dashboard)
|
||||||
|
|
||||||
add aggregated resource usage stats to the dashboard
|
add aggregated resource usage stats to the dashboard
|
||||||
|
|
||||||
- Aggregate CPU, memory, and network stats across all running user and platform service containers in getSystemStatus
|
- Aggregate CPU, memory, and network stats across all running user and platform service containers in getSystemStatus
|
||||||
@@ -104,6 +136,7 @@ add aggregated resource usage stats to the dashboard
|
|||||||
- Wire dashboard resource usage card to display real aggregated data from the backend
|
- Wire dashboard resource usage card to display real aggregated data from the backend
|
||||||
|
|
||||||
## 2026-03-16 - 1.19.0 - feat(opsserver,web)
|
## 2026-03-16 - 1.19.0 - feat(opsserver,web)
|
||||||
|
|
||||||
add real-time platform service log streaming to the dashboard
|
add real-time platform service log streaming to the dashboard
|
||||||
|
|
||||||
- stream running platform service container logs from the ops server to connected dashboard clients via TypedSocket
|
- stream running platform service container logs from the ops server to connected dashboard clients via TypedSocket
|
||||||
@@ -112,6 +145,7 @@ add real-time platform service log streaming to the dashboard
|
|||||||
- add the typedsocket dependency and update the catalog package for dashboard support
|
- add the typedsocket dependency and update the catalog package for dashboard support
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.5 - fix(platform-services)
|
## 2026-03-16 - 1.18.5 - fix(platform-services)
|
||||||
|
|
||||||
fix platform service detail view navigation and log display
|
fix platform service detail view navigation and log display
|
||||||
|
|
||||||
- Add back button to platform service detail view for returning to services list
|
- Add back button to platform service detail view for returning to services list
|
||||||
@@ -120,23 +154,25 @@ fix platform service detail view navigation and log display
|
|||||||
- Clear previous stats/logs state before fetching new platform service data
|
- Clear previous stats/logs state before fetching new platform service data
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.4 - fix(repo)
|
## 2026-03-16 - 1.18.4 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.3 - fix(deps)
|
## 2026-03-16 - 1.18.3 - fix(deps)
|
||||||
|
|
||||||
bump @serve.zone/catalog to ^2.6.1
|
bump @serve.zone/catalog to ^2.6.1
|
||||||
|
|
||||||
- Updates the @serve.zone/catalog runtime dependency from ^2.6.0 to ^2.6.1.
|
- Updates the @serve.zone/catalog runtime dependency from ^2.6.0 to ^2.6.1.
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.2 - fix(repo)
|
## 2026-03-16 - 1.18.2 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.1 - fix(repo)
|
## 2026-03-16 - 1.18.1 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.18.0 - feat(platform-services)
|
## 2026-03-16 - 1.18.0 - feat(platform-services)
|
||||||
|
|
||||||
add platform service log retrieval and display in the services UI
|
add platform service log retrieval and display in the services UI
|
||||||
|
|
||||||
- add typed request support in the ops server to fetch Docker logs for platform service containers
|
- add typed request support in the ops server to fetch Docker logs for platform service containers
|
||||||
@@ -144,18 +180,21 @@ add platform service log retrieval and display in the services UI
|
|||||||
- render platform service logs in the services detail view and add sidebar icons for main navigation tabs
|
- render platform service logs in the services detail view and add sidebar icons for main navigation tabs
|
||||||
|
|
||||||
## 2026-03-16 - 1.17.4 - fix(docs)
|
## 2026-03-16 - 1.17.4 - fix(docs)
|
||||||
|
|
||||||
add hello world running screenshot for documentation
|
add hello world running screenshot for documentation
|
||||||
|
|
||||||
- Adds a new PNG asset showing the application in a running hello world state.
|
- Adds a new PNG asset showing the application in a running hello world state.
|
||||||
- Supports project documentation or README usage without changing runtime behavior.
|
- Supports project documentation or README usage without changing runtime behavior.
|
||||||
|
|
||||||
## 2026-03-16 - 1.17.3 - fix(mongodb)
|
## 2026-03-16 - 1.17.3 - fix(mongodb)
|
||||||
|
|
||||||
downgrade the MongoDB service image to 4.4 and use the legacy mongo shell for container operations
|
downgrade the MongoDB service image to 4.4 and use the legacy mongo shell for container operations
|
||||||
|
|
||||||
- changes the default MongoDB container image from mongo:7 to mongo:4.4
|
- changes the default MongoDB container image from mongo:7 to mongo:4.4
|
||||||
- replaces mongosh with mongo for health checks, provisioning, and deprovisioning inside the container
|
- replaces mongosh with mongo for health checks, provisioning, and deprovisioning inside the container
|
||||||
|
|
||||||
## 2026-03-16 - 1.17.2 - fix(platform-services)
|
## 2026-03-16 - 1.17.2 - fix(platform-services)
|
||||||
|
|
||||||
provision ClickHouse, MinIO, and MongoDB resources via docker exec instead of host port access
|
provision ClickHouse, MinIO, and MongoDB resources via docker exec instead of host port access
|
||||||
|
|
||||||
- switch ClickHouse provisioning and teardown to in-container client commands to avoid host port mapping issues
|
- switch ClickHouse provisioning and teardown to in-container client commands to avoid host port mapping issues
|
||||||
@@ -163,10 +202,11 @@ provision ClickHouse, MinIO, and MongoDB resources via docker exec instead of ho
|
|||||||
- run MongoDB provisioning and deprovisioning through mongosh inside the container and improve docker exec failure reporting
|
- run MongoDB provisioning and deprovisioning through mongosh inside the container and improve docker exec failure reporting
|
||||||
|
|
||||||
## 2026-03-16 - 1.17.1 - fix(repo)
|
## 2026-03-16 - 1.17.1 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.17.0 - feat(web/services)
|
## 2026-03-16 - 1.17.0 - feat(web/services)
|
||||||
|
|
||||||
add deploy service action to the services view
|
add deploy service action to the services view
|
||||||
|
|
||||||
- Adds a prominent "Deploy Service" button to the services page header.
|
- Adds a prominent "Deploy Service" button to the services page header.
|
||||||
@@ -174,6 +214,7 @@ add deploy service action to the services view
|
|||||||
- Includes a new service creation form screenshot asset for the updated interface.
|
- Includes a new service creation form screenshot asset for the updated interface.
|
||||||
|
|
||||||
## 2026-03-16 - 1.16.0 - feat(services)
|
## 2026-03-16 - 1.16.0 - feat(services)
|
||||||
|
|
||||||
add platform service navigation and stats in the services UI
|
add platform service navigation and stats in the services UI
|
||||||
|
|
||||||
- add platform service stats state and fetch action
|
- add platform service stats state and fetch action
|
||||||
@@ -183,24 +224,28 @@ add platform service navigation and stats in the services UI
|
|||||||
- bump @serve.zone/catalog to ^2.6.0 for the new platform service UI components
|
- bump @serve.zone/catalog to ^2.6.0 for the new platform service UI components
|
||||||
|
|
||||||
## 2026-03-16 - 1.15.3 - fix(install)
|
## 2026-03-16 - 1.15.3 - fix(install)
|
||||||
|
|
||||||
refresh systemd service configuration before restarting previously running installations
|
refresh systemd service configuration before restarting previously running installations
|
||||||
|
|
||||||
- Re-enable the systemd service during updates so unit file changes are applied before restart
|
- Re-enable the systemd service during updates so unit file changes are applied before restart
|
||||||
- Add a log message indicating the service configuration is being refreshed
|
- Add a log message indicating the service configuration is being refreshed
|
||||||
|
|
||||||
## 2026-03-16 - 1.15.2 - fix(systemd)
|
## 2026-03-16 - 1.15.2 - fix(systemd)
|
||||||
|
|
||||||
set HOME and DENO_DIR for the systemd service environment
|
set HOME and DENO_DIR for the systemd service environment
|
||||||
|
|
||||||
- Adds HOME=/root to the generated onebox systemd unit
|
- Adds HOME=/root to the generated onebox systemd unit
|
||||||
- Adds DENO_DIR=/root/.cache/deno so Deno cache paths are available when running as a service
|
- Adds DENO_DIR=/root/.cache/deno so Deno cache paths are available when running as a service
|
||||||
|
|
||||||
## 2026-03-16 - 1.15.1 - fix(systemd)
|
## 2026-03-16 - 1.15.1 - fix(systemd)
|
||||||
|
|
||||||
move Docker installation and swarm initialization to systemd enable flow
|
move Docker installation and swarm initialization to systemd enable flow
|
||||||
|
|
||||||
- Ensures Docker is installed before writing and enabling the systemd unit that depends on docker.service.
|
- Ensures Docker is installed before writing and enabling the systemd unit that depends on docker.service.
|
||||||
- Removes Docker auto-installation from Onebox initialization so setup happens in the service management path.
|
- Removes Docker auto-installation from Onebox initialization so setup happens in the service management path.
|
||||||
|
|
||||||
## 2026-03-16 - 1.15.0 - feat(systemd)
|
## 2026-03-16 - 1.15.0 - feat(systemd)
|
||||||
|
|
||||||
replace smartdaemon-based service management with native systemd commands
|
replace smartdaemon-based service management with native systemd commands
|
||||||
|
|
||||||
- adds a dedicated OneboxSystemd manager for enabling, disabling, starting, stopping, checking status, and following logs
|
- adds a dedicated OneboxSystemd manager for enabling, disabling, starting, stopping, checking status, and following logs
|
||||||
@@ -208,28 +253,30 @@ replace smartdaemon-based service management with native systemd commands
|
|||||||
- removes the smartdaemon dependency and related service management code
|
- removes the smartdaemon dependency and related service management code
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.10 - fix(services)
|
## 2026-03-16 - 1.14.10 - fix(services)
|
||||||
|
|
||||||
stop auto-update monitoring during shutdown
|
stop auto-update monitoring during shutdown
|
||||||
|
|
||||||
- Track the auto-update polling interval in the services manager
|
- Track the auto-update polling interval in the services manager
|
||||||
- Clear the auto-update interval when Onebox shuts down to prevent background checks after shutdown
|
- Clear the auto-update interval when Onebox shuts down to prevent background checks after shutdown
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.9 - fix(repo)
|
## 2026-03-16 - 1.14.9 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.8 - fix(repo)
|
## 2026-03-16 - 1.14.8 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.7 - fix(repo)
|
## 2026-03-16 - 1.14.7 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.6 - fix(project)
|
## 2026-03-16 - 1.14.6 - fix(project)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.5 - fix(onebox)
|
## 2026-03-16 - 1.14.5 - fix(onebox)
|
||||||
|
|
||||||
move Docker auto-install and swarm initialization into Onebox startup flow
|
move Docker auto-install and swarm initialization into Onebox startup flow
|
||||||
|
|
||||||
- removes Docker setup from daemon service installation
|
- removes Docker setup from daemon service installation
|
||||||
@@ -237,22 +284,23 @@ move Docker auto-install and swarm initialization into Onebox startup flow
|
|||||||
- preserves automatic Docker Swarm initialization on fresh servers
|
- preserves automatic Docker Swarm initialization on fresh servers
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.4 - fix(repo)
|
## 2026-03-16 - 1.14.4 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.3 - fix(repo)
|
## 2026-03-16 - 1.14.3 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.2 - fix(repo)
|
## 2026-03-16 - 1.14.2 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.1 - fix(repo)
|
## 2026-03-16 - 1.14.1 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-16 - 1.14.0 - feat(daemon)
|
## 2026-03-16 - 1.14.0 - feat(daemon)
|
||||||
|
|
||||||
auto-install Docker and initialize Swarm during daemon service setup
|
auto-install Docker and initialize Swarm during daemon service setup
|
||||||
|
|
||||||
- Adds a Docker availability check before installing the Onebox daemon service
|
- Adds a Docker availability check before installing the Onebox daemon service
|
||||||
@@ -260,75 +308,83 @@ auto-install Docker and initialize Swarm during daemon service setup
|
|||||||
- Attempts to initialize Docker Swarm after installation and handles already-initialized environments gracefully
|
- Attempts to initialize Docker Swarm after installation and handles already-initialized environments gracefully
|
||||||
|
|
||||||
## 2026-03-16 - 1.13.17 - fix(ci)
|
## 2026-03-16 - 1.13.17 - fix(ci)
|
||||||
|
|
||||||
remove forced container image pulling from Gitea workflow jobs
|
remove forced container image pulling from Gitea workflow jobs
|
||||||
|
|
||||||
- Drops the `--pull always` container option from CI, npm publish, and release workflows.
|
- Drops the `--pull always` container option from CI, npm publish, and release workflows.
|
||||||
- Keeps workflow container images unchanged while avoiding forced pulls on every job run.
|
- Keeps workflow container images unchanged while avoiding forced pulls on every job run.
|
||||||
|
|
||||||
## 2026-03-16 - 1.13.16 - fix(ci)
|
## 2026-03-16 - 1.13.16 - fix(ci)
|
||||||
|
|
||||||
refresh workflow container images on every run and bump @apiclient.xyz/docker to ^5.1.1
|
refresh workflow container images on every run and bump @apiclient.xyz/docker to ^5.1.1
|
||||||
|
|
||||||
- add --pull always to CI, release, and npm publish workflow containers to avoid stale images
|
- add --pull always to CI, release, and npm publish workflow containers to avoid stale images
|
||||||
- update @apiclient.xyz/docker from ^5.1.0 to ^5.1.1 in deno.json
|
- update @apiclient.xyz/docker from ^5.1.0 to ^5.1.1 in deno.json
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.15 - fix(repo)
|
## 2026-03-15 - 1.13.15 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.14 - fix(repo)
|
## 2026-03-15 - 1.13.14 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.13 - fix(repo)
|
## 2026-03-15 - 1.13.13 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.12 - fix(ci)
|
## 2026-03-15 - 1.13.12 - fix(ci)
|
||||||
|
|
||||||
run pnpm install with --ignore-scripts in CI and release workflows
|
run pnpm install with --ignore-scripts in CI and release workflows
|
||||||
|
|
||||||
- Update CI workflow dependency installation steps to skip lifecycle scripts during builds.
|
- Update CI workflow dependency installation steps to skip lifecycle scripts during builds.
|
||||||
- Apply the same install change to the release workflow for consistent automation behavior.
|
- Apply the same install change to the release workflow for consistent automation behavior.
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.11 - fix(project)
|
## 2026-03-15 - 1.13.11 - fix(project)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.10 - fix(deps)
|
## 2026-03-15 - 1.13.10 - fix(deps)
|
||||||
|
|
||||||
bump @git.zone/tsdeno to ^1.2.0
|
bump @git.zone/tsdeno to ^1.2.0
|
||||||
|
|
||||||
- Updates the tsdeno development dependency from ^1.1.1 to ^1.2.0.
|
- Updates the tsdeno development dependency from ^1.1.1 to ^1.2.0.
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.9 - fix(repo)
|
## 2026-03-15 - 1.13.9 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.8 - fix(repo)
|
## 2026-03-15 - 1.13.8 - fix(repo)
|
||||||
no changes to commit
|
|
||||||
|
|
||||||
|
no changes to commit
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.7 - fix(repo)
|
## 2026-03-15 - 1.13.7 - fix(repo)
|
||||||
|
|
||||||
no changes to commit
|
no changes to commit
|
||||||
|
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.6 - fix(ci)
|
## 2026-03-15 - 1.13.6 - fix(ci)
|
||||||
|
|
||||||
correct workflow container image registry path
|
correct workflow container image registry path
|
||||||
|
|
||||||
- Update Gitea CI, release, and npm publish workflows to use the corrected ht-docker-node image path
|
- Update Gitea CI, release, and npm publish workflows to use the corrected ht-docker-node image path
|
||||||
- Align all workflow container references from hosttoday to host.today to prevent pipeline image resolution issues
|
- Align all workflow container references from hosttoday to host.today to prevent pipeline image resolution issues
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.5 - fix(workflows)
|
## 2026-03-15 - 1.13.5 - fix(workflows)
|
||||||
|
|
||||||
switch Gitea workflow containers from ht-docker-dbase to ht-docker-node
|
switch Gitea workflow containers from ht-docker-dbase to ht-docker-node
|
||||||
|
|
||||||
- Updates the CI, release, and npm publish workflows to use the Node-focused container image consistently.
|
- Updates the CI, release, and npm publish workflows to use the Node-focused container image consistently.
|
||||||
- Aligns workflow runtime images with the project's Node and Deno build and publish steps.
|
- Aligns workflow runtime images with the project's Node and Deno build and publish steps.
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.4 - fix(ci)
|
## 2026-03-15 - 1.13.4 - fix(ci)
|
||||||
|
|
||||||
run workflows in the shared build container and enable corepack for pnpm installs
|
run workflows in the shared build container and enable corepack for pnpm installs
|
||||||
|
|
||||||
- adds the ht-docker-dbase container image to CI, release, and npm publish workflows
|
- adds the ht-docker-dbase container image to CI, release, and npm publish workflows
|
||||||
- enables corepack before pnpm install in build and release jobs to ensure package manager availability
|
- enables corepack before pnpm install in build and release jobs to ensure package manager availability
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.3 - fix(build)
|
## 2026-03-15 - 1.13.3 - fix(build)
|
||||||
|
|
||||||
replace custom Deno compile scripts with tsdeno-based binary builds in CI and release workflows
|
replace custom Deno compile scripts with tsdeno-based binary builds in CI and release workflows
|
||||||
|
|
||||||
- adds @git.zone/tsdeno as a dev dependency and configures compile targets in npmextra.json
|
- adds @git.zone/tsdeno as a dev dependency and configures compile targets in npmextra.json
|
||||||
@@ -336,18 +392,21 @@ replace custom Deno compile scripts with tsdeno-based binary builds in CI and re
|
|||||||
- removes the legacy scripts/compile-all.sh script and points the compile task to tsdeno compile
|
- removes the legacy scripts/compile-all.sh script and points the compile task to tsdeno compile
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.2 - fix(scripts)
|
## 2026-03-15 - 1.13.2 - fix(scripts)
|
||||||
|
|
||||||
install production dependencies before compiling binaries and exclude local node_modules from builds
|
install production dependencies before compiling binaries and exclude local node_modules from builds
|
||||||
|
|
||||||
- Adds a dependency installation step using the application entrypoint before cross-platform compilation
|
- Adds a dependency installation step using the application entrypoint before cross-platform compilation
|
||||||
- Updates all deno compile targets to use --node-modules-dir=none to avoid bundling local node_modules
|
- Updates all deno compile targets to use --node-modules-dir=none to avoid bundling local node_modules
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.1 - fix(deno)
|
## 2026-03-15 - 1.13.1 - fix(deno)
|
||||||
|
|
||||||
remove nodeModulesDir from Deno configuration
|
remove nodeModulesDir from Deno configuration
|
||||||
|
|
||||||
- Drops the explicit nodeModulesDir setting from deno.json.
|
- Drops the explicit nodeModulesDir setting from deno.json.
|
||||||
- Keeps the package version unchanged at 1.13.0 while simplifying runtime configuration.
|
- Keeps the package version unchanged at 1.13.0 while simplifying runtime configuration.
|
||||||
|
|
||||||
## 2026-03-15 - 1.13.0 - feat(install)
|
## 2026-03-15 - 1.13.0 - feat(install)
|
||||||
|
|
||||||
improve installer with version selection, service restart handling, and upgrade documentation
|
improve installer with version selection, service restart handling, and upgrade documentation
|
||||||
|
|
||||||
- Adds installer command-line options for help, specific version selection, and custom install directory.
|
- Adds installer command-line options for help, specific version selection, and custom install directory.
|
||||||
@@ -355,12 +414,14 @@ improve installer with version selection, service restart handling, and upgrade
|
|||||||
- Preserves Onebox data directories, stops and restarts the systemd service during updates, and refreshes installation instructions in the README including upgrade usage.
|
- Preserves Onebox data directories, stops and restarts the systemd service during updates, and refreshes installation instructions in the README including upgrade usage.
|
||||||
|
|
||||||
## 2026-03-15 - 1.12.1 - fix(package.json)
|
## 2026-03-15 - 1.12.1 - fix(package.json)
|
||||||
|
|
||||||
update package metadata
|
update package metadata
|
||||||
|
|
||||||
- Single metadata-only file changed (+1, -1)
|
- Single metadata-only file changed (+1, -1)
|
||||||
- No source code or runtime behavior modified; safe patch release
|
- No source code or runtime behavior modified; safe patch release
|
||||||
|
|
||||||
## 2026-03-15 - 1.12.0 - feat(cli,release)
|
## 2026-03-15 - 1.12.0 - feat(cli,release)
|
||||||
|
|
||||||
add self-upgrade command and automate CI, release, and npm publishing workflows
|
add self-upgrade command and automate CI, release, and npm publishing workflows
|
||||||
|
|
||||||
- adds a new `onebox upgrade` CLI command that checks the latest release and reinstalls the current binary via the installer script
|
- adds a new `onebox upgrade` CLI command that checks the latest release and reinstalls the current binary via the installer script
|
||||||
@@ -368,6 +429,7 @@ add self-upgrade command and automate CI, release, and npm publishing workflows
|
|||||||
- adds a reusable release template describing installation options, supported platforms, and checksum availability
|
- adds a reusable release template describing installation options, supported platforms, and checksum availability
|
||||||
|
|
||||||
## 2026-03-03 - 1.11.0 - feat(services)
|
## 2026-03-03 - 1.11.0 - feat(services)
|
||||||
|
|
||||||
map backend service data to UI components, add stats & logs parsing, fetch service stats, and fix logs request param
|
map backend service data to UI components, add stats & logs parsing, fetch service stats, and fix logs request param
|
||||||
|
|
||||||
- Fix: rename service logs request property from 'lines' to 'tail' when calling typedRequest
|
- Fix: rename service logs request property from 'lines' to 'tail' when calling typedRequest
|
||||||
@@ -377,21 +439,24 @@ map backend service data to UI components, add stats & logs parsing, fetch servi
|
|||||||
- Parse and normalize logs into timestamp/message pairs for the detail view
|
- Parse and normalize logs into timestamp/message pairs for the detail view
|
||||||
|
|
||||||
## 2026-03-02 - 1.10.3 - fix(bin)
|
## 2026-03-02 - 1.10.3 - fix(bin)
|
||||||
|
|
||||||
make bin/onebox-wrapper.js executable
|
make bin/onebox-wrapper.js executable
|
||||||
|
|
||||||
- Metadata-only change: file mode updated for bin/onebox-wrapper.js to include the executable bit
|
- Metadata-only change: file mode updated for bin/onebox-wrapper.js to include the executable bit
|
||||||
- No source or behavior changes to the code
|
- No source or behavior changes to the code
|
||||||
|
|
||||||
## 2026-03-02 - 1.10.2 - fix(build)
|
## 2026-03-02 - 1.10.2 - fix(build)
|
||||||
|
|
||||||
update build/watch configuration, switch to esbuild bundler and tswatch, and bump catalog and tooling dependencies
|
update build/watch configuration, switch to esbuild bundler and tswatch, and bump catalog and tooling dependencies
|
||||||
|
|
||||||
- Switch watch script to 'tswatch' (replaced previous concurrently command invoking deno + tswatch).
|
- Switch watch script to 'tswatch' (replaced previous concurrently command invoking deno + tswatch).
|
||||||
- npmextra.json: set bundler to 'esbuild', enable production mode, include html/index.html in the bundle, and extend watchPatterns to include ./html/**/*.
|
- npmextra.json: set bundler to 'esbuild', enable production mode, include html/index.html in the bundle, and extend watchPatterns to include ./html/\*_/_.
|
||||||
- Backend watcher: expanded watch globs and changed command to include --unstable-ffi and runtime flags (--ephemeral --monitor); restart and debounce kept.
|
- Backend watcher: expanded watch globs and changed command to include --unstable-ffi and runtime flags (--ephemeral --monitor); restart and debounce kept.
|
||||||
- Bump runtime deps: @design.estate/dees-catalog -> ^3.43.3, @serve.zone/catalog -> ^2.5.0.
|
- Bump runtime deps: @design.estate/dees-catalog -> ^3.43.3, @serve.zone/catalog -> ^2.5.0.
|
||||||
- Bump devDependencies: @git.zone/tsbundle -> ^2.9.0, @git.zone/tswatch -> ^3.2.0.
|
- Bump devDependencies: @git.zone/tsbundle -> ^2.9.0, @git.zone/tswatch -> ^3.2.0.
|
||||||
|
|
||||||
## 2026-02-24 - 1.10.1 - fix(package.json)
|
## 2026-02-24 - 1.10.1 - fix(package.json)
|
||||||
|
|
||||||
update package metadata
|
update package metadata
|
||||||
|
|
||||||
- Single metadata-only file changed (+1 -1)
|
- Single metadata-only file changed (+1 -1)
|
||||||
@@ -399,6 +464,7 @@ update package metadata
|
|||||||
- Current package version is 1.10.0; recommend patch bump to 1.10.1
|
- Current package version is 1.10.0; recommend patch bump to 1.10.1
|
||||||
|
|
||||||
## 2026-02-24 - 1.10.0 - feat(opsserver)
|
## 2026-02-24 - 1.10.0 - feat(opsserver)
|
||||||
|
|
||||||
introduce OpsServer (TypedRequest API) and new lightweight web UI; replace legacy Angular UI and add typed interfaces
|
introduce OpsServer (TypedRequest API) and new lightweight web UI; replace legacy Angular UI and add typed interfaces
|
||||||
|
|
||||||
- Add OpsServer (ts/opsserver) with TypedRequest handlers for admin, services, platform, dns, domains, registry, network, backups, schedules, settings and logs.
|
- Add OpsServer (ts/opsserver) with TypedRequest handlers for admin, services, platform, dns, domains, registry, network, backups, schedules, settings and logs.
|
||||||
@@ -411,21 +477,24 @@ introduce OpsServer (TypedRequest API) and new lightweight web UI; replace legac
|
|||||||
- Note: This adds many new endpoints and internal API changes (TypedRequest-based); consumers of the old UI/HTTP endpoints should migrate to the new OpsServer TypedRequest API and web components.
|
- Note: This adds many new endpoints and internal API changes (TypedRequest-based); consumers of the old UI/HTTP endpoints should migrate to the new OpsServer TypedRequest API and web components.
|
||||||
|
|
||||||
## 2025-12-03 - 1.9.2 - fix(ui)
|
## 2025-12-03 - 1.9.2 - fix(ui)
|
||||||
|
|
||||||
Add VS Code configs for the UI workspace and normalize dark theme CSS variables
|
Add VS Code configs for the UI workspace and normalize dark theme CSS variables
|
||||||
|
|
||||||
- Add VS Code workspace files under ui/.vscode:
|
- Add VS Code workspace files under ui/.vscode:
|
||||||
- - extensions.json: recommend the Angular language support extension
|
- - extensions.json: recommend the Angular language support extension
|
||||||
- - launch.json: Chrome launch configurations for 'ng serve' and 'ng test' (preLaunchTask hooks)
|
- - launch.json: Chrome launch configurations for 'ng serve' and 'ng test' (preLaunchTask hooks)
|
||||||
- - tasks.json: npm 'start' and 'test' tasks with a background TypeScript problem matcher to improve dev workflow
|
- - tasks.json: npm 'start' and 'test' tasks with a background TypeScript problem matcher to improve dev workflow
|
||||||
- Update ui/src/styles.css dark theme variables to use neutral black/gray HSL values for background, foreground, cards, popovers, accents, borders, inputs and ring to improve contrast and consistency
|
- Update ui/src/styles.css dark theme variables to use neutral black/gray HSL values for background, foreground, cards, popovers, accents, borders, inputs and ring to improve contrast and consistency
|
||||||
|
|
||||||
## 2025-11-27 - 1.9.1 - fix(ui)
|
## 2025-11-27 - 1.9.1 - fix(ui)
|
||||||
|
|
||||||
Correct import success toast and add VS Code launch/tasks recommendations for the UI
|
Correct import success toast and add VS Code launch/tasks recommendations for the UI
|
||||||
|
|
||||||
- Fix backup import success toast in backups-tab.component to reference response.data.service.name (previously response.data.serviceName), preventing incorrect service name display.
|
- Fix backup import success toast in backups-tab.component to reference response.data.service.name (previously response.data.serviceName), preventing incorrect service name display.
|
||||||
- Add VS Code workspace settings for the UI: extensions recommendation, launch configurations for 'ng serve' and 'ng test', and npm tasks for start/test to simplify local development and debugging.
|
- Add VS Code workspace settings for the UI: extensions recommendation, launch configurations for 'ng serve' and 'ng test', and npm tasks for start/test to simplify local development and debugging.
|
||||||
|
|
||||||
## 2025-11-27 - 1.9.0 - feat(backups)
|
## 2025-11-27 - 1.9.0 - feat(backups)
|
||||||
|
|
||||||
Add backup import API and improve backup download/import flow in UI
|
Add backup import API and improve backup download/import flow in UI
|
||||||
|
|
||||||
- Backend: add /api/backups/import endpoint to accept multipart file uploads or JSON with a URL and import backups (saves temp file, validates .tar.enc, calls backupManager.restoreBackup in import mode).
|
- Backend: add /api/backups/import endpoint to accept multipart file uploads or JSON with a URL and import backups (saves temp file, validates .tar.enc, calls backupManager.restoreBackup in import mode).
|
||||||
@@ -435,6 +504,7 @@ Add backup import API and improve backup download/import flow in UI
|
|||||||
- Dev: add VS Code launch, tasks and recommended extensions for the ui workspace to simplify local development.
|
- Dev: add VS Code launch, tasks and recommended extensions for the ui workspace to simplify local development.
|
||||||
|
|
||||||
## 2025-11-27 - 1.8.0 - feat(backup)
|
## 2025-11-27 - 1.8.0 - feat(backup)
|
||||||
|
|
||||||
Add backup scheduling system with GFS retention, API and UI integration
|
Add backup scheduling system with GFS retention, API and UI integration
|
||||||
|
|
||||||
- Introduce backup scheduling subsystem (BackupScheduler) and integrate it into Onebox lifecycle (init & shutdown)
|
- Introduce backup scheduling subsystem (BackupScheduler) and integrate it into Onebox lifecycle (init & shutdown)
|
||||||
@@ -447,6 +517,7 @@ Add backup scheduling system with GFS retention, API and UI integration
|
|||||||
- Type and repository updates across codebase to support schedule-aware backups, schedule CRUD, and retention enforcement
|
- Type and repository updates across codebase to support schedule-aware backups, schedule CRUD, and retention enforcement
|
||||||
|
|
||||||
## 2025-11-27 - 1.7.0 - feat(backup)
|
## 2025-11-27 - 1.7.0 - feat(backup)
|
||||||
|
|
||||||
Add backup system: BackupManager, DB schema, API endpoints and UI support
|
Add backup system: BackupManager, DB schema, API endpoints and UI support
|
||||||
|
|
||||||
Introduce a complete service backup/restore subsystem with encrypted archives, database records and REST endpoints. Implements BackupManager with export/import for service config, platform resources (MongoDB, MinIO, ClickHouse), and Docker images; adds BackupRepository and migrations for backups table and include_image_in_backup; integrates backup flows into the HTTP API and the UI client; exposes backup password management and restore modes (restore/import/clone). Wire BackupManager into Onebox initialization.
|
Introduce a complete service backup/restore subsystem with encrypted archives, database records and REST endpoints. Implements BackupManager with export/import for service config, platform resources (MongoDB, MinIO, ClickHouse), and Docker images; adds BackupRepository and migrations for backups table and include_image_in_backup; integrates backup flows into the HTTP API and the UI client; exposes backup password management and restore modes (restore/import/clone). Wire BackupManager into Onebox initialization.
|
||||||
@@ -459,6 +530,7 @@ Introduce a complete service backup/restore subsystem with encrypted archives, d
|
|||||||
- Integrate BackupManager into Onebox core (initialized in Onebox constructor) and wire HTTP handlers to use the new manager; add DB repository export/import glue so backups are stored and referenced by ID.
|
- Integrate BackupManager into Onebox core (initialized in Onebox constructor) and wire HTTP handlers to use the new manager; add DB repository export/import glue so backups are stored and referenced by ID.
|
||||||
|
|
||||||
## 2025-11-27 - 1.6.0 - feat(ui.dashboard)
|
## 2025-11-27 - 1.6.0 - feat(ui.dashboard)
|
||||||
|
|
||||||
Add Resource Usage card to dashboard and make dashboard cards full-height; add VSCode launch/tasks/config
|
Add Resource Usage card to dashboard and make dashboard cards full-height; add VSCode launch/tasks/config
|
||||||
|
|
||||||
- Introduce ResourceUsageCardComponent and include it as a full-width row in the dashboard layout.
|
- Introduce ResourceUsageCardComponent and include it as a full-width row in the dashboard layout.
|
||||||
@@ -467,6 +539,7 @@ Add Resource Usage card to dashboard and make dashboard cards full-height; add V
|
|||||||
- Add VSCode workspace configuration: recommended Angular extension, launch configurations for ng serve/ng test, and npm tasks to run/start the UI in development.
|
- Add VSCode workspace configuration: recommended Angular extension, launch configurations for ng serve/ng test, and npm tasks to run/start the UI in development.
|
||||||
|
|
||||||
## 2025-11-27 - 1.5.0 - feat(network)
|
## 2025-11-27 - 1.5.0 - feat(network)
|
||||||
|
|
||||||
Add traffic stats endpoint and dashboard UI; enhance platform services and certificate health reporting
|
Add traffic stats endpoint and dashboard UI; enhance platform services and certificate health reporting
|
||||||
|
|
||||||
- Add /api/network/traffic-stats GET endpoint to the HTTP API with an optional minutes query parameter (validated, 1-60).
|
- Add /api/network/traffic-stats GET endpoint to the HTTP API with an optional minutes query parameter (validated, 1-60).
|
||||||
@@ -478,26 +551,29 @@ Add traffic stats endpoint and dashboard UI; enhance platform services and certi
|
|||||||
- Add VSCode workspace launch/tasks recommendations for the UI development environment.
|
- Add VSCode workspace launch/tasks recommendations for the UI development environment.
|
||||||
|
|
||||||
## 2025-11-26 - 1.4.0 - feat(platform-services)
|
## 2025-11-26 - 1.4.0 - feat(platform-services)
|
||||||
|
|
||||||
Add ClickHouse platform service support and improve related healthchecks and tooling
|
Add ClickHouse platform service support and improve related healthchecks and tooling
|
||||||
|
|
||||||
- Add ClickHouse as a first-class platform service: register provider, provision/cleanup support and env var injection
|
- Add ClickHouse as a first-class platform service: register provider, provision/cleanup support and env var injection
|
||||||
- Expose ClickHouse endpoints in the HTTP API routing (list/get/start/stop/stats) and map default port (8123)
|
- Expose ClickHouse endpoints in the HTTP API routing (list/get/start/stop/stats) and map default port (8123)
|
||||||
- Enable services to request ClickHouse as a platform requirement (enableClickHouse / platformRequirements) during deploy/provision flows
|
- Enable services to request ClickHouse as a platform requirement (enableClickHouse / platformRequirements) during deploy/provision flows
|
||||||
- Fix ClickHouse container health check to use absolute wget path (/usr/bin/wget) for more reliable in-container checks
|
- Fix ClickHouse container health check to use absolute wget path (/usr/bin/wget) for more reliable in-container checks
|
||||||
- Add VS Code workspace launch/tasks/extensions configs for the UI (ui/.vscode/*) to improve local dev experience
|
- Add VS Code workspace launch/tasks/extensions configs for the UI (ui/.vscode/\*) to improve local dev experience
|
||||||
|
|
||||||
## 2025-11-26 - 1.3.0 - feat(platform-services)
|
## 2025-11-26 - 1.3.0 - feat(platform-services)
|
||||||
|
|
||||||
Add ClickHouse platform service support (provider, types, provisioning, UI and port mappings)
|
Add ClickHouse platform service support (provider, types, provisioning, UI and port mappings)
|
||||||
|
|
||||||
- Introduce ClickHouse as a first-class platform service: added ClickHouseProvider and registered it in PlatformServicesManager
|
- Introduce ClickHouse as a first-class platform service: added ClickHouseProvider and registered it in PlatformServicesManager
|
||||||
- Support provisioning ClickHouse resources for user services and storing encrypted credentials in platform_resources
|
- Support provisioning ClickHouse resources for user services and storing encrypted credentials in platform_resources
|
||||||
- Add ClickHouse to core types (TPlatformServiceType, IPlatformRequirements, IServiceDeployOptions) and service DB handling so services can request ClickHouse
|
- Add ClickHouse to core types (TPlatformServiceType, IPlatformRequirements, IServiceDeployOptions) and service DB handling so services can request ClickHouse
|
||||||
- Inject ClickHouse-related environment variables into deployed services (CLICKHOUSE_* mappings) when provisioning resources
|
- Inject ClickHouse-related environment variables into deployed services (CLICKHOUSE\_\* mappings) when provisioning resources
|
||||||
- Expose ClickHouse default port (8123) in platform port mappings / network targets
|
- Expose ClickHouse default port (8123) in platform port mappings / network targets
|
||||||
- UI: add checkbox and description for enabling ClickHouse during service creation; form now submits enableClickHouse
|
- UI: add checkbox and description for enabling ClickHouse during service creation; form now submits enableClickHouse
|
||||||
- Add VS Code recommendations and launch/tasks for the UI development workflow
|
- Add VS Code recommendations and launch/tasks for the UI development workflow
|
||||||
|
|
||||||
## 2025-11-26 - 1.2.1 - fix(platform-services/minio)
|
## 2025-11-26 - 1.2.1 - fix(platform-services/minio)
|
||||||
|
|
||||||
Improve MinIO provider: reuse existing data and credentials, use host-bound port for provisioning, and safer provisioning/deprovisioning
|
Improve MinIO provider: reuse existing data and credentials, use host-bound port for provisioning, and safer provisioning/deprovisioning
|
||||||
|
|
||||||
- MinIO provider now detects existing data directory and will reuse stored admin credentials when available instead of regenerating them.
|
- MinIO provider now detects existing data directory and will reuse stored admin credentials when available instead of regenerating them.
|
||||||
@@ -508,15 +584,17 @@ Improve MinIO provider: reuse existing data and credentials, use host-bound port
|
|||||||
- Added VSCode workspace files (extensions, launch, tasks) for the ui project to improve developer experience.
|
- Added VSCode workspace files (extensions, launch, tasks) for the ui project to improve developer experience.
|
||||||
|
|
||||||
## 2025-11-26 - 1.2.0 - feat(ui)
|
## 2025-11-26 - 1.2.0 - feat(ui)
|
||||||
|
|
||||||
Sync UI tab state with URL and update routes/links
|
Sync UI tab state with URL and update routes/links
|
||||||
|
|
||||||
- Add VSCode workspace recommendations, launch and tasks configs for the UI (ui/.vscode/*)
|
- Add VSCode workspace recommendations, launch and tasks configs for the UI (ui/.vscode/\*)
|
||||||
- Update Angular routes to support tab URL segments and default redirects for services, network and registries
|
- Update Angular routes to support tab URL segments and default redirects for services, network and registries
|
||||||
- Change service detail route to use explicit 'detail/:name' path and update links accordingly
|
- Change service detail route to use explicit 'detail/:name' path and update links accordingly
|
||||||
- Make ServicesList, Registries and Network components read tab from route params and navigate on tab changes; add ngOnDestroy to unsubscribe
|
- Make ServicesList, Registries and Network components read tab from route params and navigate on tab changes; add ngOnDestroy to unsubscribe
|
||||||
- Update Domain detail template link to point to the new services detail route
|
- Update Domain detail template link to point to the new services detail route
|
||||||
|
|
||||||
## 2025-11-26 - 1.1.0 - feat(platform-services)
|
## 2025-11-26 - 1.1.0 - feat(platform-services)
|
||||||
|
|
||||||
Add platform service log streaming, improve health checks and provisioning robustness
|
Add platform service log streaming, improve health checks and provisioning robustness
|
||||||
|
|
||||||
- Add WebSocket log streaming support for platform services (backend + UI) to stream MinIO/MongoDB/Caddy logs in real time
|
- Add WebSocket log streaming support for platform services (backend + UI) to stream MinIO/MongoDB/Caddy logs in real time
|
||||||
@@ -536,6 +614,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Initial project structure
|
- Initial project structure
|
||||||
- Core architecture classes
|
- Core architecture classes
|
||||||
- Docker container management
|
- Docker container management
|
||||||
@@ -554,4 +633,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [1.0.0] - TBD
|
## [1.0.0] - TBD
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- First stable release
|
- First stable release
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/onebox",
|
"name": "@serve.zone/onebox",
|
||||||
"version": "1.23.0",
|
"version": "1.24.2",
|
||||||
"exports": "./mod.ts",
|
"exports": "./mod.ts",
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"test": "deno test --allow-all test/",
|
"test": "deno test --allow-all test/",
|
||||||
@@ -19,14 +19,15 @@
|
|||||||
"@apiclient.xyz/cloudflare": "npm:@apiclient.xyz/cloudflare@6.4.3",
|
"@apiclient.xyz/cloudflare": "npm:@apiclient.xyz/cloudflare@6.4.3",
|
||||||
"@push.rocks/smartacme": "npm:@push.rocks/smartacme@^8.0.0",
|
"@push.rocks/smartacme": "npm:@push.rocks/smartacme@^8.0.0",
|
||||||
"@push.rocks/smartregistry": "npm:@push.rocks/smartregistry@^2.2.0",
|
"@push.rocks/smartregistry": "npm:@push.rocks/smartregistry@^2.2.0",
|
||||||
"@push.rocks/smarts3": "npm:@push.rocks/smarts3@^5.1.0",
|
"@push.rocks/smartstorage": "npm:@push.rocks/smartstorage@^6.3.0",
|
||||||
"@push.rocks/taskbuffer": "npm:@push.rocks/taskbuffer@^3.1.0",
|
"@push.rocks/taskbuffer": "npm:@push.rocks/taskbuffer@^3.1.0",
|
||||||
"@api.global/typedrequest-interfaces": "npm:@api.global/typedrequest-interfaces@^3.0.19",
|
"@api.global/typedrequest-interfaces": "npm:@api.global/typedrequest-interfaces@^3.0.19",
|
||||||
"@api.global/typedrequest": "npm:@api.global/typedrequest@^3.2.6",
|
"@api.global/typedrequest": "npm:@api.global/typedrequest@^3.2.6",
|
||||||
"@api.global/typedserver": "npm:@api.global/typedserver@^8.3.1",
|
"@api.global/typedserver": "npm:@api.global/typedserver@^8.3.1",
|
||||||
"@push.rocks/smartguard": "npm:@push.rocks/smartguard@^3.1.0",
|
"@push.rocks/smartguard": "npm:@push.rocks/smartguard@^3.1.0",
|
||||||
"@push.rocks/smartjwt": "npm:@push.rocks/smartjwt@^2.2.1",
|
"@push.rocks/smartjwt": "npm:@push.rocks/smartjwt@^2.2.1",
|
||||||
"@api.global/typedsocket": "npm:@api.global/typedsocket@^4.1.2"
|
"@api.global/typedsocket": "npm:@api.global/typedsocket@^4.1.2",
|
||||||
|
"@serve.zone/containerarchive": "npm:@serve.zone/containerarchive@^0.1.3"
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"lib": [
|
"lib": [
|
||||||
|
|||||||
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@serve.zone/onebox",
|
"name": "@serve.zone/onebox",
|
||||||
"version": "1.23.0",
|
"version": "1.24.2",
|
||||||
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
|
"description": "Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers",
|
||||||
"main": "mod.ts",
|
"main": "mod.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -56,13 +56,17 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@api.global/typedrequest-interfaces": "^3.0.19",
|
"@api.global/typedrequest-interfaces": "^3.0.19",
|
||||||
"@api.global/typedsocket": "^4.1.2",
|
"@api.global/typedsocket": "^4.1.2",
|
||||||
"@design.estate/dees-catalog": "^3.43.3",
|
"@design.estate/dees-catalog": "^3.49.0",
|
||||||
"@design.estate/dees-element": "^2.1.6",
|
"@design.estate/dees-element": "^2.1.6",
|
||||||
"@serve.zone/catalog": "^2.9.0"
|
"@serve.zone/catalog": "^2.9.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbundle": "^2.9.0",
|
"@git.zone/tsbundle": "^2.10.0",
|
||||||
"@git.zone/tsdeno": "^1.2.0",
|
"@git.zone/tsdeno": "^1.3.1",
|
||||||
"@git.zone/tswatch": "^3.2.0"
|
"@git.zone/tswatch": "^3.3.2"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"pnpm": {
|
||||||
|
"overrides": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
634
pnpm-lock.yaml
generated
634
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@
|
|||||||
## SSL Certificate Storage (November 2025)
|
## SSL Certificate Storage (November 2025)
|
||||||
|
|
||||||
SSL certificates are now stored directly in the SQLite database as PEM content instead of file paths:
|
SSL certificates are now stored directly in the SQLite database as PEM content instead of file paths:
|
||||||
|
|
||||||
- `ISslCertificate` and `ICertificate` interfaces use `certPem`, `keyPem`, `fullchainPem` properties
|
- `ISslCertificate` and `ICertificate` interfaces use `certPem`, `keyPem`, `fullchainPem` properties
|
||||||
- Database migration 8 converted the `certificates` table schema
|
- Database migration 8 converted the `certificates` table schema
|
||||||
- No filesystem storage for certificates - everything in DB
|
- No filesystem storage for certificates - everything in DB
|
||||||
@@ -16,6 +17,7 @@ SSL certificates are now stored directly in the SQLite database as PEM content i
|
|||||||
The database layer has been refactored into a repository pattern:
|
The database layer has been refactored into a repository pattern:
|
||||||
|
|
||||||
**Directory Structure:**
|
**Directory Structure:**
|
||||||
|
|
||||||
```
|
```
|
||||||
ts/database/
|
ts/database/
|
||||||
├── index.ts # Main OneboxDatabase class (composes repositories, handles migrations)
|
├── index.ts # Main OneboxDatabase class (composes repositories, handles migrations)
|
||||||
@@ -32,10 +34,12 @@ ts/database/
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Import paths:**
|
**Import paths:**
|
||||||
|
|
||||||
- Main: `import { OneboxDatabase } from './database/index.ts'`
|
- Main: `import { OneboxDatabase } from './database/index.ts'`
|
||||||
- Legacy (deprecated): `import { OneboxDatabase } from './classes/database.ts'` (re-exports from new location)
|
- Legacy (deprecated): `import { OneboxDatabase } from './classes/database.ts'` (re-exports from new location)
|
||||||
|
|
||||||
**API Compatibility:**
|
**API Compatibility:**
|
||||||
|
|
||||||
- The `OneboxDatabase` class maintains the same public API
|
- The `OneboxDatabase` class maintains the same public API
|
||||||
- All methods delegate to the appropriate repository
|
- All methods delegate to the appropriate repository
|
||||||
- No breaking changes for existing code
|
- No breaking changes for existing code
|
||||||
@@ -49,6 +53,7 @@ Migration 8 converted certificate storage from file paths to PEM content.
|
|||||||
The reverse proxy uses **Caddy** running as a Docker Swarm service for production-grade reverse proxying with native SNI support, HTTP/2, HTTP/3, and WebSocket handling.
|
The reverse proxy uses **Caddy** running as a Docker Swarm service for production-grade reverse proxying with native SNI support, HTTP/2, HTTP/3, and WebSocket handling.
|
||||||
|
|
||||||
**Architecture:**
|
**Architecture:**
|
||||||
|
|
||||||
- Caddy runs as Docker Swarm service (`onebox-caddy`) on the overlay network
|
- Caddy runs as Docker Swarm service (`onebox-caddy`) on the overlay network
|
||||||
- No binary download required - uses `caddy:2-alpine` Docker image
|
- No binary download required - uses `caddy:2-alpine` Docker image
|
||||||
- Configuration pushed dynamically via Caddy Admin API (port 2019)
|
- Configuration pushed dynamically via Caddy Admin API (port 2019)
|
||||||
@@ -57,10 +62,12 @@ The reverse proxy uses **Caddy** running as a Docker Swarm service for productio
|
|||||||
- Services reached by Docker service name (e.g., `onebox-hello-world:80`)
|
- Services reached by Docker service name (e.g., `onebox-hello-world:80`)
|
||||||
|
|
||||||
**Key files:**
|
**Key files:**
|
||||||
|
|
||||||
- `ts/classes/caddy.ts` - CaddyManager class for Docker service and Admin API
|
- `ts/classes/caddy.ts` - CaddyManager class for Docker service and Admin API
|
||||||
- `ts/classes/reverseproxy.ts` - Delegates to CaddyManager
|
- `ts/classes/reverseproxy.ts` - Delegates to CaddyManager
|
||||||
|
|
||||||
**Certificate workflow:**
|
**Certificate workflow:**
|
||||||
|
|
||||||
1. `CertRequirementManager` creates requirements for domains
|
1. `CertRequirementManager` creates requirements for domains
|
||||||
2. Daemon processes requirements via `certmanager.ts`
|
2. Daemon processes requirements via `certmanager.ts`
|
||||||
3. Certificates stored in database (PEM content)
|
3. Certificates stored in database (PEM content)
|
||||||
@@ -68,16 +75,19 @@ The reverse proxy uses **Caddy** running as a Docker Swarm service for productio
|
|||||||
5. Caddy serves TLS with the loaded certificates (no volume mounts needed)
|
5. Caddy serves TLS with the loaded certificates (no volume mounts needed)
|
||||||
|
|
||||||
**Docker Service Configuration:**
|
**Docker Service Configuration:**
|
||||||
|
|
||||||
- Service name: `onebox-caddy`
|
- Service name: `onebox-caddy`
|
||||||
- Image: `caddy:2-alpine`
|
- Image: `caddy:2-alpine`
|
||||||
- Network: `onebox-network` (overlay, attachable)
|
- Network: `onebox-network` (overlay, attachable)
|
||||||
- Startup: Writes initial config with `admin.listen: 0.0.0.0:2019` for host access
|
- Startup: Writes initial config with `admin.listen: 0.0.0.0:2019` for host access
|
||||||
|
|
||||||
**Port Mapping:**
|
**Port Mapping:**
|
||||||
|
|
||||||
- Dev mode: HTTP on 8080, HTTPS on 8443, Admin on 2019
|
- Dev mode: HTTP on 8080, HTTPS on 8443, Admin on 2019
|
||||||
- Production: HTTP on 80, HTTPS on 443, Admin on 2019
|
- Production: HTTP on 80, HTTPS on 443, Admin on 2019
|
||||||
- All ports use `PublishMode: 'host'` for direct binding
|
- All ports use `PublishMode: 'host'` for direct binding
|
||||||
|
|
||||||
**Log Receiver:**
|
**Log Receiver:**
|
||||||
|
|
||||||
- Caddy sends access logs to `tcp/172.17.0.1:9999` (Docker bridge gateway)
|
- Caddy sends access logs to `tcp/172.17.0.1:9999` (Docker bridge gateway)
|
||||||
- `CaddyLogReceiver` on host receives and processes logs
|
- `CaddyLogReceiver` on host receives and processes logs
|
||||||
|
|||||||
121
readme.md
121
readme.md
@@ -22,6 +22,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
## Features ✨
|
## Features ✨
|
||||||
|
|
||||||
### Core Platform
|
### Core Platform
|
||||||
|
|
||||||
- 🐳 **Docker Swarm Management** - Deploy, scale, and orchestrate services with Swarm mode
|
- 🐳 **Docker Swarm Management** - Deploy, scale, and orchestrate services with Swarm mode
|
||||||
- 🌐 **Caddy Reverse Proxy** - Production-grade proxy running as Docker service with SNI, HTTP/2, HTTP/3
|
- 🌐 **Caddy Reverse Proxy** - Production-grade proxy running as Docker service with SNI, HTTP/2, HTTP/3
|
||||||
- 🔒 **Automatic SSL Certificates** - Let's Encrypt integration with hot-reload and renewal monitoring
|
- 🔒 **Automatic SSL Certificates** - Let's Encrypt integration with hot-reload and renewal monitoring
|
||||||
@@ -30,6 +31,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
- 🔄 **Real-time WebSocket Updates** - Live service status, logs, and system events
|
- 🔄 **Real-time WebSocket Updates** - Live service status, logs, and system events
|
||||||
|
|
||||||
### Monitoring & Management
|
### Monitoring & Management
|
||||||
|
|
||||||
- 📊 **Metrics Collection** - Historical CPU, memory, and network stats (every 60s)
|
- 📊 **Metrics Collection** - Historical CPU, memory, and network stats (every 60s)
|
||||||
- 📝 **Centralized Logging** - Container logs with streaming and retention policies
|
- 📝 **Centralized Logging** - Container logs with streaming and retention policies
|
||||||
- 🎨 **Angular Web UI** - Modern, responsive interface with real-time updates
|
- 🎨 **Angular Web UI** - Modern, responsive interface with real-time updates
|
||||||
@@ -37,6 +39,7 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|||||||
- 💾 **SQLite Database** - Embedded, zero-configuration storage
|
- 💾 **SQLite Database** - Embedded, zero-configuration storage
|
||||||
|
|
||||||
### Developer Experience
|
### Developer Experience
|
||||||
|
|
||||||
- 🚀 **Auto-update on Push** - Push to registry and services update automatically
|
- 🚀 **Auto-update on Push** - Push to registry and services update automatically
|
||||||
- 🔐 **Private Registry Support** - Use Docker Hub, Gitea, or custom registries
|
- 🔐 **Private Registry Support** - Use Docker Hub, Gitea, or custom registries
|
||||||
- 🔄 **Systemd Integration** - Run as a daemon with auto-restart
|
- 🔄 **Systemd Integration** - Run as a daemon with auto-restart
|
||||||
@@ -75,6 +78,7 @@ onebox service add myapp \
|
|||||||
Open `http://localhost:3000` in your browser.
|
Open `http://localhost:3000` in your browser.
|
||||||
|
|
||||||
**Default credentials:**
|
**Default credentials:**
|
||||||
|
|
||||||
- Username: `admin`
|
- Username: `admin`
|
||||||
- Password: `admin`
|
- Password: `admin`
|
||||||
|
|
||||||
@@ -130,15 +134,15 @@ Onebox is built with modern technologies for performance and developer experienc
|
|||||||
|
|
||||||
### Core Components
|
### Core Components
|
||||||
|
|
||||||
| Component | Description |
|
| Component | Description |
|
||||||
|-----------|-------------|
|
| ----------------------- | -------------------------------------------------------------------- |
|
||||||
| **Deno Runtime** | Modern TypeScript with built-in security |
|
| **Deno Runtime** | Modern TypeScript with built-in security |
|
||||||
| **Caddy Reverse Proxy** | Docker Swarm service with HTTP/2, HTTP/3, SNI, and WebSocket support |
|
| **Caddy Reverse Proxy** | Docker Swarm service with HTTP/2, HTTP/3, SNI, and WebSocket support |
|
||||||
| **Docker Swarm** | Container orchestration (all workloads run as services) |
|
| **Docker Swarm** | Container orchestration (all workloads run as services) |
|
||||||
| **SQLite Database** | Configuration, metrics, and user data |
|
| **SQLite Database** | Configuration, metrics, and user data |
|
||||||
| **WebSocket Server** | Real-time bidirectional communication |
|
| **WebSocket Server** | Real-time bidirectional communication |
|
||||||
| **Let's Encrypt** | Automatic SSL certificate management |
|
| **Let's Encrypt** | Automatic SSL certificate management |
|
||||||
| **Cloudflare API** | DNS record automation |
|
| **Cloudflare API** | DNS record automation |
|
||||||
|
|
||||||
## CLI Reference 📖
|
## CLI Reference 📖
|
||||||
|
|
||||||
@@ -262,11 +266,11 @@ sudo onebox upgrade
|
|||||||
|
|
||||||
### Data Locations
|
### Data Locations
|
||||||
|
|
||||||
| Data | Location |
|
| Data | Location |
|
||||||
|------|----------|
|
| -------------------- | ------------------------------ |
|
||||||
| **Database** | `./onebox.db` (or custom path) |
|
| **Database** | `./onebox.db` (or custom path) |
|
||||||
| **SSL Certificates** | Managed by CertManager |
|
| **SSL Certificates** | Managed by CertManager |
|
||||||
| **Registry Data** | `./.nogit/registry-data` |
|
| **Registry Data** | `./.nogit/registry-data` |
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
@@ -355,62 +359,69 @@ onebox/
|
|||||||
The HTTP server exposes a comprehensive REST API:
|
The HTTP server exposes a comprehensive REST API:
|
||||||
|
|
||||||
#### Authentication
|
#### Authentication
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
|
| ------ | ----------------- | ----------------------------------- |
|
||||||
| `POST` | `/api/auth/login` | User authentication (returns token) |
|
| `POST` | `/api/auth/login` | User authentication (returns token) |
|
||||||
|
|
||||||
#### Services
|
#### Services
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/services` | List all services |
|
| -------- | --------------------------------- | ------------------------- |
|
||||||
| `POST` | `/api/services` | Create/deploy service |
|
| `GET` | `/api/services` | List all services |
|
||||||
| `GET` | `/api/services/:name` | Get service details |
|
| `POST` | `/api/services` | Create/deploy service |
|
||||||
| `PUT` | `/api/services/:name` | Update service |
|
| `GET` | `/api/services/:name` | Get service details |
|
||||||
| `DELETE` | `/api/services/:name` | Delete service |
|
| `PUT` | `/api/services/:name` | Update service |
|
||||||
| `POST` | `/api/services/:name/start` | Start service |
|
| `DELETE` | `/api/services/:name` | Delete service |
|
||||||
| `POST` | `/api/services/:name/stop` | Stop service |
|
| `POST` | `/api/services/:name/start` | Start service |
|
||||||
| `POST` | `/api/services/:name/restart` | Restart service |
|
| `POST` | `/api/services/:name/stop` | Stop service |
|
||||||
| `GET` | `/api/services/:name/logs` | Get service logs |
|
| `POST` | `/api/services/:name/restart` | Restart service |
|
||||||
| `WS` | `/api/services/:name/logs/stream` | Stream logs via WebSocket |
|
| `GET` | `/api/services/:name/logs` | Get service logs |
|
||||||
|
| `WS` | `/api/services/:name/logs/stream` | Stream logs via WebSocket |
|
||||||
|
|
||||||
#### SSL Certificates
|
#### SSL Certificates
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/ssl/list` | List all certificates |
|
| ------ | ------------------------ | ----------------------- |
|
||||||
| `GET` | `/api/ssl/:domain` | Get certificate details |
|
| `GET` | `/api/ssl/list` | List all certificates |
|
||||||
| `POST` | `/api/ssl/obtain` | Request new certificate |
|
| `GET` | `/api/ssl/:domain` | Get certificate details |
|
||||||
|
| `POST` | `/api/ssl/obtain` | Request new certificate |
|
||||||
| `POST` | `/api/ssl/:domain/renew` | Force renew certificate |
|
| `POST` | `/api/ssl/:domain/renew` | Force renew certificate |
|
||||||
|
|
||||||
#### Domains
|
#### Domains
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/domains` | List all domains |
|
| ------ | ---------------------- | ---------------------------- |
|
||||||
| `GET` | `/api/domains/:domain` | Get domain details |
|
| `GET` | `/api/domains` | List all domains |
|
||||||
| `POST` | `/api/domains/sync` | Sync domains from Cloudflare |
|
| `GET` | `/api/domains/:domain` | Get domain details |
|
||||||
|
| `POST` | `/api/domains/sync` | Sync domains from Cloudflare |
|
||||||
|
|
||||||
#### DNS Records
|
#### DNS Records
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/dns` | List DNS records |
|
| -------- | ------------------ | ------------------------ |
|
||||||
| `POST` | `/api/dns` | Create DNS record |
|
| `GET` | `/api/dns` | List DNS records |
|
||||||
| `DELETE` | `/api/dns/:domain` | Delete DNS record |
|
| `POST` | `/api/dns` | Create DNS record |
|
||||||
| `POST` | `/api/dns/sync` | Sync DNS from Cloudflare |
|
| `DELETE` | `/api/dns/:domain` | Delete DNS record |
|
||||||
|
| `POST` | `/api/dns/sync` | Sync DNS from Cloudflare |
|
||||||
|
|
||||||
#### Registry
|
#### Registry
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/registry/tags/:service` | Get registry tags for service |
|
| -------- | ----------------------------- | ----------------------------- |
|
||||||
| `GET` | `/api/registry/tokens` | List registry tokens |
|
| `GET` | `/api/registry/tags/:service` | Get registry tags for service |
|
||||||
| `POST` | `/api/registry/tokens` | Create registry token |
|
| `GET` | `/api/registry/tokens` | List registry tokens |
|
||||||
| `DELETE` | `/api/registry/tokens/:id` | Delete registry token |
|
| `POST` | `/api/registry/tokens` | Create registry token |
|
||||||
|
| `DELETE` | `/api/registry/tokens/:id` | Delete registry token |
|
||||||
|
|
||||||
#### System
|
#### System
|
||||||
| Method | Endpoint | Description |
|
|
||||||
|--------|----------|-------------|
|
| Method | Endpoint | Description |
|
||||||
| `GET` | `/api/status` | System status |
|
| ------ | --------------- | ------------------------------- |
|
||||||
| `GET` | `/api/settings` | Get settings |
|
| `GET` | `/api/status` | System status |
|
||||||
| `PUT` | `/api/settings` | Update settings |
|
| `GET` | `/api/settings` | Get settings |
|
||||||
| `WS` | `/api/ws` | WebSocket for real-time updates |
|
| `PUT` | `/api/settings` | Update settings |
|
||||||
|
| `WS` | `/api/ws` | WebSocket for real-time updates |
|
||||||
|
|
||||||
### WebSocket Messages
|
### WebSocket Messages
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/onebox',
|
name: '@serve.zone/onebox',
|
||||||
version: '1.23.0',
|
version: '1.24.2',
|
||||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -59,6 +59,15 @@ export class BackupScheduler {
|
|||||||
await this.registerTask(schedule);
|
await this.registerTask(schedule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add periodic archive prune task (runs daily at 3 AM)
|
||||||
|
const pruneTask = new plugins.taskbuffer.Task({
|
||||||
|
name: 'backup-archive-prune',
|
||||||
|
taskFunction: async () => {
|
||||||
|
await this.pruneArchive();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.taskManager.addAndScheduleTask(pruneTask, '0 3 * * *');
|
||||||
|
|
||||||
// Start the task manager (activates cron scheduling)
|
// Start the task manager (activates cron scheduling)
|
||||||
await this.taskManager.start();
|
await this.taskManager.start();
|
||||||
|
|
||||||
@@ -436,9 +445,11 @@ export class BackupScheduler {
|
|||||||
if (!toKeep.has(backup.id!)) {
|
if (!toKeep.has(backup.id!)) {
|
||||||
try {
|
try {
|
||||||
await this.oneboxRef.backupManager.deleteBackup(backup.id!);
|
await this.oneboxRef.backupManager.deleteBackup(backup.id!);
|
||||||
logger.info(`Deleted backup ${backup.filename} (retention policy)`);
|
const backupRef = backup.snapshotId || backup.filename;
|
||||||
|
logger.info(`Deleted backup ${backupRef} (retention policy)`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn(`Failed to delete old backup ${backup.filename}: ${getErrorMessage(error)}`);
|
const backupRef = backup.snapshotId || backup.filename;
|
||||||
|
logger.warn(`Failed to delete old backup ${backupRef}: ${getErrorMessage(error)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -647,4 +658,48 @@ export class BackupScheduler {
|
|||||||
private getRetentionDescription(retention: IRetentionPolicy): string {
|
private getRetentionDescription(retention: IRetentionPolicy): string {
|
||||||
return `H:${retention.hourly} D:${retention.daily} W:${retention.weekly} M:${retention.monthly}`;
|
return `H:${retention.hourly} D:${retention.daily} W:${retention.weekly} M:${retention.monthly}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prune the containerarchive repository to reclaim storage.
|
||||||
|
* Uses the most generous retention policy across all schedules.
|
||||||
|
*/
|
||||||
|
private async pruneArchive(): Promise<void> {
|
||||||
|
const archive = this.oneboxRef.backupManager.archive;
|
||||||
|
if (!archive) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Compute the most generous retention across all schedules
|
||||||
|
const schedules = this.oneboxRef.database.getAllBackupSchedules();
|
||||||
|
|
||||||
|
// Default minimums if no schedules exist
|
||||||
|
let maxDays = 7;
|
||||||
|
let maxWeeks = 4;
|
||||||
|
let maxMonths = 12;
|
||||||
|
|
||||||
|
for (const schedule of schedules) {
|
||||||
|
if (schedule.retention.daily > maxDays) maxDays = schedule.retention.daily;
|
||||||
|
if (schedule.retention.weekly > maxWeeks) maxWeeks = schedule.retention.weekly;
|
||||||
|
if (schedule.retention.monthly > maxMonths) maxMonths = schedule.retention.monthly;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await archive.prune(
|
||||||
|
{
|
||||||
|
keepDays: maxDays,
|
||||||
|
keepWeeks: maxWeeks,
|
||||||
|
keepMonths: maxMonths,
|
||||||
|
},
|
||||||
|
false, // not dry run
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.removedSnapshots > 0 || result.freedBytes > 0) {
|
||||||
|
const freedMB = Math.round(result.freedBytes / (1024 * 1024) * 10) / 10;
|
||||||
|
logger.info(
|
||||||
|
`Archive prune: removed ${result.removedSnapshots} snapshot(s), ` +
|
||||||
|
`${result.removedPacks} pack(s), freed ${freedMB} MB`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn(`Archive prune failed: ${getErrorMessage(error)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2161,27 +2161,47 @@ export class OneboxHttpServer {
|
|||||||
*/
|
*/
|
||||||
private async handleDownloadBackupRequest(backupId: number): Promise<Response> {
|
private async handleDownloadBackupRequest(backupId: number): Promise<Response> {
|
||||||
try {
|
try {
|
||||||
const filePath = this.oneboxRef.backupManager.getBackupFilePath(backupId);
|
const backup = this.oneboxRef.database.getBackupById(backupId);
|
||||||
if (!filePath) {
|
if (!backup) {
|
||||||
return this.jsonResponse({ success: false, error: 'Backup not found' }, 404);
|
return this.jsonResponse({ success: false, error: 'Backup not found' }, 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let downloadPath: string | null = null;
|
||||||
|
let tempExport = false;
|
||||||
|
|
||||||
|
if (backup.snapshotId) {
|
||||||
|
// ContainerArchive backup: export as encrypted tar
|
||||||
|
downloadPath = await this.oneboxRef.backupManager.getBackupExportPath(backupId);
|
||||||
|
tempExport = true;
|
||||||
|
} else {
|
||||||
|
// Legacy file-based backup
|
||||||
|
downloadPath = this.oneboxRef.backupManager.getBackupFilePath(backupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!downloadPath) {
|
||||||
|
return this.jsonResponse({ success: false, error: 'Backup file not available' }, 404);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
try {
|
try {
|
||||||
await Deno.stat(filePath);
|
await Deno.stat(downloadPath);
|
||||||
} catch {
|
} catch {
|
||||||
return this.jsonResponse({ success: false, error: 'Backup file not found on disk' }, 404);
|
return this.jsonResponse({ success: false, error: 'Backup file not found on disk' }, 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read file and return as download
|
const file = await Deno.readFile(downloadPath);
|
||||||
const backup = this.oneboxRef.database.getBackupById(backupId);
|
const filename = backup.filename || `${backup.serviceName}-${backup.createdAt}.tar.enc`;
|
||||||
const file = await Deno.readFile(filePath);
|
|
||||||
|
// Clean up temp export file
|
||||||
|
if (tempExport) {
|
||||||
|
try { await Deno.remove(downloadPath); } catch { /* ignore */ }
|
||||||
|
}
|
||||||
|
|
||||||
return new Response(file, {
|
return new Response(file, {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/octet-stream',
|
'Content-Type': 'application/octet-stream',
|
||||||
'Content-Disposition': `attachment; filename="${backup?.filename || 'backup.tar.enc'}"`,
|
'Content-Disposition': `attachment; filename="${filename}"`,
|
||||||
'Content-Length': String(file.length),
|
'Content-Length': String(file.length),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -2241,12 +2261,6 @@ export class OneboxHttpServer {
|
|||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get backup file path
|
|
||||||
const filePath = this.oneboxRef.backupManager.getBackupFilePath(backupId);
|
|
||||||
if (!filePath) {
|
|
||||||
return this.jsonResponse({ success: false, error: 'Backup not found' }, 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate mode-specific requirements
|
// Validate mode-specific requirements
|
||||||
if ((mode === 'import' || mode === 'clone') && !newServiceName) {
|
if ((mode === 'import' || mode === 'clone') && !newServiceName) {
|
||||||
return this.jsonResponse({
|
return this.jsonResponse({
|
||||||
@@ -2255,7 +2269,7 @@ export class OneboxHttpServer {
|
|||||||
}, 400);
|
}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.oneboxRef.backupManager.restoreBackup(filePath, {
|
const result = await this.oneboxRef.backupManager.restoreBackup(backupId, {
|
||||||
mode,
|
mode,
|
||||||
newServiceName,
|
newServiceName,
|
||||||
overwriteExisting: overwriteExisting === true,
|
overwriteExisting: overwriteExisting === true,
|
||||||
|
|||||||
@@ -192,6 +192,14 @@ export class Onebox {
|
|||||||
// Start auto-update monitoring for registry services
|
// Start auto-update monitoring for registry services
|
||||||
this.services.startAutoUpdateMonitoring();
|
this.services.startAutoUpdateMonitoring();
|
||||||
|
|
||||||
|
// Initialize BackupManager (containerarchive repository, non-critical)
|
||||||
|
try {
|
||||||
|
await this.backupManager.init();
|
||||||
|
} catch (error) {
|
||||||
|
logger.warn('BackupManager initialization failed - backups will be limited');
|
||||||
|
logger.warn(`Error: ${getErrorMessage(error)}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize Backup Scheduler (non-critical)
|
// Initialize Backup Scheduler (non-critical)
|
||||||
try {
|
try {
|
||||||
await this.backupScheduler.init();
|
await this.backupScheduler.init();
|
||||||
@@ -430,6 +438,9 @@ export class Onebox {
|
|||||||
// Stop Caddy log receiver
|
// Stop Caddy log receiver
|
||||||
await this.caddyLogReceiver.stop();
|
await this.caddyLogReceiver.stop();
|
||||||
|
|
||||||
|
// Close backup archive
|
||||||
|
await this.backupManager.close();
|
||||||
|
|
||||||
// Close database
|
// Close database
|
||||||
this.database.close();
|
this.database.close();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Onebox Registry Manager
|
* Onebox Registry Manager
|
||||||
*
|
*
|
||||||
* Manages the local Docker registry using:
|
* Manages the local Docker registry using:
|
||||||
* - @push.rocks/smarts3 (S3-compatible server with filesystem storage)
|
* - @push.rocks/smartstorage (S3-compatible server with filesystem storage)
|
||||||
* - @push.rocks/smartregistry (OCI-compliant Docker registry)
|
* - @push.rocks/smartregistry (OCI-compliant Docker registry)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ export class RegistryManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the registry (start smarts3 and smartregistry)
|
* Initialize the registry (start smartstorage and smartregistry)
|
||||||
*/
|
*/
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
if (this.isInitialized) {
|
if (this.isInitialized) {
|
||||||
@@ -39,10 +39,10 @@ export class RegistryManager {
|
|||||||
const dataDir = this.options.dataDir || './.nogit/registry-data';
|
const dataDir = this.options.dataDir || './.nogit/registry-data';
|
||||||
const port = this.options.port || 4000;
|
const port = this.options.port || 4000;
|
||||||
|
|
||||||
logger.info(`Starting smarts3 server on port ${port}...`);
|
logger.info(`Starting smartstorage server on port ${port}...`);
|
||||||
|
|
||||||
// 1. Start smarts3 server (S3-compatible storage with filesystem backend)
|
// 1. Start smartstorage server (S3-compatible storage with filesystem backend)
|
||||||
this.s3Server = await plugins.smarts3.Smarts3.createAndStart({
|
this.s3Server = await plugins.smartstorage.SmartStorage.createAndStart({
|
||||||
server: {
|
server: {
|
||||||
port: port,
|
port: port,
|
||||||
address: '0.0.0.0',
|
address: '0.0.0.0',
|
||||||
@@ -53,16 +53,16 @@ export class RegistryManager {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.success(`smarts3 server started on port ${port}`);
|
logger.success(`smartstorage server started on port ${port}`);
|
||||||
|
|
||||||
// 2. Configure smartregistry to use smarts3
|
// 2. Configure smartregistry to use smartstorage
|
||||||
logger.info('Initializing smartregistry...');
|
logger.info('Initializing smartregistry...');
|
||||||
|
|
||||||
this.registry = new plugins.smartregistry.SmartRegistry({
|
this.registry = new plugins.smartregistry.SmartRegistry({
|
||||||
storage: {
|
storage: {
|
||||||
endpoint: 'localhost',
|
endpoint: 'localhost',
|
||||||
port: port,
|
port: port,
|
||||||
accessKey: 'onebox', // smarts3 doesn't validate credentials
|
accessKey: 'onebox', // smartstorage doesn't validate credentials
|
||||||
accessSecret: 'onebox',
|
accessSecret: 'onebox',
|
||||||
useSsl: false,
|
useSsl: false,
|
||||||
region: 'us-east-1',
|
region: 'us-east-1',
|
||||||
@@ -314,15 +314,15 @@ export class RegistryManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the registry and smarts3 server
|
* Stop the registry and smartstorage server
|
||||||
*/
|
*/
|
||||||
async stop(): Promise<void> {
|
async stop(): Promise<void> {
|
||||||
if (this.s3Server) {
|
if (this.s3Server) {
|
||||||
try {
|
try {
|
||||||
await this.s3Server.stop();
|
await this.s3Server.stop();
|
||||||
logger.info('smarts3 server stopped');
|
logger.info('smartstorage server stopped');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Error stopping smarts3: ${getErrorMessage(error)}`);
|
logger.error(`Error stopping smartstorage: ${getErrorMessage(error)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -607,6 +607,10 @@ export class OneboxDatabase {
|
|||||||
return this.backupRepo.getBySchedule(scheduleId);
|
return this.backupRepo.getBySchedule(scheduleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBackupBySnapshotId(snapshotId: string): IBackup | null {
|
||||||
|
return this.backupRepo.getBySnapshotId(snapshotId);
|
||||||
|
}
|
||||||
|
|
||||||
// ============ Backup Schedules (delegated to repository) ============
|
// ============ Backup Schedules (delegated to repository) ============
|
||||||
|
|
||||||
createBackupSchedule(schedule: Omit<IBackupSchedule, 'id'>): IBackupSchedule {
|
createBackupSchedule(schedule: Omit<IBackupSchedule, 'id'>): IBackupSchedule {
|
||||||
|
|||||||
13
ts/database/migrations/migration-014-containerarchive.ts
Normal file
13
ts/database/migrations/migration-014-containerarchive.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { BaseMigration } from './base-migration.ts';
|
||||||
|
import type { TQueryFunction } from '../types.ts';
|
||||||
|
|
||||||
|
export class Migration014ContainerArchive extends BaseMigration {
|
||||||
|
readonly version = 14;
|
||||||
|
readonly description = 'Add containerarchive snapshot tracking to backups';
|
||||||
|
|
||||||
|
up(query: TQueryFunction): void {
|
||||||
|
query('ALTER TABLE backups ADD COLUMN snapshot_id TEXT');
|
||||||
|
query('ALTER TABLE backups ADD COLUMN stored_size_bytes INTEGER DEFAULT 0');
|
||||||
|
query('CREATE INDEX IF NOT EXISTS idx_backups_snapshot ON backups(snapshot_id)');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ import { Migration010BackupSchedules } from './migration-010-backup-schedules.ts
|
|||||||
import { Migration011ScopeColumns } from './migration-011-scope-columns.ts';
|
import { Migration011ScopeColumns } from './migration-011-scope-columns.ts';
|
||||||
import { Migration012GfsRetention } from './migration-012-gfs-retention.ts';
|
import { Migration012GfsRetention } from './migration-012-gfs-retention.ts';
|
||||||
import { Migration013AppTemplateVersion } from './migration-013-app-template-version.ts';
|
import { Migration013AppTemplateVersion } from './migration-013-app-template-version.ts';
|
||||||
|
import { Migration014ContainerArchive } from './migration-014-containerarchive.ts';
|
||||||
import type { BaseMigration } from './base-migration.ts';
|
import type { BaseMigration } from './base-migration.ts';
|
||||||
|
|
||||||
export class MigrationRunner {
|
export class MigrationRunner {
|
||||||
@@ -44,6 +45,7 @@ export class MigrationRunner {
|
|||||||
new Migration011ScopeColumns(),
|
new Migration011ScopeColumns(),
|
||||||
new Migration012GfsRetention(),
|
new Migration012GfsRetention(),
|
||||||
new Migration013AppTemplateVersion(),
|
new Migration013AppTemplateVersion(),
|
||||||
|
new Migration014ContainerArchive(),
|
||||||
].sort((a, b) => a.version - b.version);
|
].sort((a, b) => a.version - b.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ export class BackupRepository extends BaseRepository {
|
|||||||
this.query(
|
this.query(
|
||||||
`INSERT INTO backups (
|
`INSERT INTO backups (
|
||||||
service_id, service_name, filename, size_bytes, created_at,
|
service_id, service_name, filename, size_bytes, created_at,
|
||||||
includes_image, platform_resources, checksum, schedule_id
|
includes_image, platform_resources, checksum, schedule_id,
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
snapshot_id, stored_size_bytes
|
||||||
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
[
|
[
|
||||||
backup.serviceId,
|
backup.serviceId,
|
||||||
backup.serviceName,
|
backup.serviceName,
|
||||||
@@ -32,6 +33,8 @@ export class BackupRepository extends BaseRepository {
|
|||||||
JSON.stringify(backup.platformResources),
|
JSON.stringify(backup.platformResources),
|
||||||
backup.checksum,
|
backup.checksum,
|
||||||
backup.scheduleId ?? null,
|
backup.scheduleId ?? null,
|
||||||
|
backup.snapshotId ?? null,
|
||||||
|
backup.storedSizeBytes ?? 0,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -78,6 +81,14 @@ export class BackupRepository extends BaseRepository {
|
|||||||
return rows.map((row) => this.rowToBackup(row));
|
return rows.map((row) => this.rowToBackup(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getBySnapshotId(snapshotId: string): IBackup | null {
|
||||||
|
const rows = this.query(
|
||||||
|
'SELECT * FROM backups WHERE snapshot_id = ?',
|
||||||
|
[snapshotId]
|
||||||
|
);
|
||||||
|
return rows.length > 0 ? this.rowToBackup(rows[0]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
private rowToBackup(row: any): IBackup {
|
private rowToBackup(row: any): IBackup {
|
||||||
let platformResources: TPlatformServiceType[] = [];
|
let platformResources: TPlatformServiceType[] = [];
|
||||||
const platformResourcesRaw = row.platform_resources;
|
const platformResourcesRaw = row.platform_resources;
|
||||||
@@ -94,7 +105,9 @@ export class BackupRepository extends BaseRepository {
|
|||||||
serviceId: Number(row.service_id),
|
serviceId: Number(row.service_id),
|
||||||
serviceName: String(row.service_name),
|
serviceName: String(row.service_name),
|
||||||
filename: String(row.filename),
|
filename: String(row.filename),
|
||||||
|
snapshotId: row.snapshot_id ? String(row.snapshot_id) : undefined,
|
||||||
sizeBytes: Number(row.size_bytes),
|
sizeBytes: Number(row.size_bytes),
|
||||||
|
storedSizeBytes: row.stored_size_bytes ? Number(row.stored_size_bytes) : undefined,
|
||||||
createdAt: Number(row.created_at),
|
createdAt: Number(row.created_at),
|
||||||
includesImage: Boolean(row.includes_image),
|
includesImage: Boolean(row.includes_image),
|
||||||
platformResources,
|
platformResources,
|
||||||
|
|||||||
@@ -53,12 +53,8 @@ export class BackupsHandler {
|
|||||||
'restoreBackup',
|
'restoreBackup',
|
||||||
async (dataArg) => {
|
async (dataArg) => {
|
||||||
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
await requireValidIdentity(this.opsServerRef.adminHandler, dataArg);
|
||||||
const backupPath = this.opsServerRef.oneboxRef.backupManager.getBackupFilePath(dataArg.backupId);
|
|
||||||
if (!backupPath) {
|
|
||||||
throw new plugins.typedrequest.TypedResponseError('Backup file not found');
|
|
||||||
}
|
|
||||||
const rawResult = await this.opsServerRef.oneboxRef.backupManager.restoreBackup(
|
const rawResult = await this.opsServerRef.oneboxRef.backupManager.restoreBackup(
|
||||||
backupPath,
|
dataArg.backupId,
|
||||||
dataArg.options,
|
dataArg.options,
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
@@ -84,14 +80,11 @@ export class BackupsHandler {
|
|||||||
if (!backup) {
|
if (!backup) {
|
||||||
throw new plugins.typedrequest.TypedResponseError('Backup not found');
|
throw new plugins.typedrequest.TypedResponseError('Backup not found');
|
||||||
}
|
}
|
||||||
const filePath = this.opsServerRef.oneboxRef.backupManager.getBackupFilePath(dataArg.backupId);
|
|
||||||
if (!filePath) {
|
|
||||||
throw new plugins.typedrequest.TypedResponseError('Backup file not found');
|
|
||||||
}
|
|
||||||
// Return a download URL that the client can fetch directly
|
// Return a download URL that the client can fetch directly
|
||||||
|
const filename = backup.filename || `${backup.serviceName}-${backup.createdAt}.tar.enc`;
|
||||||
return {
|
return {
|
||||||
downloadUrl: `/api/backups/${dataArg.backupId}/download`,
|
downloadUrl: `/api/backups/${dataArg.backupId}/download`,
|
||||||
filename: backup.filename,
|
filename,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ import * as smartregistry from '@push.rocks/smartregistry';
|
|||||||
export { smartregistry };
|
export { smartregistry };
|
||||||
|
|
||||||
// S3-compatible storage server
|
// S3-compatible storage server
|
||||||
import * as smarts3 from '@push.rocks/smarts3';
|
import * as smartstorage from '@push.rocks/smartstorage';
|
||||||
export { smarts3 };
|
export { smartstorage };
|
||||||
|
|
||||||
// Task scheduling and cron jobs
|
// Task scheduling and cron jobs
|
||||||
import * as taskbuffer from '@push.rocks/taskbuffer';
|
import * as taskbuffer from '@push.rocks/taskbuffer';
|
||||||
@@ -67,3 +67,12 @@ export { typedrequest, typedserver };
|
|||||||
import * as smartguard from '@push.rocks/smartguard';
|
import * as smartguard from '@push.rocks/smartguard';
|
||||||
import * as smartjwt from '@push.rocks/smartjwt';
|
import * as smartjwt from '@push.rocks/smartjwt';
|
||||||
export { smartguard, smartjwt };
|
export { smartguard, smartjwt };
|
||||||
|
|
||||||
|
// Backup archive (content-addressed dedup storage)
|
||||||
|
import { ContainerArchive } from '@serve.zone/containerarchive';
|
||||||
|
export { ContainerArchive };
|
||||||
|
|
||||||
|
// Node.js compat for streaming
|
||||||
|
import * as nodeFs from 'node:fs';
|
||||||
|
import * as nodeStream from 'node:stream';
|
||||||
|
export { nodeFs, nodeStream };
|
||||||
|
|||||||
@@ -356,7 +356,9 @@ export interface IBackup {
|
|||||||
serviceId: number;
|
serviceId: number;
|
||||||
serviceName: string; // Denormalized for display
|
serviceName: string; // Denormalized for display
|
||||||
filename: string;
|
filename: string;
|
||||||
|
snapshotId?: string; // ContainerArchive snapshot ID (new backups)
|
||||||
sizeBytes: number;
|
sizeBytes: number;
|
||||||
|
storedSizeBytes?: number; // Actual stored size after dedup+compression
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
includesImage: boolean;
|
includesImage: boolean;
|
||||||
platformResources: TPlatformServiceType[]; // Which platform types were backed up
|
platformResources: TPlatformServiceType[]; // Which platform types were backed up
|
||||||
@@ -399,7 +401,8 @@ export interface IBackupPlatformResource {
|
|||||||
|
|
||||||
export interface IBackupResult {
|
export interface IBackupResult {
|
||||||
backup: IBackup;
|
backup: IBackup;
|
||||||
filePath: string;
|
filePath?: string; // Legacy file-based backups only
|
||||||
|
snapshotId?: string; // ContainerArchive snapshot ID
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRestoreOptions {
|
export interface IRestoreOptions {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -28,7 +28,9 @@ export interface IBackup {
|
|||||||
serviceId: number;
|
serviceId: number;
|
||||||
serviceName: string;
|
serviceName: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
|
snapshotId?: string;
|
||||||
sizeBytes: number;
|
sizeBytes: number;
|
||||||
|
storedSizeBytes?: number;
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
includesImage: boolean;
|
includesImage: boolean;
|
||||||
platformResources: TPlatformServiceType[];
|
platformResources: TPlatformServiceType[];
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@serve.zone/onebox',
|
name: '@serve.zone/onebox',
|
||||||
version: '1.23.0',
|
version: '1.24.2',
|
||||||
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
description: 'Self-hosted container platform with automatic SSL and DNS - a mini Heroku for single servers'
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user