Compare commits

...

6 Commits

Author SHA1 Message Date
0c9eb0653d v1.24.2
All checks were successful
Release / build-and-release (push) Successful in 3m37s
2026-03-24 20:17:30 +00:00
ed6a35eb86 fix(deps): bump runtime and build tool dependencies 2026-03-24 20:17:30 +00:00
242677404b v1.24.1
Some checks failed
Release / build-and-release (push) Failing after 24s
2026-03-24 20:08:25 +00:00
8c6159c596 fix(repo): migrate smart build config to .smartconfig.json and tidy repository metadata 2026-03-24 20:08:25 +00:00
c210507951 v1.24.0
All checks were successful
Release / build-and-release (push) Successful in 3m6s
2026-03-24 19:54:56 +00:00
0799efadae feat(backup): add containerarchive-backed backup storage, restore, download, and pruning support 2026-03-24 19:54:56 +00:00
24 changed files with 1382 additions and 864 deletions

29
.gitignore vendored
View File

@@ -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/

View File

@@ -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": {}
} }

View File

@@ -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

View File

@@ -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": [

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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)}`);
}
}
} }

View File

@@ -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,

View File

@@ -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();

View File

@@ -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)}`);
} }
} }

View File

@@ -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 {

View 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)');
}
}

View File

@@ -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);
} }

View File

@@ -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,

View File

@@ -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,
}; };
}, },
), ),

View File

@@ -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 };

View File

@@ -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

View File

@@ -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[];

View File

@@ -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'
} }