diff --git a/.github/workflows/sync_php_files.yml b/.github/workflows/sync_php_files.yml index e0dc2c0c1..012cf4686 100644 --- a/.github/workflows/sync_php_files.yml +++ b/.github/workflows/sync_php_files.yml @@ -4,11 +4,11 @@ on: branches: - dev paths: - - 'apps/php/src/apt_install.sh' - - 'apps/php/src/cmd.sh' - - 'apps/php/src/extensions.ini' - - 'apps/php/src/php_extra.ini' - - 'apps/php/src/php_install.sh' + - 'archive/apps/php/src/apt_install.sh' + - 'archive/apps/php/src/cmd.sh' + - 'archive/apps/php/src/extensions.ini' + - 'archive/apps/php/src/php_extra.ini' + - 'archive/apps/php/src/php_install.sh' jobs: sync-php-files: runs-on: ubuntu-latest @@ -21,7 +21,7 @@ jobs: - name: Sync files to apps/phpfpmapache/src run: | root_dir=$(pwd) - source_files_dir="$root_dir/apps/php/src" + source_files_dir="$root_dir/archive/apps/php/src" destination_dir="$root_dir/apps/phpfpmapache/src" file_list="apt_install.sh,cmd.sh,extensions.ini,php_extra.ini,php_install.sh" for file in $(echo $file_list | tr ',' '\n'); do @@ -31,7 +31,7 @@ jobs: - name: Sync files to apps/phpfpmnginx/src run: | root_dir=$(pwd) - source_files_dir="$root_dir/apps/php/src" + source_files_dir="$root_dir/archive/apps/php/src" destination_dir="$root_dir/apps/phpfpmnginx/src" file_list="apt_install.sh,cmd.sh,extensions.ini,php_extra.ini,php_install.sh" for file in $(echo $file_list | tr ',' '\n'); do @@ -41,4 +41,4 @@ jobs: - name: Commit and push changes uses: stefanzweifel/git-auto-commit-action@v4 with: - commit_message: Sync PHP Files \ No newline at end of file + commit_message: Sync PHP Files diff --git a/.opencode/command/libs-batch-update-app.md b/.opencode/command/libs-batch-update-app.md new file mode 100644 index 000000000..2a18db3b5 --- /dev/null +++ b/.opencode/command/libs-batch-update-app.md @@ -0,0 +1,41 @@ +--- +description: Implement approved updates for a batch of apps selected by app names or initials +agent: build +argument-hint: [app list | initials] [options optional] +--- + +Use the `batch-app-update` skill to run the batch app update workflow. + +The slash command stays action-first (`libs-batch-update-app`) even though the shared skill label is `batch-app-update`. + +Usage: `/libs-batch-update-app ` + +Supported selector forms: + +- explicit app list, for example `n8n,nocodb,netdata` +- initials, for example `n,m` to target all apps whose names start with `n` or `m` +- mixed input when clear, for example `n8n,n,m` + +Supported options: + +- `--mode auto|app-list|initials` +- `--concurrency 1|2|3` +- `--continue` +- `--stop-on-first-failure` +- `--report` + +Default behavior: + +- selector mode defaults to `auto` +- concurrency defaults to `2` +- failure policy defaults to `continue` +- apps that appear to require reverse-engineering from an official `install.sh` without a clear official Compose spec, especially when the runtime likely exceeds 5 containers, should be skipped quickly and recorded in the batch summary for later manual follow-up +- after each app passes automated validation, run `libs appstore-sync --app ` so the updated package is synced into the appstore environment for the later manual E2E pass + +If the task input is `help` or empty, echo the usage line, then ask the user for the selector. + +If the task input is present, treat it as the workflow input. + +If the task input contains `--report`, `formal`, or `formal-report`, produce the output using `report-template.md` from the skill. + +$ARGUMENTS diff --git a/.opencode/command/libs-update-app.md b/.opencode/command/libs-update-app.md index cd89ff7c2..5c4cde9f2 100644 --- a/.opencode/command/libs-update-app.md +++ b/.opencode/command/libs-update-app.md @@ -10,7 +10,7 @@ The slash command stays action-first (`libs-update-app`) even though the shared Usage: /libs-update-app [target version] -If the task input is `help` or empty, echo the usage line, then ask the user for the app name. The target version is optional: when omitted, detect the best candidate stable version, continue automatically when the choice is clear, and ask for confirmation only when the candidate is ambiguous, risky, or review-first. +If the task input is `help` or empty, echo the usage line, then ask the user for the app name. The target version is optional: when omitted, detect the best candidate stable version and continue automatically when the choice is clear. A major version jump by itself is not a reason to stop for confirmation, because this workflow updates repository packaging rather than performing a live-instance migration. Ask for confirmation only when the candidate is ambiguous, risky for the package itself, or review-first. If the task input is present, treat it as the workflow input. diff --git a/CHANGELOG.md b/CHANGELOG.md index 327aa4842..0911432be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,16 @@ and versions prior to 0.8.0 do not strictly follow this format. ## [0.8.0] - Unreleased ### Added -- `libs dns-bind` / `libs dns-delete` for Aliyun DNS wildcard records, plus the `aliyun` provider in `make connector` +- `make dns-bind` / `make dns-delete` for Aliyun DNS wildcard records +- Generic DNS credentials in `make connector` (`dns` → `.secrets/dns.env` with `DNS_PROVIDER`/`DNS_KEY_ID`/`DNS_KEY_SECRET`/`DNS_DOMAIN`), plus cloud-provider options `alibabacloud` (`.secrets/aliyun.env`), `aws` (`.secrets/aws.env`), and `azure` (`.secrets/azure.env`) +- `make create-aliyun-ecs` to launch a spot Aliyun ECS instance from the fixed `ci/cloud/aliyun-ecs.json` config, with interactive disk size (bounded by the config range) and auto-release time; the marketplace `ImageId` is resolved from the product code via ECS `DescribeImages`, the instance is named `libs-test-`, and the public IP is printed after creation - Appstore Publish workflow with v2/catalog/library/manifest output model - Channel-aware distribution merge for dev channel - `workflow_dispatch` support for manual dev/rc/release publishing - Contentful GraphQL catalog fetching (`build/fetch_catalog.py`) ### Changed +- Moved `dns-bind`, `dns-delete`, and `websoft9-upgrade` from `libs` commands to `make` targets (`make dns-bind`, `make dns-delete`, `make websoft9-upgrade`) - Simplified `library.json` to only retain `Version` field - GitHub Release tag now uses `library.json` Version instead of run_number - Removed legacy `release.yml` and `release-dev.yml` workflows diff --git a/Makefile b/Makefile index 6d73021bf..5b97fb3e8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help opencode opencode-clear install libs cli remote connector test test-cli test-build test-skills +.PHONY: help opencode opencode-clear install libs cli remote connector dns-bind dns-delete websoft9-upgrade create-aliyun-ecs test test-cli test-build test-skills ifeq ($(OS),Windows_NT) PYTHON ?= py @@ -18,6 +18,11 @@ help: @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'opencode-clear' 'list opencode sessions, confirm, then delete them (ARGS: --all/--dry-run)' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'cli' 'enter an activated shell for libs' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'libs' 'run one libs command, e.g. make libs ARGS="scan --app wordpress --json"' + @printf '\n \033[1;35m▸ Server Ops\033[0m\n' + @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'dns-bind' 'point the wildcard record (*.) at the remote host or localhost (ARGS: --domain/--ip/--json)' + @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'dns-delete' 'delete the single wildcard record (*.) for the domain (ARGS: --domain/--json)' + @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'websoft9-upgrade' 'upgrade the Websoft9 platform container: set image tag, pull, recreate (ARGS: --tag/--target)' + @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'create-aliyun-ecs' 'create a spot Aliyun ECS instance from ci/cloud/aliyun-ecs.json (ARGS: --disk-size/--release-in)' @printf '\n \033[1;35m▸ Testing & Quality\033[0m\n' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'test' 'run the full repo machine-system test suite' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'test-cli' 'run cli unit and contract tests' @@ -27,7 +32,7 @@ help: @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'help' 'show this help' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'install' 'create .venv and install the libs CLI' @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'remote' 'interactively write .secrets/remote.env for remote-aware commands' - @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'connector' 'interactively write .secrets/.env for external API tokens' + @printf ' \033[2mmake \033[0m\033[1;32m%-18s\033[0m %s\n' 'connector' 'interactively write .secrets/.env for API tokens, DNS and cloud credentials' @printf '\n' opencode: @@ -52,6 +57,26 @@ libs: if [ -n "$$proxy" ]; then export https_proxy="$$proxy" http_proxy="$$proxy" all_proxy="$$proxy" no_proxy= NO_PROXY=; fi; \ $(VENV_BIN)/libs $(ARGS) +dns-bind: + @proxy="$${https_proxy:-$${HTTPS_PROXY:-$${http_proxy:-$${HTTP_PROXY:-}}}}"; \ + if [ -n "$$proxy" ]; then export https_proxy="$$proxy" http_proxy="$$proxy" all_proxy="$$proxy" no_proxy= NO_PROXY=; fi; \ + $(VENV_BIN)/python -m libs.ops dns-bind $(ARGS) + +dns-delete: + @proxy="$${https_proxy:-$${HTTPS_PROXY:-$${http_proxy:-$${HTTP_PROXY:-}}}}"; \ + if [ -n "$$proxy" ]; then export https_proxy="$$proxy" http_proxy="$$proxy" all_proxy="$$proxy" no_proxy= NO_PROXY=; fi; \ + $(VENV_BIN)/python -m libs.ops dns-delete $(ARGS) + +websoft9-upgrade: + @proxy="$${https_proxy:-$${HTTPS_PROXY:-$${http_proxy:-$${HTTP_PROXY:-}}}}"; \ + if [ -n "$$proxy" ]; then export https_proxy="$$proxy" http_proxy="$$proxy" all_proxy="$$proxy" no_proxy= NO_PROXY=; fi; \ + $(VENV_BIN)/python -m libs.ops websoft9-upgrade $(ARGS) + +create-aliyun-ecs: + @proxy="$${https_proxy:-$${HTTPS_PROXY:-$${http_proxy:-$${HTTP_PROXY:-}}}}"; \ + if [ -n "$$proxy" ]; then export https_proxy="$$proxy" http_proxy="$$proxy" all_proxy="$$proxy" no_proxy= NO_PROXY=; fi; \ + $(VENV_BIN)/python -m libs.ops create-aliyun-ecs $(ARGS) + cli: @echo "Entering a shell with the libs CLI activated. Type 'exit' to leave." @exec bash -c 'source $(VENV_ACTIVATE); \ @@ -92,35 +117,90 @@ connector: @mkdir -p .secrets @bash -lc 'set -e; \ current_choice=1; \ - if [ "${PROVIDER:-}" = "cloudflare" ] || [ "${PROVIDER:-}" = "2" ]; then current_choice=2; fi; \ - if [ "${PROVIDER:-}" = "dockerhub" ] || [ "${PROVIDER:-}" = "3" ]; then current_choice=3; fi; \ - if [ "${PROVIDER:-}" = "aliyun" ] || [ "${PROVIDER:-}" = "4" ]; then current_choice=4; fi; \ - printf "Available providers:\n 1) contentful\n 2) cloudflare\n 3) dockerhub\n 4) aliyun (DNS)\n"; \ + if [ "$${PROVIDER:-}" = "cloudflare" ] || [ "$${PROVIDER:-}" = "2" ]; then current_choice=2; fi; \ + if [ "$${PROVIDER:-}" = "dockerhub" ] || [ "$${PROVIDER:-}" = "3" ]; then current_choice=3; fi; \ + if [ "$${PROVIDER:-}" = "dns" ] || [ "$${PROVIDER:-}" = "4" ]; then current_choice=4; fi; \ + if [ "$${PROVIDER:-}" = "alibabacloud" ] || [ "$${PROVIDER:-}" = "5" ]; then current_choice=5; fi; \ + if [ "$${PROVIDER:-}" = "aws" ] || [ "$${PROVIDER:-}" = "6" ]; then current_choice=6; fi; \ + if [ "$${PROVIDER:-}" = "azure" ] || [ "$${PROVIDER:-}" = "7" ]; then current_choice=7; fi; \ + printf "Available providers:\n 1) contentful\n 2) cloudflare\n 3) dockerhub\n 4) dns\n 5) alibabacloud\n 6) aws\n 7) azure\n"; \ read -r -p "provider [$$current_choice]: " input_choice; input_choice="$${input_choice:-$$current_choice}"; \ case "$$input_choice" in \ 1|contentful) provider="contentful"; file=".secrets/contentful.env"; key="CONTENTFUL_ACCESS_TOKEN" ;; \ 2|cloudflare) provider="cloudflare"; file=".secrets/cloudflare.env"; key="CLOUDFLARE_API_TOKEN" ;; \ 3|dockerhub) provider="dockerhub"; file=".secrets/dockerhub.env"; key="DOCKERHUB_TOKEN" ;; \ - 4|aliyun) provider="aliyun"; file=".secrets/aliyun.env"; key="ALIYUN_ACCESS_KEY_SECRET" ;; \ + 4|dns) provider="dns"; file=".secrets/dns.env" ;; \ + 5|alibabacloud) provider="aliyun"; file=".secrets/aliyun.env" ;; \ + 6|aws) provider="aws"; file=".secrets/aws.env" ;; \ + 7|azure) provider="azure"; file=".secrets/azure.env" ;; \ *) echo "unsupported provider selection: $$input_choice" >&2; exit 1 ;; \ esac; \ if [ -f "$$file" ]; then echo "updating $$file"; else echo "creating $$file"; fi; \ - if [ "$$provider" = "aliyun" ]; then \ - cur_id=""; cur_secret=""; cur_domain=""; \ + if [ "$$provider" = "dns" ]; then \ + cur_dns=""; cur_id=""; cur_secret=""; cur_domain=""; \ + if [ -f "$$file" ]; then \ + cur_dns="$$(grep -E '^DNS_PROVIDER=' "$$file" | cut -d= -f2-)"; \ + cur_id="$$(grep -E '^DNS_KEY_ID=' "$$file" | cut -d= -f2-)"; \ + cur_secret="$$(grep -E '^DNS_KEY_SECRET=' "$$file" | cut -d= -f2-)"; \ + cur_domain="$$(grep -E '^DNS_DOMAIN=' "$$file" | cut -d= -f2-)"; \ + fi; \ + cur_dns="$${cur_dns:-aliyun}"; \ + read -r -p "DNS_PROVIDER (e.g. aliyun) [$$cur_dns]: " input_dns; input_dns="$${input_dns:-$$cur_dns}"; \ + read -r -p "DNS_KEY_ID [$$cur_id]: " input_id; input_id="$${input_id:-$$cur_id}"; \ + read -r -s -p "DNS_KEY_SECRET [keep existing]: " input_secret; echo; input_secret="$${input_secret:-$$cur_secret}"; \ + read -r -p "DNS_DOMAIN (wildcard base, e.g. libs.websoft9.cn) [$$cur_domain]: " input_domain; input_domain="$${input_domain:-$$cur_domain}"; \ + if [ -z "$$input_dns" ] || [ -z "$$input_id" ] || [ -z "$$input_secret" ]; then echo "provider, key id and secret are required" >&2; exit 1; fi; \ + if [ -n "$$input_domain" ]; then \ + printf "DNS_PROVIDER=%s\nDNS_KEY_ID=%s\nDNS_KEY_SECRET=%s\nDNS_DOMAIN=%s\n" "$$input_dns" "$$input_id" "$$input_secret" "$$input_domain" > "$$file"; \ + else \ + printf "DNS_PROVIDER=%s\nDNS_KEY_ID=%s\nDNS_KEY_SECRET=%s\n" "$$input_dns" "$$input_id" "$$input_secret" > "$$file"; \ + fi; \ + elif [ "$$provider" = "aliyun" ]; then \ + cur_id=""; cur_secret=""; cur_region=""; \ if [ -f "$$file" ]; then \ cur_id="$$(grep -E '^ALIYUN_ACCESS_KEY_ID=' "$$file" | cut -d= -f2-)"; \ cur_secret="$$(grep -E '^ALIYUN_ACCESS_KEY_SECRET=' "$$file" | cut -d= -f2-)"; \ - cur_domain="$$(grep -E '^ALIYUN_DNS_DOMAIN=' "$$file" | cut -d= -f2-)"; \ + cur_region="$$(grep -E '^ALIYUN_REGION=' "$$file" | cut -d= -f2-)"; \ fi; \ read -r -p "ALIYUN_ACCESS_KEY_ID [$$cur_id]: " input_id; input_id="$${input_id:-$$cur_id}"; \ read -r -s -p "ALIYUN_ACCESS_KEY_SECRET [keep existing]: " input_secret; echo; input_secret="$${input_secret:-$$cur_secret}"; \ - read -r -p "ALIYUN_DNS_DOMAIN (wildcard base, e.g. libs.websoft9.cn) [$$cur_domain]: " input_domain; input_domain="$${input_domain:-$$cur_domain}"; \ + read -r -p "ALIYUN_REGION (optional, e.g. cn-hongkong) [$$cur_region]: " input_region; input_region="$${input_region:-$$cur_region}"; \ if [ -z "$$input_id" ] || [ -z "$$input_secret" ]; then echo "access key id and secret are required" >&2; exit 1; fi; \ - if [ -n "$$input_domain" ]; then \ - printf "ALIYUN_ACCESS_KEY_ID=%s\nALIYUN_ACCESS_KEY_SECRET=%s\nALIYUN_DNS_DOMAIN=%s\n" "$$input_id" "$$input_secret" "$$input_domain" > "$$file"; \ + if [ -n "$$input_region" ]; then \ + printf "ALIYUN_ACCESS_KEY_ID=%s\nALIYUN_ACCESS_KEY_SECRET=%s\nALIYUN_REGION=%s\n" "$$input_id" "$$input_secret" "$$input_region" > "$$file"; \ else \ printf "ALIYUN_ACCESS_KEY_ID=%s\nALIYUN_ACCESS_KEY_SECRET=%s\n" "$$input_id" "$$input_secret" > "$$file"; \ fi; \ + elif [ "$$provider" = "aws" ]; then \ + cur_id=""; cur_secret=""; cur_region=""; \ + if [ -f "$$file" ]; then \ + cur_id="$$(grep -E '^AWS_ACCESS_KEY_ID=' "$$file" | cut -d= -f2-)"; \ + cur_secret="$$(grep -E '^AWS_SECRET_ACCESS_KEY=' "$$file" | cut -d= -f2-)"; \ + cur_region="$$(grep -E '^AWS_REGION=' "$$file" | cut -d= -f2-)"; \ + fi; \ + read -r -p "AWS_ACCESS_KEY_ID [$$cur_id]: " input_id; input_id="$${input_id:-$$cur_id}"; \ + read -r -s -p "AWS_SECRET_ACCESS_KEY [keep existing]: " input_secret; echo; input_secret="$${input_secret:-$$cur_secret}"; \ + read -r -p "AWS_REGION (optional, e.g. us-east-1) [$$cur_region]: " input_region; input_region="$${input_region:-$$cur_region}"; \ + if [ -z "$$input_id" ] || [ -z "$$input_secret" ]; then echo "access key id and secret are required" >&2; exit 1; fi; \ + if [ -n "$$input_region" ]; then \ + printf "AWS_ACCESS_KEY_ID=%s\nAWS_SECRET_ACCESS_KEY=%s\nAWS_REGION=%s\n" "$$input_id" "$$input_secret" "$$input_region" > "$$file"; \ + else \ + printf "AWS_ACCESS_KEY_ID=%s\nAWS_SECRET_ACCESS_KEY=%s\n" "$$input_id" "$$input_secret" > "$$file"; \ + fi; \ + elif [ "$$provider" = "azure" ]; then \ + cur_sub=""; cur_tenant=""; cur_client=""; cur_secret=""; \ + if [ -f "$$file" ]; then \ + cur_sub="$$(grep -E '^AZURE_SUBSCRIPTION_ID=' "$$file" | cut -d= -f2-)"; \ + cur_tenant="$$(grep -E '^AZURE_TENANT_ID=' "$$file" | cut -d= -f2-)"; \ + cur_client="$$(grep -E '^AZURE_CLIENT_ID=' "$$file" | cut -d= -f2-)"; \ + cur_secret="$$(grep -E '^AZURE_CLIENT_SECRET=' "$$file" | cut -d= -f2-)"; \ + fi; \ + read -r -p "AZURE_SUBSCRIPTION_ID [$$cur_sub]: " input_sub; input_sub="$${input_sub:-$$cur_sub}"; \ + read -r -p "AZURE_TENANT_ID [$$cur_tenant]: " input_tenant; input_tenant="$${input_tenant:-$$cur_tenant}"; \ + read -r -p "AZURE_CLIENT_ID [$$cur_client]: " input_client; input_client="$${input_client:-$$cur_client}"; \ + read -r -s -p "AZURE_CLIENT_SECRET [keep existing]: " input_secret; echo; input_secret="$${input_secret:-$$cur_secret}"; \ + if [ -z "$$input_sub" ] || [ -z "$$input_tenant" ] || [ -z "$$input_client" ] || [ -z "$$input_secret" ]; then echo "subscription id, tenant id, client id and client secret are required" >&2; exit 1; fi; \ + printf "AZURE_SUBSCRIPTION_ID=%s\nAZURE_TENANT_ID=%s\nAZURE_CLIENT_ID=%s\nAZURE_CLIENT_SECRET=%s\n" "$$input_sub" "$$input_tenant" "$$input_client" "$$input_secret" > "$$file"; \ elif [ "$$provider" = "dockerhub" ]; then \ cur_user=""; cur_token=""; cur_org=""; \ if [ -f "$$file" ]; then \ diff --git a/Notes.md b/Notes.md index 78aa9c256..1dca8d53e 100644 --- a/Notes.md +++ b/Notes.md @@ -26,11 +26,8 @@ Docker Model Runner 1. 把 README/Notes 再补成“如何取默认登录邮箱、如何登录”的最终文案 2. 继续排查 workload-launcher 的重启原因,争取把日志风险也压到最低 -InfluxDB 开源时序数据库 -OpenClaw -Canvas LMS -Semaphore +Canvas LMS cloudreve,compreface,commafeed, coze,dashy,ejbca, frigate, falcon @@ -42,4 +39,9 @@ RustDesk elizaOS Nuclear -port define? \ No newline at end of file +port define? + +canvas 令牌无效 +jfrog 的默认账号密码 +nginxproxymanager 没有显示 +elasticsearch 域名访问报错。大概原因是 es 默认有 https 和 http 两种机制。 \ No newline at end of file diff --git a/active-app-suspicious-packages-report-2026-10-13.md b/active-app-suspicious-packages-report-2026-10-13.md new file mode 100644 index 000000000..a17fd1e19 --- /dev/null +++ b/active-app-suspicious-packages-report-2026-10-13.md @@ -0,0 +1,234 @@ +# Suspicious Active App Packages Report + +Date: 2026-10-13 + +Scope: +- active apps under `apps/` +- goal: find packages that look unimplemented, barely adapted, or still mostly a template/scaffold copy + +Method: +- repository-wide heuristic scan for placeholder text, demo scripts, generic bootstrap logic, cross-app copy/paste, mismatched image identity, and runtime/scaffold packages presented as finished apps +- manual review of the strongest candidates + +## High-Confidence Suspects + +These are the apps I consider the most suspicious because they look like they were not really implemented as app packages, or are still mostly template/demo scaffolds. + +### 1. `apps/docusaurus` + +Why it is suspicious: +- This looks like an old scaffold with very weak app-local adaptation. +- The README contains an obvious cross-app copy/paste error. +- The `.env` layout does not follow current repo packaging conventions at all. + +Evidence: +- `apps/docusaurus/.env:1-13` + The file is only 13 lines, uses `W9_NAME`, has no `W9_REPO`, no protected `W9_ID` block, and no current template structure. +- `apps/docusaurus/README.md:3` + Still says: `This is an Docker Compose template`. +- `apps/docusaurus/README.md:11` + System requirements link points to ONLYOFFICE docs: `https://github.com/onlyoffice/docker#recommended-system-requirements`. +- `apps/docusaurus/README.md:18-26` + README remains generic marketplace/install copy with little app-specific operational detail. + +Assessment: +- Strong candidate for “not really upgraded/implemented”. +- Should be reviewed as a stale active package. + +### 2. `apps/nodejs` + +Why it is suspicious: +- This is not an actual Node.js application package. It is a generic Node runtime that writes and runs a demo app on startup. +- The docs present it like a finished app with an admin console and password flow, which does not match the runtime. + +Evidence: +- `apps/nodejs/src/cmd.sh:4` + Literal placeholder text: `Add your CI code here, below is example`. +- `apps/nodejs/src/cmd.sh:6-21` + Writes a throwaway Hello World HTTP server into `app.js` and runs it. +- `apps/nodejs/src/cmd.sh:23-52` + Keeps commented sample sections for Express and Docusaurus. +- `apps/nodejs/.env:12` + Comment says: `# replace this with your application's port`. +- `apps/nodejs/docker-compose.yml:10-11` + The package mounts and executes the demo script directly. +- `apps/nodejs/README.md:14-21` + Generic “sign in to the Node.js admin console” and “Change Password” wording that does not fit a plain Node runtime. + +Assessment: +- High-confidence scaffold/runtime package rather than a real app package. +- If intentionally kept, it should likely be classified/documented as a runtime template, not a normal application package. + +### 3. `apps/nginx` + +Why it is suspicious: +- This package still bootstraps a demo page and tells users to replace it. +- It behaves like a generic hosting scaffold, not a real app implementation. + +Evidence: +- `apps/nginx/src/cmd.sh:1` + `### Default Demo which you can delete it` +- `apps/nginx/src/cmd.sh:3` + `Add your CI code here, below is example` +- `apps/nginx/src/cmd.sh:4-6` + Writes `Hello, Nginx!` into `/usr/share/nginx/html/index.html`. +- `apps/nginx/src/cmd.sh:13-16` + Commented sample download/unzip demo instructions. +- `apps/nginx/docker-compose.yml` + Mounts and runs that script as part of startup. + +Assessment: +- High-confidence generic scaffold package, not a real app-specific packaging effort. + +### 4. `apps/springboot` + +Why it is suspicious: +- This is a development workspace/demo generator, not a finished Spring Boot application package. +- The public identity and README tone overstate how productized it is. + +Evidence: +- `apps/springboot/README.md:14-22` + Explicitly says the default demo returns `Spring Boot is running...`, `/hello`, `/actuator/health`, and that the project is generated into `/workspace` on first start. +- `apps/springboot/README.md:19-22` + Tells users to exec into the container and edit Java code in `/workspace`. +- `apps/springboot/README.md:33` + Claims it is packaged from the “official Spring Boot Docker image”. +- `apps/springboot/README.md:87` + References `https://hub.docker.com/_/maven`, indicating the actual runtime is Maven-based rather than a Spring Boot app image. + +Assessment: +- High-confidence runtime/scaffold package rather than a real application package. +- Similar to `nodejs`, probably intentional, but should not be mistaken for a properly adapted application package. + +### 5. `apps/php` + +Why it is suspicious: +- This package is largely a generic PHP runtime scaffold with sample bootstrap behavior. +- It still carries “for your reference” demo logic instead of app-specific implementation. + +Evidence: +- `apps/php/src/cmd.sh:4` + `## Sample for you` +- `apps/php/src/cmd.sh:6-12` + Creates a default `phpinfo()` page when the web root is empty. +- `apps/php/src/cmd.sh:15-21` + Keeps commented “Install WordPress for your reference” sample steps. +- `apps/php/README.md:3` + Still uses older wording: `This is an Docker Compose template`. + +Assessment: +- High-confidence scaffold/runtime package, not a real app package. + +## Medium-Confidence Suspects + +These are likely intentional runtime/scaffold packages or partially adapted packages, but they still look misleading or under-implemented. + +### 6. `apps/nextjs` + +Why it is suspicious: +- Uses a generic Node runtime image and scaffolds a default Next.js app. +- This is closer to a runtime/template than a finished application package. + +Evidence: +- `apps/nextjs/.env:1` + Uses `W9_REPO=node`. +- `apps/nextjs/docker-compose.yml:3` + Uses `image: ${W9_REPO}:${NODE_IMAGE_TAG}`. +- Existing package behavior and docs indicate first-start scaffold/build workflow rather than a finished application. + +Assessment: +- Probably intentional as a runtime package. +- Still suspicious if evaluated as a normal “active app” because it is not really an app package in the usual sense. + +### 7. `apps/laravel` + +Why it is suspicious: +- Similar pattern to `nextjs` and `springboot`: runtime/scaffold behavior presented like a finished app. + +Evidence: +- Uses a PHP runtime stack rather than a Laravel image. +- Repo docs/changelog describe first-start scaffolding of a default Laravel project. +- README language reportedly still uses generic “admin console” and password wording. + +Assessment: +- Likely intentional runtime package, but not a true application package. + +### 8. `apps/django` + +Why it is suspicious: +- Similar runtime/scaffold identity drift. + +Evidence: +- Uses `W9_REPO=python` and Python base-image behavior rather than a Django app image. +- Package behavior reportedly scaffolds a default Django project on first start. + +Assessment: +- Likely intentional runtime package, but suspicious if counted as a fully implemented application package. + +### 9. `apps/openhands` + +Why it is suspicious: +- The package identity says `OpenHands`, but the actual image and docs point to Agent Canvas backend setup. + +Evidence: +- `apps/openhands/.env:1` + `W9_REPO=ghcr.io/openhands/agent-canvas` +- `apps/openhands/.env:20` + Docs URL points to `openhands/usage/agent-canvas/backend-setup/docker` +- `apps/openhands/.env:31-34` + Uses backend/API-key and secret settings tied to Agent Canvas. + +Assessment: +- Could be valid if the app is intentionally this specific OpenHands subproduct. +- Still suspicious because package identity and actual runtime/docs are not cleanly aligned. + +## Lower-Severity Template Residue + +These apps appear implemented, but still contain clear template leftovers and should be cleaned up. + +### `apps/dify` +- `apps/dify/Notes.md:1` is still `# Appname` +- `apps/dify/Notes.md:2` is only `## FAQ` + +### `apps/nginxproxymanager` +- `apps/nginxproxymanager/Notes.md:1` is still `# Appname` + +### `apps/openhands` +- `apps/openhands/Notes.md:1` is still `# Appname` + +### `apps/openclaw` +- `apps/openclaw/Notes.md:1` is still `# Appname` + +### `apps/consul` +- `apps/consul/Notes.md:1` is still `# Appname` + +Assessment: +- These are not proof of broken packaging by themselves. +- They are good indicators that some active packages never received a full cleanup pass. + +## Shortlist + +If only a small set should be inspected first, the strongest candidates are: + +1. `docusaurus` +2. `nodejs` +3. `nginx` +4. `springboot` +5. `php` + +These five most strongly look like one of the following: +- stale old template copies +- generic runtime scaffolds presented as app packages +- packages that were never really adapted into a proper app-specific implementation + +## Conclusion + +The active app set appears to contain two distinct kinds of suspicious entries: + +1. Truly stale or badly adapted packages +- strongest example: `docusaurus` + +2. Intentional runtime/scaffold packages that are still misleading when treated as normal application packages +- `nodejs`, `nginx`, `springboot`, `php`, `nextjs`, `laravel`, `django` + +If the repository wants every active app to be a real end-user application package rather than a language/framework workspace, the second group should probably be reclassified, documented differently, or removed from the main active app surface. diff --git a/apps/activemq/.env b/apps/activemq/.env index bef01a9e4..cfc8156de 100644 --- a/apps/activemq/.env +++ b/apps/activemq/.env @@ -1,6 +1,6 @@ W9_REPO=apache/activemq W9_DIST=community -W9_VERSION=6.3.0 +W9_VERSION=6.3.2 W9_POWER_PASSWORD=8dHZPFLFGoPXuC diff --git a/apps/activemq/CHANGELOG.md b/apps/activemq/CHANGELOG.md index cecb1d3b1..de2956e6c 100644 --- a/apps/activemq/CHANGELOG.md +++ b/apps/activemq/CHANGELOG.md @@ -1,4 +1,11 @@ # CHANGELOG -- 2026-08-25: Removed Artemis, Classic only; official `apache/activemq` image, versions 6.3.0 / 6.2.8 / 5.19.9 / latest -- 2026-08-25: Added `src/entrypoint.sh` compatible with 5.19 / 6.2 / 6.3; fixed Web Console 403, 5.19 auth & CSP, and restart loop +## 2026-10-13 + +- Updated the default ActiveMQ image tag from `6.3.0` to `6.3.2`. +- Refreshed the documented supported image tags to `6.3.2`, `6.2.10`, `5.19.11`, and `latest`. + +## 2026-08-25 + +- Removed Artemis, Classic only; official `apache/activemq` image, versions 6.3.0 / 6.2.8 / 5.19.9 / latest. +- Added `src/entrypoint.sh` compatible with 5.19 / 6.2 / 6.3; fixed Web Console 403, 5.19 auth and CSP quirks, and restart loop. diff --git a/apps/activemq/README.md b/apps/activemq/README.md index 7313c3518..7fc2cdcfa 100644 --- a/apps/activemq/README.md +++ b/apps/activemq/README.md @@ -24,7 +24,7 @@ ## Configuration Reference -Websoft9 packages this app from the official [ActiveMQ Docker image](https://hub.docker.com/r/apache/activemq/tags) and makes some improvements below. +Websoft9 packages this app from the official [ActiveMQ Docker image](https://hub.docker.com/r/apache/activemq) and makes some improvements below. - To make the Web Console reachable through the published port, the package adds `src/entrypoint.sh`, which opens the console IP allow-list and fixes 5.19 auth/CSP quirks across versions. @@ -34,7 +34,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 6.3.0, 6.2.8, 5.19.9, latest. +Supported versions: 6.3.2, 6.2.10, 5.19.11, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -70,7 +70,7 @@ Configuration is overridden by mounting `./src/entrypoint.sh` to `/opt/websoft9/ - [ActiveMQ Administrator Guide](https://support.websoft9.com/docs/activemq) by Websoft9 -- [Docker Hub image](https://hub.docker.com/r/apache/activemq/tags) +- [Docker Hub image](https://hub.docker.com/r/apache/activemq) - [Releases](https://github.com/apache/activemq/releases) @@ -90,4 +90,3 @@ Configuration is overridden by mounting `./src/entrypoint.sh` to `/opt/websoft9/ **Port not reachable?** - Ensure the cloud security group / firewall allows the port. - diff --git a/apps/activemq/variables.json b/apps/activemq/variables.json index 367bdcf19..9fd40c2de 100644 --- a/apps/activemq/variables.json +++ b/apps/activemq/variables.json @@ -13,9 +13,8 @@ { "dist": "community", "version": [ - "6.3.0", - "6.2.8", - "5.19.9", + "6.3.2", + "5.19.11", "latest" ] } diff --git a/apps/activepieces/.env b/apps/activepieces/.env index 080ff9d9a..09c732b4c 100644 --- a/apps/activepieces/.env +++ b/apps/activepieces/.env @@ -1,6 +1,6 @@ W9_REPO=ghcr.io/activepieces/activepieces W9_DIST='community' -W9_VERSION='0.88.4-hotfix.1' +W9_VERSION='0.92.3' W9_POWER_PASSWORD='cwyVT6jU!2ugmz09' # Environments which for user settings when create application @@ -33,7 +33,7 @@ AP_ENCRYPTION_KEY=62d9672ed7c55a9bf31b34149c07c9ad AP_JWT_SECRET=094d670880695794b4bf6c7556e63948ec02a5a70170e541897fd6bfebedbe5b AP_ENVIRONMENT=prod -AP_FRONTEND_URL=${W9_URL} +AP_FRONTEND_URL=http://${W9_URL} AP_INTERNAL_URL=http://activepieces/api AP_WEBHOOK_TIMEOUT_SECONDS=30 AP_TRIGGER_DEFAULT_POLL_INTERVAL=5 diff --git a/apps/activepieces/CHANGELOG.md b/apps/activepieces/CHANGELOG.md index 06a562f78..594c11b6c 100644 --- a/apps/activepieces/CHANGELOG.md +++ b/apps/activepieces/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2026-10-13 + +- Upgraded Activepieces from `0.88.4-hotfix.1` to `0.92.3`. +- Fixed `AP_FRONTEND_URL` to use `http://${W9_URL}` so the packaged public URL matches upstream self-host requirements and repository URL wiring rules. + ## 2026-08-27 - Upgraded Activepieces from `0.70.4` to `0.88.4`. diff --git a/apps/activepieces/README.md b/apps/activepieces/README.md index 291142d53..09a160e41 100644 --- a/apps/activepieces/README.md +++ b/apps/activepieces/README.md @@ -33,7 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 0.88.4-hotfix.1, latest. +Supported versions: 0.92.3, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -42,7 +42,7 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p | Purpose | Port | | --- | --- | -| W9_HTTP_PORT_SET | 80 | +| Web Console | 80 | ### Data Directory @@ -71,7 +71,7 @@ Configuration files live inside the image; mount a single file read-only to over - [GHCR image](https://ghcr.io/activepieces/activepieces) -- [Releases](https://github.com/activepieces/activepieces/tags) +- [Releases](https://github.com/activepieces/activepieces) - [Official compose](https://raw.githubusercontent.com/activepieces/activepieces/main/docker-compose.yml) diff --git a/apps/activepieces/variables.json b/apps/activepieces/variables.json index 54a056931..dbf6ec072 100644 --- a/apps/activepieces/variables.json +++ b/apps/activepieces/variables.json @@ -19,7 +19,7 @@ { "dist": "community", "version": [ - "0.88.4-hotfix.1", + "0.92.3", "latest" ] } diff --git a/apps/affine/CHANGELOG.md b/apps/affine/CHANGELOG.md index 56c260f7e..60b8671ce 100644 --- a/apps/affine/CHANGELOG.md +++ b/apps/affine/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-13 + +- Verified upstream stable remains 0.27.4; removed the unsupported `latest` version claim from package metadata. +- Marked `W9_POWER_PASSWORD` as first-startup-only because bundled PostgreSQL applies its initialization auth settings only on a fresh data directory. +- Added app-specific AFFiNE smoke coverage under `tests/cases.yml` to validate the first-run landing page beyond the default adaptive checks. + ## 2026-08-29 - Rebuilt the package on upstream 0.27.4 compose: main app + one-time `affine-migration` job, `pgvector/pgvector:pg16` Postgres, and Redis. diff --git a/apps/affine/README.md b/apps/affine/README.md index 1abdee40d..6714f8d6c 100644 --- a/apps/affine/README.md +++ b/apps/affine/README.md @@ -33,9 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 0.27.4, latest. - -The `latest` tag is not guaranteed to remain valid; pin a specific version for production. +Supported versions: 0.27.4. ### Ports @@ -58,6 +56,9 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. +Note: `W9_POWER_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + ### Configuration Files diff --git a/apps/affine/tests/cases.yml b/apps/affine/tests/cases.yml new file mode 100644 index 000000000..250dd0bb8 --- /dev/null +++ b/apps/affine/tests/cases.yml @@ -0,0 +1,4 @@ +optional: + - id: homepage-smoke + type: script + script: check.sh diff --git a/apps/affine/tests/check.sh b/apps/affine/tests/check.sh new file mode 100755 index 000000000..4cfe0b196 --- /dev/null +++ b/apps/affine/tests/check.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +base="${BASE_URL:?BASE_URL is required}" +body="$(mktemp)" +trap 'rm -f "$body"' EXIT + +status="$(curl -sS -L -o "$body" -w '%{http_code}' "${base}/")" + +case "$status" in + 200) ;; + *) + echo "unexpected HTTP ${status} from AFFiNE" >&2 + exit 1 + ;; +esac + +if ! grep -Eqi 'AFFiNE|create (your|first) account|workspace' "$body"; then + echo "response does not look like an AFFiNE landing page" >&2 + exit 1 +fi + +echo "AFFiNE responded with HTTP ${status}" diff --git a/apps/affine/variables.json b/apps/affine/variables.json index 24ba3801c..b0060a64a 100644 --- a/apps/affine/variables.json +++ b/apps/affine/variables.json @@ -18,8 +18,7 @@ { "dist": "community", "version": [ - "0.27.4", - "latest" + "0.27.4" ] } ], @@ -55,6 +54,8 @@ } }, "env": { - "first_startup_only": [] + "first_startup_only": [ + "W9_POWER_PASSWORD" + ] } } diff --git a/apps/airflow/.env b/apps/airflow/.env index 0b5f46d7d..650fb53b4 100644 --- a/apps/airflow/.env +++ b/apps/airflow/.env @@ -1,4 +1,4 @@ -W9_VERSION='3.3.1' +W9_VERSION='3.3.2' W9_DIST='community' W9_REPO=apache/airflow W9_POWER_PASSWORD='8vdZN5SoDaD!zs8o' @@ -21,3 +21,16 @@ AIRFLOW_UID=0 POSTGRES_DB=airflow POSTGRES_USER=airflow POSTGRES_PASSWORD=${W9_RCODE} + +# ============================================================ +# Airflow image environment variables +# Docs: https://airflow.apache.org/docs/apache-airflow/stable/howto/docker-compose/index.html +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# _PIP_ADDITIONAL_REQUIREMENTS= diff --git a/apps/airflow/CHANGELOG.md b/apps/airflow/CHANGELOG.md index 825fbf249..1c7934b70 100644 --- a/apps/airflow/CHANGELOG.md +++ b/apps/airflow/CHANGELOG.md @@ -1,9 +1,13 @@ # CHANGELOG +## 2026-10-13 + +- Update Airflow from 3.3.1 to 3.3.2. +- Add a minimal app-specific functional check for the version API endpoint. + ## 2026-09-02 - Update Airflow from 3.1.0 to 3.3.1. - Bump the bundled PostgreSQL from 13 to 18 (highest major Airflow 3.3.1 is tested against), now driven by `W9_DB_VERSION`. - Remove legacy `# docs:` / `# image:` source comments from `docker-compose.yml`, use braced `${VAR}` references, and add an inline `# Web Console` purpose comment to the published port. - Add a minimal README note that upgrading across Airflow/PostgreSQL majors is a data migration. - diff --git a/apps/airflow/tests/cases.yml b/apps/airflow/tests/cases.yml new file mode 100644 index 000000000..385cac403 --- /dev/null +++ b/apps/airflow/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: version-api + type: web-access + path: /api/v2/version + expect_status: 200 diff --git a/apps/airflow/variables.json b/apps/airflow/variables.json index 4d48a56d7..6780ceb4a 100644 --- a/apps/airflow/variables.json +++ b/apps/airflow/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "3.3.1", + "3.3.2", "latest" ] } diff --git a/apps/akeneo/CHANGELOG.md b/apps/akeneo/CHANGELOG.md index 337202221..1200d59cf 100644 --- a/apps/akeneo/CHANGELOG.md +++ b/apps/akeneo/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-13 +- Added `tests/cases.yml` coverage for the Akeneo login page so deploy validation exercises the real web entry path instead of only default checks. +- Hardened the Docker image package-install step with an apt index refresh retry to avoid transient Debian mirror 404 failures during build. + ## 2026-09-03 - Rebuilt the Akeneo package around a custom Dockerfile based on `akeneo/pim-php-dev:8.3`. - Updated Akeneo to `v2026.4` with a build-time `composer create-project` flow instead of runtime source installation. diff --git a/apps/akeneo/Dockerfile b/apps/akeneo/Dockerfile index 591fe66ea..d3717469d 100644 --- a/apps/akeneo/Dockerfile +++ b/apps/akeneo/Dockerfile @@ -20,7 +20,10 @@ USER root RUN mkdir -p /etc/apt/keyrings \ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ - && apt-get update \ + && export DEBIAN_FRONTEND=noninteractive \ + && sed -i 's|http://deb.debian.org/debian-security|http://archive.debian.org/debian-security|g' /etc/apt/sources.list \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get -o Acquire::Check-Valid-Until=false update \ && apt-get install -y --no-install-recommends apache2 default-mysql-client gnupg nodejs \ && npm install -g yarn@1.22.22 \ && a2enmod rewrite proxy proxy_fcgi actions alias expires headers \ diff --git a/apps/akeneo/tests/cases.yml b/apps/akeneo/tests/cases.yml new file mode 100644 index 000000000..527166cd7 --- /dev/null +++ b/apps/akeneo/tests/cases.yml @@ -0,0 +1,8 @@ +skip: + - id: web-access + +optional: + - id: login-page + type: web-access + path: /user/login + expect_status: 200 diff --git a/apps/anythingllm/.env b/apps/anythingllm/.env index 3b5d2dbf4..2bab257a2 100644 --- a/apps/anythingllm/.env +++ b/apps/anythingllm/.env @@ -1,15 +1,37 @@ W9_REPO=mintplexlabs/anythingllm -W9_DIST='community' -W9_VERSION='1.16' +W9_DIST=community +W9_VERSION=1.17 +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=anythingllm W9_HTTP_PORT=3001 -W9_HTTP_PORT_SET='9001' -W9_ID='anythingllm' -W9_URL='anythingllm.example.com' +W9_HTTP_PORT_SET=9001 +W9_URL=anythingllm.example.com W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### +#W9_NAME="" +#W9_RCODE="" + +# ============================================================ +# AnythingLLM image environment variables +# Docs: https://raw.githubusercontent.com/Mintplex-Labs/anything-llm/master/docker/.env.example +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +STORAGE_DIR=/app/server/storage -# Below environment is created by this app: https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/.env.example -STORAGE_DIR="/app/server/storage" +# Not used by default; enable only when needed: +# SERVER_PORT=3001 +# UID=1000 +# GID=1000 +# AUTH_TOKEN=hunter2 +# DISABLE_TELEMETRY=false diff --git a/apps/anythingllm/CHANGELOG.md b/apps/anythingllm/CHANGELOG.md index 808879a5a..505df1369 100644 --- a/apps/anythingllm/CHANGELOG.md +++ b/apps/anythingllm/CHANGELOG.md @@ -1,9 +1,15 @@ # CHANGELOG +## 2026-10-13 + +- Update AnythingLLM from 1.16 to 1.17 using the stable upstream image tag. +- Refresh `variables.json` upstream compose and env sources to the raw official files so drift checks resolve correctly. +- Add `tests/cases.yml` with an app-specific `/api/ping` reachability check. +- Align `.env` with the current repository layout while keeping the package's minimal AnythingLLM-specific settings. + ## 2026-09-02 - Update AnythingLLM from 1.8 to 1.16 (minor float tag). - Remove legacy `# docs:` source comments from `docker-compose.yml` and move the upstream compose/env/docs links into `variables.json` `upstream`. - Add an inline `# Web Console` purpose comment to the published port and use braced `${VAR}` references in `docker-compose.yml`. - Author a real AnythingLLM usage guide in the README `Usage` section instead of template or Notes-derived placeholder text. - diff --git a/apps/anythingllm/tests/cases.yml b/apps/anythingllm/tests/cases.yml new file mode 100644 index 000000000..7d18cba19 --- /dev/null +++ b/apps/anythingllm/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: api-ping + type: web-access + path: /api/ping + expect_status: 200 diff --git a/apps/anythingllm/variables.json b/apps/anythingllm/variables.json index 5ac946391..24889c9e8 100644 --- a/apps/anythingllm/variables.json +++ b/apps/anythingllm/variables.json @@ -6,8 +6,8 @@ "image": "https://hub.docker.com/r/mintplexlabs/anythingllm", "releases": "https://github.com/Mintplex-Labs/anything-llm", "compose": { - "compose": "https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/docker-compose.yml", - "env": "https://github.com/Mintplex-Labs/anything-llm/blob/master/docker/.env.example" + "compose": "https://raw.githubusercontent.com/Mintplex-Labs/anything-llm/master/docker/docker-compose.yml", + "env": "https://raw.githubusercontent.com/Mintplex-Labs/anything-llm/master/docker/.env.example" }, "docs": [ "https://github.com/Mintplex-Labs/anything-llm", @@ -19,7 +19,7 @@ { "dist": "community", "version": [ - "1.16", + "1.17", "latest" ] } diff --git a/apps/apisix/src/config/mkcert/lvh.me+1-key.pem b/apps/apisix/src/config/mkcert/lvh.me+1-key.pem deleted file mode 100644 index 849e5d090..000000000 --- a/apps/apisix/src/config/mkcert/lvh.me+1-key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCq5TJwEHgVNaft -kU+mytN8gNInFJCU05YfZO8w6yIbeYR4dvdUgfXhDjxb8ZcWfzC7qfpKFAeA0X0l -yHdOYmI6ONhuYW4C4ssaaiIJjnUI0ogHKYtCKPNppU0cRjdnSKWopv9QXZ9UHoRX -zDcHcUnRhL0I057tfZrPAr1X0eMVEKTSUoFVS/nRvuQiOYitiSnSONEpYEAdmGG3 -vWxvW1BI9qi4UxXK6IcNF3HUwM20oAAF+5r+3vT+zG04tKfoJfwHoevWKS5V2Rz1 -xVW/O8LWKzE1Hl5GHGPXuhZUVDEIIFIV8D67h6dT4BGMS6pUjm0HyfNAdIEHHB4d -RX+RDK75AgMBAAECggEBAKP0Lhabhkl657ghMBSqBIovIO+DaE6QTDekY2JAQ8Gu -LKxSHmmCIX4gZUIknrpjnkJ9CfZmDujEktdb4zJdazXGccY8TQoRwZ9+8VbPyHKF -YSHV9perqBPUFg2pQ+AgL2aFiO72UzSl7nw5HRZT1ule+ujr9k6MsagnTbZiVAVR -F0Lxi7QZc0PQH4tLItkAM3eujUUR+lM0pNhdVqvm2XrNANb423uz1TUvDCXe/1Wb -b7hRYIQEdXY4b3+Emi3SNMtGGBIOaNSQIgXC6s9AezTno5oWj3I5B+AGSD9VmWoK -89iQtFtW1xXjCWM0ZAqH+4b7pmlbUFuv40BqLpUYiAECgYEAw6HfyDoMXaU1q9Yg -xprSQQOrflk24ngCO5HISyEH2ZDeUWkqsOECFhkslJuJewkQfvjBza3Iee3IpJPQ -CnvOtSfnV0YQM7RctVVXmwwgVGd35GeqIM5un3r1LgRslBWpsBkOYQVrPSHnHy7v -f1t/RQHcil08pCl6kyzBS/EGefkCgYEA36Ez8vPjUoWyoFcpFJha/vC8o7Ay4SQ6 -kSUhWOLQaA8Oy3BLIH0YI6EpZvHYTtQFTCFhMfTLJpD/M0hmFHQvbhGpvB4Zi6G6 -+4GtIi+hgZ7DB86MdKRpQzELPy9JuxYavOUMlMsel2UTAPCfGn3SIJjEkfxo/t0E -8Ct0Z2sdHQECgYALosMmq500rLDmiZPlfCvpRgibOT80dSLc3Cznmw1WeXFfsjuh -zaBMJC8sn5urv7xFcRJF44I7DlOSxl/nX7nJuJff7wDjsmSZPHw7cpsxqf3NjgTm -cqDNx4hxtj2nCSrQmIzsZGAegLe4eRgxoQWO2y9841LKCNWLj2vn0mwqMQKBgQCr -/6qbBGYlBFvc4uzfwEbMqpAMPesEKv84v5wkZ17vihVQ929w74XvcXcMjJpYFs50 -PYAqEiNl6EPAR8DrnmkUeVVZMLVpJd1Qr+5fys6niVpr2LtCw2mKmmASGubUlC3A -d1Lz5j4DJ2Q0Zt2YXImPNLCLr915mLjBmEqReFsOAQKBgQCtuwlhmOE43jGKP5RJ -Ow5KhZze1gX4EA3HQOYRUE3psuzIesUEcDOvoCE/iWo22uNieqpBbXKi0CrtR6/6 -SopgMSPkNrrKDvbrM2azvdD85hoPmoYjEuyWTDJReqCzNxbHeri5Yo0/pcDqWSb3 -49RDuXS9aIj3PjFtsqQFXbfugg== ------END PRIVATE KEY----- diff --git a/apps/apisix/src/config/mkcert/lvh.me+1.pem b/apps/apisix/src/config/mkcert/lvh.me+1.pem deleted file mode 100644 index 29b6023b8..000000000 --- a/apps/apisix/src/config/mkcert/lvh.me+1.pem +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEKjCCApKgAwIBAgIQJ7+tTZRECIp1/rZvizFsADANBgkqhkiG9w0BAQsFADBl -MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExHTAbBgNVBAsMFHJvb3RA -dmtpbGwtYXJjaGxpbnV4MSQwIgYDVQQDDBtta2NlcnQgcm9vdEB2a2lsbC1hcmNo -bGludXgwHhcNMTkwNzE3MDA1NTMwWhcNMjkwNzE3MDA1NTMwWjBIMScwJQYDVQQK -Ex5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxHTAbBgNVBAsMFHJvb3RA -dmtpbGwtYXJjaGxpbnV4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -quUycBB4FTWn7ZFPpsrTfIDSJxSQlNOWH2TvMOsiG3mEeHb3VIH14Q48W/GXFn8w -u6n6ShQHgNF9Jch3TmJiOjjYbmFuAuLLGmoiCY51CNKIBymLQijzaaVNHEY3Z0il -qKb/UF2fVB6EV8w3B3FJ0YS9CNOe7X2azwK9V9HjFRCk0lKBVUv50b7kIjmIrYkp -0jjRKWBAHZhht71sb1tQSPaouFMVyuiHDRdx1MDNtKAABfua/t70/sxtOLSn6CX8 -B6Hr1ikuVdkc9cVVvzvC1isxNR5eRhxj17oWVFQxCCBSFfA+u4enU+ARjEuqVI5t -B8nzQHSBBxweHUV/kQyu+QIDAQABo3MwcTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l -BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSYvVgP4gOX -oeisL5WsQbGN4B9BZTAbBgNVHREEFDASggZsdmgubWWCCCoubHZoLm1lMA0GCSqG -SIb3DQEBCwUAA4IBgQBAuqUCOe4dYs5Wx6R99c2W+OoeyxN8RYLK8IJkUnuqzLIk -REzYuAzO99McMe61nc0s5obsVGOyhchj101Y22Roq9W6IMo5xMxtnjHBuFhMHUKL -np6U2hcd73u68q/dgq9+tQk1UhTJGVkZKr7E5FAr5Lh9ge3p+6xoc2czMGaoHKge -jcCT+nPE73Nec17LUSZhqcxlzzXIrLubi0W8IrkCoDWQYnV8HjuigpSuclAI2Pet -GD/fi6w0sERsSG2VFRA56j17l27LqFfHtz1GWMJGh7cQ+GOGe8Wviiskz5tZEQTw -y2q2CFwx9MxzBk5mO8zG4pnYhB/UMeLHiTJO4WeLP8uVkEyzckc1INsgw6Kit2oZ -hQDoHunZ7y/RfL/8xj78nya58YZ6oaf+EDVqA+JPhbAZEFC+U9+BYLmr5eB31DNc -NfeqlIybQ1xrj42QRUTGPIwfl6lwGu4L63WKVfSOOEWkx1yB/x5vUYmWK4Vub+Gs -rwqoluFp44oNMY+uy9w= ------END CERTIFICATE----- diff --git a/apps/apisix/src/config/mkcert/rootCA-key.pem b/apps/apisix/src/config/mkcert/rootCA-key.pem deleted file mode 100644 index 4dbdddb5d..000000000 --- a/apps/apisix/src/config/mkcert/rootCA-key.pem +++ /dev/null @@ -1,40 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIG/AIBADANBgkqhkiG9w0BAQEFAASCBuYwggbiAgEAAoIBgQCz/Ya3wSY9CAzL -78eJ6bugV8UEm9T/an0UDY+r9x8zSVsvz1rgqoxE1tFwc2KCdGoXe9qFc7M5HOuF -N7sbr1CusgoRbLO/zzmd/IUCkG6iLdo3dY6JcIFUQcerbSGLbqLQ54uixxsXG5l/ -5K/rS0SboxQQWXRt/+FLB3TZpSA9eNiI9WGUdtEsiZIu0H7UFjgIEer7ucFXFJPn -Yfc6zZcY25mkraIJR6+e4DA8liTaC8MzLGgpvqlGr8z/5f5Fhi8LWGJbDZKvpCyW -lsWWE7tgk7yj8tTScFtjMHynT74YNUP2SaUvgDFFSf7hUyapSpkg9dtykELSO5HC -8yK+XAXhiwuk/lwh4y9CokiX2rldQvgiuvw3eSxGhGmfAOGbn2mhHI8t+xjHzXNr -ZgYH+PluFiZ2sC8Y0eY+OWdqU0+pMa+6/6fJbZVX1eCkKNNYyv+YJlbcmVEeFUwb -Bkx/K1lJIVwWvpaEOQja8CkOImxQ68KaisNF/RHC+OFkhUMXfmMCAwEAAQKCAYAt -/FA3Enoajbv3PsPUUItHZCVKECZTO3nJbc2POgwWpl9Nz8SAMhK0Y84O1OwOOIAC -j/o8rlrT9LeXya1cXWZXu9UmroceMmueGa5CAXTCqsRd9wL7ymrAhC3ndnJjlViz -1vSuGgCp3rtRGbR4gTp+KSQvKSu+DuoYqUcJdE7QZdes5kSQEetPXbajj1FYDnUy -WqGWvtbO0MsZCsaHl49LIpAWquYDSPVtugmY8SNpMiglIutZ/wRwsunFV5WnXaip -eXOlD85lbbRzIuuydGn15aD1svQMOKyiWuA3Fr2nG7uPxgb6O5KV/cTfaKNjrJzp -lo7RF1S6Y4piXlrzDFCKc6LGjAk41kMOpjkrRVSHBtvWCFX8vNOkq09mGnGMhzSR -bA4Qj11sbVM4IGy49FCHPCw9sLZWzpjtWXFipDkuzGRedGLjuURr5iKpA5B+jVkH -iGUHfbjfU/eWiHRuDSr3UzMJ8GiSpLbZ5x1+2lUSUksvZ5ACDHXUd31Z4uGI1UEC -gcEAyvPTSaC+e3SCfKpMazfTICh/nminglKud5y5d35lU3sezw94WIJ0DJSpYVXA -rR6n2MTIku44fr53Yq25jyxjnhQ273G9QVVDfnkpHnH2+9PTLaRF8xmFhPiQBKOX -rdJK3YDgJ96aHZ2/un+kqEJ9dWetioy8zie1zYlHq0H4fjbc0MwaUC+Oi8Ys84xX -H2W9OxhDhBqhwH6eP3XJgXf3ov6PznqKJtMOO9IMJNmN067U30mVulFcVNN40fLh -up9dAoHBAOMJPEkGRzhIOHXKPmAQMIDC9DHhHU15pDCRpNLBAbcBx4fUbiaT3Xz0 -CVeqLuDlW/dKQ48t/8ftEXqt6B+KlFa5xzivulKuB5QSf3d5pDmhfksCtq3DkynF -w5CsbiYs/xNYqg+RlCJBUgCXiXimElyJ+FfxPJqU6TGpK+pH1Vkg79wAZ8y32Pkn -0cqw42xuzlYvB7pNgoWiEh2c0efISARYNl72lgrBsMQWS0x7kZsXigVVfaK4L7qC -lTIQT1N4vwKBwAl54P+rFbnF8uHHQdIvxRfXTD4lPM0E90h2dOJzcF+5e/LHEiNv -0+NSfaYhzuFGcSfZ6FOT8+dXFVPyMJvSwsP6xaXgdam7RW9+UMEvKQ0REucqqGl1 -Y5qV0IOm78oZ64z0G4NBDYkceHtIwnNox1rYAG5bq+UkTYTPSB1i8ytRfHXzUbc0 -wT8dfbPRda/tnCxKMbzVUYAfaVwlL8dvxoxBvo0xg4nUiPGaGR8PWWPs4dubH/aX -HeyIAzgqUwfXsQKBwA+12OUYuR7s6HNGLnDJTgHq+6jj8fole7YcrfIjhvHZ/quo -iILE4qO941OcpCfN10JSckBbJ4L3Jal+lTxxg3hI3L9Qca08+6tEaGulEDcotKuO -IYP+r5VJaRH+zJR5sqDtFr+DDGQebwU5dzrRCx46MeQr/kyYF1bnZPGOTPYg8Fgh -8wzYf/wlxD+pY+Nh+4c9M+SxbmG+6FACRQgr9MfQLtr9Zz6RTqETBdziBB5eT5+0 -3b+/zRWz6Y0QUdzt0wKBwEqkBkMAdT/tKN9ZM9g/FseisAfwBtmqdvZsXj9Fx0A7 -PHlEbh6G91nhXwg2zeBrakCU4YY4NY5qiz80ykwJ0uwbUUb628ai9OGqjS3LGhI3 -kYIrxQpv9mdNkJsISsYfhvMjiPt5LvxdCynC3w2FGd/pgBZwi14zkusW86pPGjVc -o5UXcZLgR68O3tfsr8+EpWVCnS7Ln2UcrWfnrBHFRCiwFCFfwO9JfgnEXNquxBGX -2Hqwp0dr/cxfVFXcD8fa9Q== ------END PRIVATE KEY----- diff --git a/apps/apisix/src/config/mkcert/rootCA.pem b/apps/apisix/src/config/mkcert/rootCA.pem deleted file mode 100644 index af505921e..000000000 --- a/apps/apisix/src/config/mkcert/rootCA.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEmTCCAwGgAwIBAgIQdbSoj8s/j7Hgten9A8CKBTANBgkqhkiG9w0BAQsFADBl -MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExHTAbBgNVBAsMFHJvb3RA -dmtpbGwtYXJjaGxpbnV4MSQwIgYDVQQDDBtta2NlcnQgcm9vdEB2a2lsbC1hcmNo -bGludXgwHhcNMTkwNzE1MTQ0MDA0WhcNMjkwNzE1MTQ0MDA0WjBlMR4wHAYDVQQK -ExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExHTAbBgNVBAsMFHJvb3RAdmtpbGwtYXJj -aGxpbnV4MSQwIgYDVQQDDBtta2NlcnQgcm9vdEB2a2lsbC1hcmNobGludXgwggGi -MA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCz/Ya3wSY9CAzL78eJ6bugV8UE -m9T/an0UDY+r9x8zSVsvz1rgqoxE1tFwc2KCdGoXe9qFc7M5HOuFN7sbr1CusgoR -bLO/zzmd/IUCkG6iLdo3dY6JcIFUQcerbSGLbqLQ54uixxsXG5l/5K/rS0SboxQQ -WXRt/+FLB3TZpSA9eNiI9WGUdtEsiZIu0H7UFjgIEer7ucFXFJPnYfc6zZcY25mk -raIJR6+e4DA8liTaC8MzLGgpvqlGr8z/5f5Fhi8LWGJbDZKvpCyWlsWWE7tgk7yj -8tTScFtjMHynT74YNUP2SaUvgDFFSf7hUyapSpkg9dtykELSO5HC8yK+XAXhiwuk -/lwh4y9CokiX2rldQvgiuvw3eSxGhGmfAOGbn2mhHI8t+xjHzXNrZgYH+PluFiZ2 -sC8Y0eY+OWdqU0+pMa+6/6fJbZVX1eCkKNNYyv+YJlbcmVEeFUwbBkx/K1lJIVwW -vpaEOQja8CkOImxQ68KaisNF/RHC+OFkhUMXfmMCAwEAAaNFMEMwDgYDVR0PAQH/ -BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJi9WA/iA5eh6Kwv -laxBsY3gH0FlMA0GCSqGSIb3DQEBCwUAA4IBgQAQajEfAgQHrjHCaVcFskq8p7sw -FRDMyWVBB7FdtXIwZELib2oqDh3dTOamCYbRzRy2GHYGRp2mqDpMIEeomL475pSl -/Kqk9vRZgNHoEzKChPnbYJpZXEqlvxQzmS5Pu4ijAcP/+DFxMo400WbpNB9YQeeP -x/aeOP4RqBdtBx+yXr9iHiaYH0ZKmvQiGOAGUhw1WPd1lvv5gmrXsAJ7/QGSAuWM -KHyYIx6pfO4fq3OFONrDWPBAEoW+ZvDVi0mBEhksBm5H6+APD3qfU6ZGI2kHGMR4 -oL5+K6Qd8W8rljrtYW0yk3OHZ5ZlP3XhXs3dBnrXRzsQN2FCMJ+tV+iqcLll0Gzq -9Fnx0qKT8NQS1FkP49W1Zqeoxof9iruXpQ1cMTEy/XvkNGw76MBubZZ1ZQwKlG8/ -3lTENUnr9nvwpwZpjjfut96KgpbcOnhM8q8dn60YWgARXa88uRVbw3IJ0T2A+RGu -KEYT0ZZQQMFUvobozBi3XdWM33FjHoMyCzth0DY= ------END CERTIFICATE----- diff --git a/apps/arangodb/.env b/apps/arangodb/.env index 015687015..4e44c2701 100644 --- a/apps/arangodb/.env +++ b/apps/arangodb/.env @@ -1,18 +1,48 @@ W9_REPO=arangodb -W9_VERSION='3.12' -W9_DIST='community' -W9_POWER_PASSWORD='lHo!yTwSjj89EnZ7' +W9_DIST=community +W9_VERSION=3.12 + +# Optional password seed: enabled because the package controls the root login. +W9_POWER_PASSWORD=lHo!yTwSjj89EnZ7 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='arangodb' -# DB port also is web port + +W9_ID=arangodb + +# Web/internal ports: ArangoDB exposes its HTTP API and admin console on the same port. W9_HTTP_PORT=8529 -W9_HTTP_PORT_SET='9001' +W9_HTTP_PORT_SET=9001 + +# Built-in login and URL helpers: keep these in the protected block because the appstore parser +# reads them from the app package metadata surface. W9_LOGIN_USER=root W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} -W9_URL='appname.example.com' +W9_URL=appname.example.com + W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### -# Official ENV +#### ----------------------------------------------------------------------------------------- #### + +#W9_NAME= +#W9_RCODE= + +# ============================================================ +# ArangoDB image environment variables +# Docs: https://hub.docker.com/_/arangodb +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: ARANGO_ROOT_PASSWORD=${W9_POWER_PASSWORD} + +# Not used by default; enable only when needed: +# ARANGO_NO_AUTH=0 +# ARANGO_STORAGE_ENGINE=rocksdb +# ARANGO_OVERRIDE_DETECTED_TOTAL_MEMORY= +# ARANGO_OVERRIDE_DETECTED_NUMBER_OF_CORES= +# ARANGO_RANDOM_ROOT_PASSWORD=0 diff --git a/apps/arangodb/CHANGELOG.md b/apps/arangodb/CHANGELOG.md index fbda4c2fb..14c7b60bb 100644 --- a/apps/arangodb/CHANGELOG.md +++ b/apps/arangodb/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-13 +- Verified the upstream stable line remains ArangoDB 3.12 and refreshed the package metadata for the current stable release notes. +- Updated the app package to the current `.env` layout and metadata rules, including credential and first-startup-only declarations. +- Added app-local test cases metadata required by the current validation workflow. + ## 2026-09-03 - Upgraded ArangoDB to the 3.12 line (float tag, tracking latest 3.12 patch). - Regenerated the README via the app generator. diff --git a/apps/arangodb/README.md b/apps/arangodb/README.md index 18372e86d..60e02560b 100644 --- a/apps/arangodb/README.md +++ b/apps/arangodb/README.md @@ -23,7 +23,7 @@ ## Configuration Reference -Websoft9 packages this app from the official [ArangoDB Docker image](https://hub.docker.com/r/arangodb/arangodb) and makes some improvements below. +Websoft9 packages this app from the official [ArangoDB Docker image](https://hub.docker.com/_/arangodb) and makes some improvements below. @@ -55,6 +55,9 @@ Data is kept inside the container; a named volume is recommended for persistence Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. +Note: `ARANGO_ROOT_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + ### Configuration Files @@ -65,11 +68,13 @@ Configuration files live inside the image; mount a single file read-only to over - [ArangoDB Administrator Guide](https://support.websoft9.com/docs/arangodb) by Websoft9 -- [Docker Hub image](https://hub.docker.com/r/arangodb/arangodb) +- [Docker Hub image](https://hub.docker.com/_/arangodb) - [Releases](https://github.com/arangodb/arangodb) -- [Official docs](https://hub.docker.com/r/arangodb/arangodb) +- [Official docs](https://docs.arangodb.com/stable/release-notes/) + +- [Official docs](https://hub.docker.com/_/arangodb) diff --git a/apps/arangodb/docker-compose.yml b/apps/arangodb/docker-compose.yml index 90ca23158..1b26db2c5 100644 --- a/apps/arangodb/docker-compose.yml +++ b/apps/arangodb/docker-compose.yml @@ -6,7 +6,7 @@ services: env_file: - .env ports: - - '${W9_HTTP_PORT_SET}:8529' #Admin Console + - '${W9_HTTP_PORT_SET}:8529' # Web Console and API environment: - ARANGO_ROOT_PASSWORD=${W9_POWER_PASSWORD} volumes: diff --git a/apps/arangodb/tests/cases.yml b/apps/arangodb/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/arangodb/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/arangodb/variables.json b/apps/arangodb/variables.json index 50f5f79a7..62d6cc72f 100644 --- a/apps/arangodb/variables.json +++ b/apps/arangodb/variables.json @@ -6,6 +6,7 @@ "image": "https://hub.docker.com/_/arangodb", "releases": "https://github.com/arangodb/arangodb", "docs": [ + "https://docs.arangodb.com/stable/release-notes/", "https://hub.docker.com/_/arangodb" ] }, @@ -29,5 +30,20 @@ "cpu": "1", "memory": "1", "disk": "1" + }, + "credentials": { + "username": { + "source": "inline", + "value": "root" + }, + "password": { + "source": "container-env", + "name": "W9_LOGIN_PASSWORD" + } + }, + "env": { + "first_startup_only": [ + "ARANGO_ROOT_PASSWORD" + ] } } diff --git a/apps/budibase/.env b/apps/budibase/.env index 3cfe6510d..f1b879f38 100644 --- a/apps/budibase/.env +++ b/apps/budibase/.env @@ -1,39 +1,64 @@ -W9_DIST='community' -W9_REPO=budibase.docker.scarf.sh/budibase/apps -W9_VERSION='3.13.28' -W9_POWER_PASSWORD='8d2sBiOLPhXuHef!' +W9_REPO=budibase/apps +W9_DIST=community +W9_VERSION=latest +W9_POWER_PASSWORD=8d2sBiOLPhXuHef! + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='budibase' + +W9_ID=budibase W9_HTTP_PORT=10000 -W9_HTTP_PORT_SET='9009' -W9_URL='appname.example.com' +W9_HTTP_PORT_SET=9009 +W9_DB_VERSION=16 +W9_DB_EXPOSE=postgresql +W9_URL=budibase.example.com W9_NETWORK=websoft9 + #### --------------------------------------------------------------------------------------- #### # Use the main port in the builder for your self hosting URL, e.g. localhost:10000 -MAIN_PORT=$W9_HTTP_PORT_SET +MAIN_PORT=${W9_HTTP_PORT_SET} + +# ============================================================ +# Budibase image environment variables +# Docs: https://docs.budibase.com/docs/docker-compose +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: # This section contains all secrets pertaining to the system # These should be updated API_ENCRYPTION_KEY=${W9_POWER_PASSWORD}6UF6GPsa3iu2tbP JWT_SECRET=${W9_POWER_PASSWORD}6UF6GPsa3iu2tbP -MINIO_ACCESS_KEY=$W9_POWER_PASSWORD -MINIO_SECRET_KEY=$W9_POWER_PASSWORD -COUCH_DB_PASSWORD=$W9_POWER_PASSWORD -COUCH_DB_USER=$W9_POWER_PASSWORD -REDIS_PASSWORD=$W9_POWER_PASSWORD -INTERNAL_API_KEY=$W9_POWER_PASSWORD +MINIO_ACCESS_KEY=${W9_POWER_PASSWORD} +MINIO_SECRET_KEY=${W9_POWER_PASSWORD} +COUCH_DB_PASSWORD=${W9_POWER_PASSWORD} +COUCH_DB_USER=${W9_POWER_PASSWORD} +REDIS_PASSWORD=${W9_POWER_PASSWORD} +REDIS_USERNAME= +INTERNAL_API_KEY=${W9_POWER_PASSWORD} +LITELLM_MASTER_KEY=${W9_POWER_PASSWORD} +LITELLM_SALT_KEY=${W9_POWER_PASSWORD}salt +LITELLM_DB_PASSWORD=${W9_POWER_PASSWORD} # This section contains variables that do not need to be altered under normal circumstances APP_PORT=4002 WORKER_PORT=4003 -MINIO_PORT=4004 -COUCH_DB_PORT=4005 +MINIO_PORT=9000 +COUCH_DB_PORT=5984 REDIS_PORT=6379 -WATCHTOWER_PORT=6161 +LITELLM_PORT=4000 +LITELLM_DB_NAME=litellm +LITELLM_DB_USER=llmproxy BUDIBASE_ENVIRONMENT=PRODUCTION SQL_MAX_ROWS= +PASSWORD_MIN_LENGTH=12 +PASSWORD_MAX_LENGTH=512 # An admin user can be automatically created initially if these are set BB_ADMIN_USER_EMAIL= @@ -41,4 +66,9 @@ BB_ADMIN_USER_PASSWORD= # A path that is watched for plugin bundles. Any bundles found are imported automatically/ PLUGINS_DIR= -ROLLING_LOG_MAX_SIZE= +OFFLINE_MODE= + +# Not used by default; enable only when needed: +# PASSWORD_REGEX= +# PASSWORD_REGEX_ERROR_MESSAGE= +# ROLLING_LOG_MAX_SIZE= diff --git a/apps/budibase/CHANGELOG.md b/apps/budibase/CHANGELOG.md index 582cf46c5..11d052c1f 100644 --- a/apps/budibase/CHANGELOG.md +++ b/apps/budibase/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Updated Budibase from `3.13.28` to the current official self-hosted `latest` image line. +- Aligned the compose stack with the current official self-hosted topology, including LiteLLM and its PostgreSQL dependency. +- Brought `.env`, `docker-compose.yml`, and metadata into current repository policy shape and added app-specific validation cases. diff --git a/apps/budibase/Notes.md b/apps/budibase/Notes.md deleted file mode 100644 index e9cc76844..000000000 --- a/apps/budibase/Notes.md +++ /dev/null @@ -1,92 +0,0 @@ -# Budibase - -* docs: https://docs.budibase.com/docs/docker-compose -* repo: https://github.com/Budibase/budibase/tree/develop/hosting - -## FAQ - -#### watchtower-service 的作用? - -它是一个更新代理,通过 API 以驱动更新。当前的设置下,它不会主动更新其他容器 - -## quickstart - -## 使用 Budibase 构建webApp -Budibase 是一个开源的low code平台,支持数据建模,页面设计和流程自动化,下面以数据的CURD为例,做最佳实践 - -![image](https://user-images.githubusercontent.com/62225175/159839764-d70552c2-fcc4-44d2-872d-4e4f7e0fa8b6.png) - - -### 安装 Budibase - -> 2核4G 香港服务器,基本够用 - -#### 使用 Docker 私有部署 ,[参考官方](https://account.budibase.app/portal/install) - -To get started, you must have docker and docker compose installed on your machine. -Once you have Docker installed, the process takes 5 minutes, with these four steps: - -1. Install the Budibase CLI: - -npm i -g @budibase/cli - -2. Setup Budibase (select where to store Budibase, and the port to run it on): - -budi hosting --init - -3. Run Budibase: - -budi hosting --start - -4. Create your admin user by entering the email and password for the new admin user. - - -### 使用 Budibase 构建应用 - -1. 基于模板构建应用 -![image](https://user-images.githubusercontent.com/62225175/159836833-cdb300bf-39a4-40b3-bf07-13afea26fb1d.png) - -2. 建模,创建数据表,并添加数据 - -![image](https://user-images.githubusercontent.com/62225175/159836968-f54ebeb6-4f88-456f-b8b1-48738c20cb68.png) - -3. 数据展示:新建页面 - 设置路由 - 在页面添加数据提供器 - 在页面添加表 - -![image](https://user-images.githubusercontent.com/62225175/159837232-111fed45-1a09-4d81-af19-bd2403f478c7.png) - -![image](https://user-images.githubusercontent.com/62225175/159837380-a66fecf3-2b21-4638-ae1c-3e7b53b7d947.png) - -数据查看详情设置:在表中添加【link】 设置链接,并传递参数,提前设置好带参的预览页面 - -![image](https://user-images.githubusercontent.com/62225175/159840085-89c191dc-e88a-4ab7-968d-2aeff6bcb2ff.png) - -4 . 数据修改:数据传参与呈现 - -- 根据传递参数,获取数据 -![image](https://user-images.githubusercontent.com/62225175/159838727-7aebc53d-1cd9-4d1e-9ee4-cbcac437d35c.png) - -- 将数据绑定到表单 Form, 设置 type 为 update -![image](https://user-images.githubusercontent.com/62225175/159838917-a572f3e0-f9ba-4cda-b111-8bac48747fa7.png) - -- 将单项数据 绑定到 控件 呈现 -![image](https://user-images.githubusercontent.com/62225175/159839012-56aa31a2-48f5-4805-be38-f2e258fde9b5.png) - -5. 数据添加:基于页面,构建表单 - -- 新建页面,添加 Form 和 控件 -![image](https://user-images.githubusercontent.com/62225175/159839206-308a37a7-3bc7-44f6-9815-2a9b503fdd1d.png) - -- 在 Form 表单中添加 Elements - Button -![image](https://user-images.githubusercontent.com/62225175/159839288-dafed893-8abb-4c5c-88fe-8dd63c2d5c42.png) - -- 设置 提交按钮 单击 事件处理程序:1、将Form数据作为数据源添加一行到数据表; 2、添加完数据,跳转到呈现页面 -![image](https://user-images.githubusercontent.com/62225175/159839444-4c714df8-141e-4815-9dc7-3f3582a29f8e.png) - -![image](https://user-images.githubusercontent.com/62225175/159839627-6dca40fc-e1be-4af3-a729-71b364885ee2.png) - -6. 做完每个操作,可以发布或预览 -![image](https://user-images.githubusercontent.com/62225175/159839714-c691df28-4de3-476a-8628-6276cacaeb46.png) - - - - diff --git a/apps/budibase/README.md b/apps/budibase/README.md index 9c2900b0d..56646338c 100644 --- a/apps/budibase/README.md +++ b/apps/budibase/README.md @@ -1,26 +1,96 @@ -# Budibase on Docker +# Budibase on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Budibase: +## Quick Start +### Deploy Verification - - community: 3.12.13, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Budibase**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Budibase admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://github.com/Budibase/budibase/tree/develop/hosting): +### Change Password -* **RAM**: 8 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Budibase by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Budibase Docker image](https://hub.docker.com/r/budibase/proxy) and makes some improvements below. -If you want use Budibase with **Websoft9 Business Support** free, you can [subscribe Budibase](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Budibase Administrator Guide](https://support.websoft9.com/docs/budibase) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 10000 | + + +### Data Directory + + +- `plugins` → `/plugins` +- `minio_data` → `/data` +- `couchdb3_data` → `/data` +- `redis_data` → `/data` +- `litellm_data` → `/var/lib/postgresql/data` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +Note: `BB_ADMIN_USER_EMAIL`, `BB_ADMIN_USER_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/litellm_config.yaml` to `/app/config.yaml`. + + +## References + +- [Budibase Administrator Guide](https://support.websoft9.com/docs/budibase) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/budibase/proxy) + +- [Releases](https://github.com/Budibase/budibase/releases) + +- [Official compose](https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml) + +- [Official env example](https://raw.githubusercontent.com/Budibase/budibase/master/hosting/.env) + +- [Official docs](https://docs.budibase.com/docs/docker-compose) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/budibase/docker-compose.yml b/apps/budibase/docker-compose.yml index f00ea79d5..c2839ea33 100644 --- a/apps/budibase/docker-compose.yml +++ b/apps/budibase/docker-compose.yml @@ -1,18 +1,12 @@ - -# docs: https://docs.budibase.com/docs/docker-compose -# compose: https://github.com/Budibase/budibase/blob/master/hosting/docker-compose.yaml - -# Websoft9 modifications: add container_name, add plugins volume, add network, add env_file: .env for proxy-service - -version: "3.8" services: app-service: restart: unless-stopped - image: budibase.docker.scarf.sh/budibase/apps - container_name: $W9_ID-bbapps + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID}-bbapps + env_file: .env environment: SELF_HOSTED: 1 - COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@couchdb-service:5984 + COUCH_DB_URL: http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@${W9_ID}-couchdb:5984 WORKER_URL: http://worker-service:4003 MINIO_URL: http://minio-service:9000 MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY} @@ -26,20 +20,27 @@ services: ENABLE_ANALYTICS: "true" REDIS_URL: redis-service:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} + REDIS_USERNAME: ${REDIS_USERNAME} + LITELLM_URL: http://litellm-service:4000 + LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} BB_ADMIN_USER_EMAIL: ${BB_ADMIN_USER_EMAIL} BB_ADMIN_USER_PASSWORD: ${BB_ADMIN_USER_PASSWORD} + PASSWORD_MIN_LENGTH: ${PASSWORD_MIN_LENGTH} + PASSWORD_MAX_LENGTH: ${PASSWORD_MAX_LENGTH} PLUGINS_DIR: ${PLUGINS_DIR} OFFLINE_MODE: ${OFFLINE_MODE} depends_on: - worker-service - redis-service + - litellm-service volumes: - plugins:/plugins worker-service: restart: unless-stopped - image: budibase.docker.scarf.sh/budibase/worker - container_name: $W9_ID-bbworker + image: budibase/worker:${W9_VERSION} + container_name: ${W9_ID}-bbworker + env_file: .env environment: SELF_HOSTED: 1 PORT: 4003 @@ -56,15 +57,21 @@ services: INTERNAL_API_KEY: ${INTERNAL_API_KEY} REDIS_URL: redis-service:6379 REDIS_PASSWORD: ${REDIS_PASSWORD} + REDIS_USERNAME: ${REDIS_USERNAME} + LITELLM_URL: http://litellm-service:4000 + LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} OFFLINE_MODE: ${OFFLINE_MODE} + PASSWORD_MIN_LENGTH: ${PASSWORD_MIN_LENGTH} + PASSWORD_MAX_LENGTH: ${PASSWORD_MAX_LENGTH} depends_on: - redis-service - minio-service + - litellm-service minio-service: restart: unless-stopped - container_name: $W9_ID-minio - image: minio/minio + container_name: ${W9_ID}-minio + image: budibase/minio:final volumes: - minio_data:/data environment: @@ -81,18 +88,17 @@ services: proxy-service: restart: unless-stopped ports: - - "${MAIN_PORT}:10000" - container_name: $W9_ID - image: budibase/proxy + - "${MAIN_PORT}:10000" # Web Console + container_name: ${W9_ID} + image: budibase/proxy:${W9_VERSION} env_file: .env environment: - PROXY_RATE_LIMIT_WEBHOOKS_PER_SECOND=10 - - PROXY_RATE_LIMIT_API_PER_SECOND=20 + - PROXY_RATE_LIMIT_API_PER_SECOND=50 - APPS_UPSTREAM_URL=http://app-service:4002 - WORKER_UPSTREAM_URL=http://worker-service:4003 - MINIO_UPSTREAM_URL=http://minio-service:9000 - COUCHDB_UPSTREAM_URL=http://couchdb-service:5984 - - WATCHTOWER_UPSTREAM_URL=http://watchtower-service:8080 - RESOLVER=127.0.0.11 depends_on: - minio-service @@ -102,37 +108,64 @@ services: couchdb-service: restart: unless-stopped - container_name: $W9_ID-couchdb - image: budibase/couchdb - pull_policy: always + container_name: ${W9_ID}-couchdb + image: budibase/database:2.1.0 + env_file: .env environment: - COUCHDB_PASSWORD=${COUCH_DB_PASSWORD} - COUCHDB_USER=${COUCH_DB_USER} - TARGETBUILD=docker-compose + - DATA_DIR=/data volumes: - - couchdb3_data:/opt/couchdb/data + - couchdb3_data:/data redis-service: restart: unless-stopped image: redis - container_name: $W9_ID-redis + container_name: ${W9_ID}-redis command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data - watchtower-service: - restart: always - container_name: $W9_ID-watchtower - image: containrrr/watchtower + litellm-service: + restart: unless-stopped + image: docker.io/litellm/litellm:main-v1.83.10-stable.patch.3 + container_name: ${W9_ID}-litellm + env_file: .env volumes: - - /var/run/docker.sock:/var/run/docker.sock - command: --debug --http-api-update bbapps bbworker bbproxy + - ./src/litellm_config.yaml:/app/config.yaml + environment: + DATABASE_URL: postgresql://${LITELLM_DB_USER}:${LITELLM_DB_PASSWORD}@litellm-db:5432/${LITELLM_DB_NAME} + STORE_MODEL_IN_DB: "True" + LITELLM_REASONING_AUTO_SUMMARY: "true" + LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY} + LITELLM_SALT_KEY: ${LITELLM_SALT_KEY} + command: ["--config", "/app/config.yaml"] + depends_on: + - litellm-db + healthcheck: + test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')\" || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + litellm-db: + restart: unless-stopped + image: postgres:${W9_DB_VERSION} + container_name: ${W9_ID}-litellm-db + env_file: .env environment: - - WATCHTOWER_HTTP_API=true - - WATCHTOWER_HTTP_API_TOKEN=budibase - - WATCHTOWER_CLEANUP=true - labels: - - "com.centurylinklabs.watchtower.enable=false" + POSTGRES_DB: ${LITELLM_DB_NAME} + POSTGRES_USER: ${LITELLM_DB_USER} + POSTGRES_PASSWORD: ${LITELLM_DB_PASSWORD} + volumes: + - litellm_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -d ${LITELLM_DB_NAME} -U ${LITELLM_DB_USER}"] + interval: 1s + timeout: 5s + retries: 10 volumes: couchdb3_data: @@ -143,8 +176,10 @@ volumes: driver: local plugins: driver: local + litellm_data: + driver: local networks: default: name: ${W9_NETWORK} - external: true \ No newline at end of file + external: true diff --git a/apps/budibase/src/litellm_config.yaml b/apps/budibase/src/litellm_config.yaml new file mode 100644 index 000000000..a9c6842c6 --- /dev/null +++ b/apps/budibase/src/litellm_config.yaml @@ -0,0 +1 @@ +model_list: [] diff --git a/apps/budibase/tests/cases.yml b/apps/budibase/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/budibase/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/budibase/variables.json b/apps/budibase/variables.json index 0b9430c8e..ed680e9a0 100644 --- a/apps/budibase/variables.json +++ b/apps/budibase/variables.json @@ -2,11 +2,21 @@ "name": "budibase", "trademark": "Budibase", "release": true, + "upstream": { + "image": "https://hub.docker.com/r/budibase/proxy", + "releases": "https://github.com/Budibase/budibase/releases", + "compose": { + "compose": "https://raw.githubusercontent.com/Budibase/budibase/master/hosting/docker-compose.yaml", + "env": "https://raw.githubusercontent.com/Budibase/budibase/master/hosting/.env" + }, + "docs": [ + "https://docs.budibase.com/docs/docker-compose" + ] + }, "edition": [ { "dist": "community", "version": [ - "3.13.28", "latest" ] } @@ -23,7 +33,10 @@ "memory": "8", "disk": "1" }, - "upstream": { - "image": "https://hub.docker.com/r/budibase/proxy" + "env": { + "first_startup_only": [ + "BB_ADMIN_USER_EMAIL", + "BB_ADMIN_USER_PASSWORD" + ] } } diff --git a/apps/caddy/.env b/apps/caddy/.env index 685ac87c4..02bb51ab0 100644 --- a/apps/caddy/.env +++ b/apps/caddy/.env @@ -1,11 +1,39 @@ -W9_DIST='community' W9_REPO=caddy -W9_VERSION='2.10' +W9_DIST=community +W9_VERSION=2.11 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='caddy' -W9_HTTP_PORT_SET='9001' + +W9_ID=caddy + W9_HTTP_PORT=80 -W9_URL='appname.example.com' +W9_HTTP_PORT_SET=9001 + +W9_URL=appname.example.com + W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### + +#### ----------------------------------------------------------------------------------------- #### + +#W9_NAME="" +#W9_RCODE="" + +# ============================================================ +# Caddy image environment variables +# Docs: https://hub.docker.com/_/caddy +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# XDG_CONFIG_HOME= +# XDG_DATA_HOME= +# CADDY_ADMIN= +# CADDY_EMAIL= +# CADDY_GLOBAL_OPTIONS= diff --git a/apps/caddy/CHANGELOG.md b/apps/caddy/CHANGELOG.md index 582cf46c5..bd2922acb 100644 --- a/apps/caddy/CHANGELOG.md +++ b/apps/caddy/CHANGELOG.md @@ -1,5 +1,6 @@ # CHANGELOG -## Release -### Fixes and Enhancements - +## 2026-10-13 +- Updated Caddy from `2.10` to `2.11` based on the latest stable upstream release line. +- Aligned `.env` and `docker-compose.yml` with current repository policy requirements. +- Added app-specific validation coverage for the Caddy root path. diff --git a/apps/caddy/README.md b/apps/caddy/README.md index 5aea07fb4..837871145 100644 --- a/apps/caddy/README.md +++ b/apps/caddy/README.md @@ -1,26 +1,90 @@ -# Caddy on Docker +# Caddy on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Caddy: +## Quick Start +### Deploy Verification - - community: 2.10, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Caddy**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Caddy admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://hub.docker.com/_/caddy): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 2 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Caddy by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Caddy Docker image](https://hub.docker.com/_/caddy) and makes some improvements below. -If you want use Caddy with **Websoft9 Business Support** free, you can [subscribe Caddy](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Caddy Administrator Guide](https://support.websoft9.com/docs/caddy) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 2.11, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 80 | + + +### Data Directory + + +- `data` → `/data` +- `config` → `/config` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +- `./src/Caddyfile` → `/etc/caddy/Caddyfile` +- `./src/cmd.sh` → `/usr/local/bin/cmd.sh` + + + +## References + +- [Caddy Administrator Guide](https://support.websoft9.com/docs/caddy) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/caddy) + +- [Releases](https://github.com/caddyserver/caddy/releases) + +- [GitHub docs](https://github.com/caddyserver/caddy/releases/tag/v2.11.7) + +- [Official docs](https://hub.docker.com/_/caddy) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/caddy/docker-compose.yml b/apps/caddy/docker-compose.yml index 554118c3f..ad5088912 100644 --- a/apps/caddy/docker-compose.yml +++ b/apps/caddy/docker-compose.yml @@ -1,18 +1,13 @@ -# image: https://hub.docker.com/_/caddy -# docs: https://github.com/caddyserver/caddy-docker - -version: '3.8' - services: caddy: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} env_file: - .env restart: unless-stopped working_dir: /srv ports: - - "$W9_HTTP_PORT_SET:80" + - "${W9_HTTP_PORT_SET}:80" # Web Console volumes: - site:/srv # Add your html site - ./src/Caddyfile:/etc/caddy/Caddyfile @@ -29,4 +24,4 @@ networks: volumes: data: config: - site: \ No newline at end of file + site: diff --git a/apps/caddy/tests/cases.yml b/apps/caddy/tests/cases.yml new file mode 100644 index 000000000..50a4a6316 --- /dev/null +++ b/apps/caddy/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: root-page + type: web-access + path: / + expect_status: 200 diff --git a/apps/caddy/variables.json b/apps/caddy/variables.json index 8c19016a9..9124cf630 100644 --- a/apps/caddy/variables.json +++ b/apps/caddy/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "2.10", + "2.11", "latest" ] } @@ -17,7 +17,12 @@ "disk": "2" }, "upstream": { - "image": "https://hub.docker.com/_/caddy" + "image": "https://hub.docker.com/_/caddy", + "releases": "https://github.com/caddyserver/caddy/releases", + "docs": [ + "https://github.com/caddyserver/caddy/releases/tag/v2.11.7", + "https://hub.docker.com/_/caddy" + ] }, "access": { "defaultScheme": "http", diff --git a/apps/canvas/CHANGELOG.md b/apps/canvas/CHANGELOG.md index 9bf7185ec..71bbdcd50 100644 --- a/apps/canvas/CHANGELOG.md +++ b/apps/canvas/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-13 +- Verified `release/2026-05-20.143` is still the newest stable upstream Canvas tag available for this package. +- Added `tests/cases.yml` so deploy validation checks the Canvas login entry path instead of relying only on default root reachability. +- Disabled Git auto-maintenance during the image build to avoid Bundler git dependency clone failures on `maintenance.lock`. + ## 2026-08-31 - Created the initial Canvas app package. - Added a custom source-based Canvas image build using the official upstream Dockerfile pattern. diff --git a/apps/canvas/Dockerfile b/apps/canvas/Dockerfile index bb5b69983..d75f7a262 100644 --- a/apps/canvas/Dockerfile +++ b/apps/canvas/Dockerfile @@ -78,6 +78,8 @@ RUN mkdir -p /home/docker/.gem/ruby/${RUBY}.0 \ && chown -R docker:docker /home/docker ${APP_HOME} USER docker +RUN git config --global maintenance.auto false \ + && git config --global gc.auto 0 RUN unset RUBY \ && bundle config --global build.nokogiri --use-system-libraries \ && bundle config --global build.ffi --enable-system-libffi \ diff --git a/apps/canvas/tests/cases.yml b/apps/canvas/tests/cases.yml new file mode 100644 index 000000000..98180fd23 --- /dev/null +++ b/apps/canvas/tests/cases.yml @@ -0,0 +1,9 @@ +skip: + - id: web-access + reason: validate the Canvas login entry path instead of the redirecting root path. + +optional: + - id: login-page + type: web-access + path: /login/canvas + expect_status: 200 diff --git a/apps/chatwoot/.env b/apps/chatwoot/.env index 4cee93e86..2757229e7 100644 --- a/apps/chatwoot/.env +++ b/apps/chatwoot/.env @@ -1,29 +1,43 @@ W9_REPO=chatwoot/chatwoot -W9_DIST='community' -W9_VERSION='v4.8.0' +W9_DIST=community +W9_VERSION=v4.18.0 W9_POWER_PASSWORD='r!1lw!J4dGLXFYzy' #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='chatwoot' +W9_ID=chatwoot W9_HTTP_PORT=3000 -W9_HTTP_PORT_SET='9007' +W9_HTTP_PORT_SET=9007 -W9_DB_EXPOSE="postgresql" -W9_DB_VERSION="12" -W9_URL='example.youdomain.com' +W9_DB_EXPOSE=postgresql +W9_DB_VERSION=16 +W9_URL=chatwoot.example.com W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### +# ============================================================ +# Chatwoot image environment variables +# Docs: https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ -# Below environment is created by chatwoot: https://github.com/chatwoot/chatwoot/blob/develop/.env.example +# Used by docker-compose.yml: -REDIS_URL=redis://$W9_ID-redis:6379 -POSTGRES_HOST=$W9_ID-postgresql +REDIS_URL=redis://${W9_ID}-redis:6379 +POSTGRES_HOST=${W9_ID}-postgresql POSTGRES_USERNAME=postgres -POSTGRES_PASSWORD=$W9_POWER_PASSWORD +POSTGRES_PASSWORD=${W9_POWER_PASSWORD} POSTGRES_DATABASE=chatwoot # Used to verify the integrity of signed cookies. so ensure a secure value is set otherwise application can not start -SECRET_KEY_BASE=MxExC45Ls-783tsrs-$W9_POWER_PASSWORD +SECRET_KEY_BASE=MxExC45Ls-783tsrs-${W9_POWER_PASSWORD} + +# Not used by default; enable only when needed: +# FRONTEND_URL=http://${W9_URL} +# RAILS_LOG_TO_STDOUT=true +# ENABLE_ACCOUNT_SIGNUP=false +# SMTP_ADDRESS= +# MAILER_SENDER_EMAIL= diff --git a/apps/chatwoot/CHANGELOG.md b/apps/chatwoot/CHANGELOG.md index 582cf46c5..6afe5d380 100644 --- a/apps/chatwoot/CHANGELOG.md +++ b/apps/chatwoot/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG -## Release -### Fixes and Enhancements - +## 2026-10-13 +- Upgraded Chatwoot from `v4.8.0` to `v4.18.0` based on the latest stable upstream release and image tag. +- Aligned `.env` and `docker-compose.yml` with current repository policy by converting all variable references to `${VAR}` form and removing upstream source comments from the compose file. +- Removed the packaged long-running migrate service and made the main app container run the upstream-required `rails db:chatwoot_prepare` step before starting Puma so first deploy and upgrades stay self-consistent. +- Added a main-container healthcheck and an app-specific API readiness check at `/api`. +- Refreshed `variables.json`, added app help text for first-run administrator creation, and regenerated the package README. diff --git a/apps/chatwoot/README.md b/apps/chatwoot/README.md index bb21dce34..1b8b840e1 100644 --- a/apps/chatwoot/README.md +++ b/apps/chatwoot/README.md @@ -1,26 +1,89 @@ -# Chatwoot on Docker +# Chatwoot on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Chatwoot: +## Quick Start +### Deploy Verification - - community: v4.2.0-ce, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Chatwoot**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Chatwoot admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.chatwoot.com/docs/self-hosted/deployment/requirements): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Chatwoot by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Chatwoot Docker image](https://hub.docker.com/r/chatwoot/chatwoot) and makes some improvements below. -If you want use Chatwoot with **Websoft9 Business Support** free, you can [subscribe Chatwoot](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Chatwoot Administrator Guide](https://support.websoft9.com/docs/chatwoot) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v4.18.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 3000 | + + +### Data Directory + + +- `chatwoot` → `/app/storage` +- `postgres` → `/var/lib/postgresql/data` +- `/data/redis` → `/data` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Chatwoot Administrator Guide](https://support.websoft9.com/docs/chatwoot) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/chatwoot/chatwoot) + +- [Releases](https://github.com/chatwoot/chatwoot/releases) + +- [Official docs](https://www.chatwoot.com/docs/self-hosted/deployment/docker) + +- [Official docs](https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/chatwoot/docker-compose.yml b/apps/chatwoot/docker-compose.yml index e5aa12c1f..eb7b61e45 100644 --- a/apps/chatwoot/docker-compose.yml +++ b/apps/chatwoot/docker-compose.yml @@ -1,14 +1,7 @@ -# docs: https://www.chatwoot.com/docs/self-hosted/deployment/docker -# compose: https://github.com/chatwoot/chatwoot/blob/develop/docker-compose.production.yaml -# chatwoot base container is not need, it only for build - -version: '3.8' - services: - rails: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} restart: unless-stopped env_file: .env volumes: @@ -17,32 +10,28 @@ services: - postgres - redis ports: - - $W9_HTTP_PORT_SET:3000 - environment: - - NODE_ENV=production - - RAILS_ENV=production - - INSTALLATION_ENV=docker - entrypoint: docker/entrypoints/rails.sh - command: ['bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0'] - - migrate: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID-migrate - env_file: .env - volumes: - - chatwoot:/app/storage - depends_on: - - rails + - "${W9_HTTP_PORT_SET}:3000" # Web Console environment: - NODE_ENV=production - RAILS_ENV=production - INSTALLATION_ENV=docker + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:3000/api || exit 1"] + interval: 15s + timeout: 10s + retries: 20 + start_period: 120s entrypoint: docker/entrypoints/rails.sh - command: bundle exec rails db:chatwoot_prepare + command: + [ + 'sh', + '-lc', + 'bundle exec rails db:chatwoot_prepare && exec bundle exec rails s -p 3000 -b 0.0.0.0' + ] sidekiq: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID-sidekiq + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID}-sidekiq restart: unless-stopped env_file: .env volumes: @@ -58,7 +47,7 @@ services: postgres: image: pgvector/pgvector:pg16 - container_name: $W9_ID-postgresql + container_name: ${W9_ID}-postgresql restart: unless-stopped volumes: - postgres:/var/lib/postgresql/data @@ -66,11 +55,11 @@ services: - POSTGRES_DB=chatwoot - POSTGRES_USER=postgres # Please provide your own password. - - POSTGRES_PASSWORD=$W9_POWER_PASSWORD + - POSTGRES_PASSWORD=${W9_POWER_PASSWORD} redis: image: redis:alpine - container_name: $W9_ID-redis + container_name: ${W9_ID}-redis restart: unless-stopped command: ["sh", "-c", "redis-server"] volumes: @@ -83,5 +72,5 @@ volumes: networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/chatwoot/tests/cases.yml b/apps/chatwoot/tests/cases.yml new file mode 100644 index 000000000..f3adcefb8 --- /dev/null +++ b/apps/chatwoot/tests/cases.yml @@ -0,0 +1,8 @@ +# The adaptive checks cover compose config, container state, the packaged +# healthcheck, and the web root. Chatwoot's API endpoint is exercised +# explicitly because the upstream docs use it as the basic post-install check. +optional: + - id: api-reachability + type: web-access + path: /api + expect_status: 200 diff --git a/apps/chatwoot/variables.json b/apps/chatwoot/variables.json index 9ba3e9f7f..328e0e889 100644 --- a/apps/chatwoot/variables.json +++ b/apps/chatwoot/variables.json @@ -3,13 +3,18 @@ "trademark": "Chatwoot", "release": true, "upstream": { - "image": "https://hub.docker.com/r/chatwoot/chatwoot" + "image": "https://hub.docker.com/r/chatwoot/chatwoot", + "releases": "https://github.com/chatwoot/chatwoot/releases", + "docs": [ + "https://www.chatwoot.com/docs/self-hosted/deployment/docker", + "https://www.chatwoot.com/docs/self-hosted/configuration/environment-variables" + ] }, "edition": [ { "dist": "community", "version": [ - "v4.8.0", + "v4.18.0", "latest" ] } @@ -25,5 +30,10 @@ "cpu": "2", "memory": "4", "disk": "1" + }, + "credentials": {}, + "help": { + "login": "First run: open the site and create the administrator account in the Chatwoot setup flow, then sign in with those credentials.", + "db": "After each image upgrade, run `docker compose run --rm rails bundle exec rails db:chatwoot_prepare` before or immediately after restarting the stack so Chatwoot applies the required database migrations." } } diff --git a/apps/chroma/Notes.md b/apps/chroma/Notes.md deleted file mode 100644 index 976e22d1c..000000000 --- a/apps/chroma/Notes.md +++ /dev/null @@ -1,49 +0,0 @@ -## RUN CHROMA -Chroma runs as a server and provides Python and JavaScript/TypeScript client SDKs - -Python: -``` -pip install chromadb-client -``` -``` -import chromadb -client = chromadb.HttpClient(host='localhost', port=9065) -collection = client.create_collection("sample2_collection") -# Add docs to the collection. Can also update and delete. Row-based API coming soon! -collection.add( - documents=["This is document1", "This is document2"], # we embed for you, or bring your own - metadatas=[{"source": "notion"}, {"source": "google-docs"}], # filter on arbitrary metadata! - ids=["doc1", "doc2"], # must be unique for each doc -) -results = collection.query( - query_texts=["This is a query document"], - n_results=2, - # where={"metadata_field": "is_equal_to_this"}, # optional filter - # where_document={"$contains":"search_string"} # optional filter -) -print(results) -``` - -JavaScript: -``` -npm install chromadb-client -``` -``` -import { ChromaClient } from 'chromadb' - async function chromaExample() { - const client = new ChromaClient(); - const collection = await client.createCollection({name: "sample_collection"}); - await collection.add({ - documents: ["This is a document", "This is another document"], // we embed for you, or bring your own - metadatas: [{ source: "my_source" }, { source: "my_source" }], // filter on arbitrary metadata! - ids: ["id1", "id2"] // must be unique for each doc - }); - const results = await collection.query({ - queryTexts: ["This is a query document"], - nResults: 2, - // where: {"metadata_field": "is_equal_to_this"}, // optional filter - // whereDocument: {"$contains":"search_string"} // optional filter - }); - } - chromaExample(); -``` \ No newline at end of file diff --git a/apps/ckan/.env b/apps/ckan/.env index 466b74a1a..296f3499c 100644 --- a/apps/ckan/.env +++ b/apps/ckan/.env @@ -1,77 +1,85 @@ -# ckan env from: https://github.com/ckan/ckan-docker/blob/master/.env.example -# Websoft9-specific variables +# Canonical semantics live in docs/w9-env-spec.md. +# This app follows the layout contract from metadata/templates/new-app/.env.tmpl. + W9_REPO=ckan/ckan-base W9_DIST=community -W9_VERSION=2.11.0 +W9_VERSION=2.12.0 W9_POWER_PASSWORD=urtghkikljee9uy -W9_ID=ckan -# Port Configurations +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=ckan W9_HTTP_PORT=5000 W9_HTTP_PORT_SET=5000 -W9_NETWORK=websoft9 +W9_DB_VERSION=16 +W9_DB_EXPOSE=postgresql +W9_LOGIN_USER=ckan_admin +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} W9_URL=example.youdomain.com +W9_URL_REPLACE=true +W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Ckan image environment variables +# Docs: https://github.com/ckan/ckan-docker/blob/master/.env.example +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ -# CKAN databases +# Used by docker-compose.yml: POSTGRES_USER=postgres -POSTGRES_PASSWORD=$W9_POWER_PASSWORD +POSTGRES_PASSWORD=${W9_POWER_PASSWORD} POSTGRES_DB=postgres POSTGRES_HOST=db -CKAN_DB_USER=ckandbuser -CKAN_DB_PASSWORD=$W9_POWER_PASSWORD -CKAN_DB=ckandb -DATASTORE_READONLY_USER=datastore_ro -DATASTORE_READONLY_PASSWORD=$W9_POWER_PASSWORD -DATASTORE_DB=datastore -CKAN_SQLALCHEMY_URL=postgresql://ckandbuser:$W9_POWER_PASSWORD@db/ckandb -CKAN_DATASTORE_WRITE_URL=postgresql://ckandbuser:$W9_POWER_PASSWORD@db/datastore -CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:$W9_POWER_PASSWORD@db/datastore - -# Test database connections -TEST_CKAN_SQLALCHEMY_URL=postgres://ckan:ckan@db/ckan_test -TEST_CKAN_DATASTORE_WRITE_URL=postgresql://ckan:ckan@db/datastore_test -TEST_CKAN_DATASTORE_READ_URL=postgresql://datastore_ro:datastore@db/datastore_test - -# Dev settings +CKAN_POSTGRES_DB=ckandb +CKAN_POSTGRES_USER=ckan_default +CKAN_POSTGRES_USER_PWD=${W9_POWER_PASSWORD} +CKAN_DATASTORE_POSTGRES_DB=datastore +CKAN_DATASTORE_POSTGRES_READ_USER=datastore_read +CKAN_DATASTORE_POSTGRES_READ_PWD=${W9_POWER_PASSWORD} +CKAN_DATASTORE_POSTGRES_WRITE_USER=datastore_write +CKAN_DATASTORE_POSTGRES_WRITE_PWD=${W9_POWER_PASSWORD} +CKAN_SQLALCHEMY_URL=postgresql://ckan_default:${W9_POWER_PASSWORD}@db/ckandb +CKAN_DATASTORE_WRITE_URL=postgresql://datastore_write:${W9_POWER_PASSWORD}@db/datastore +CKAN_DATASTORE_READ_URL=postgresql://datastore_read:${W9_POWER_PASSWORD}@db/datastore +TEST_CKAN_SQLALCHEMY_URL=postgresql://ckan_default:${W9_POWER_PASSWORD}@db/ckan_test +TEST_CKAN_DATASTORE_WRITE_URL=postgresql://datastore_write:${W9_POWER_PASSWORD}@db/datastore_test +TEST_CKAN_DATASTORE_READ_URL=postgresql://datastore_read:${W9_POWER_PASSWORD}@db/datastore_test USE_HTTPS_FOR_DEV=false - -# CKAN core CKAN_SITE_ID=default -CKAN_SITE_URL=http://$W9_URL +CKAN_SITE_URL=http://${W9_URL} CKAN___BEAKER__SESSION__SECRET=CHANGE_ME -# See https://docs.ckan.org/en/latest/maintaining/configuration.html#api-token-settings CKAN___API_TOKEN__JWT__ENCODE__SECRET=string:CHANGE_ME CKAN___API_TOKEN__JWT__DECODE__SECRET=string:CHANGE_ME CKAN_SYSADMIN_NAME=ckan_admin -CKAN_SYSADMIN_PASSWORD=$W9_POWER_PASSWORD +CKAN_SYSADMIN_PASSWORD=${W9_POWER_PASSWORD} CKAN_SYSADMIN_EMAIL=your_email@example.com CKAN_STORAGE_PATH=/var/lib/ckan CKAN_SMTP_SERVER=smtp.corporateict.domain:25 CKAN_SMTP_STARTTLS=True CKAN_SMTP_USER=user -CKAN_SMTP_PASSWORD=$W9_POWER_PASSWORD +CKAN_SMTP_PASSWORD=${W9_POWER_PASSWORD} CKAN_SMTP_MAIL_FROM=ckan@localhost CKAN_MAX_UPLOAD_SIZE_MB=100 TZ=UTC - -# Solr -SOLR_IMAGE_VERSION=2.10-solr9 -CKAN_SOLR_URL=http://$W9_ID-solr:8983/solr/ckan -TEST_CKAN_SOLR_URL=http://$W9_ID-solr:8983/solr/ckan - -# Redis +SOLR_IMAGE_VERSION=2.12-solr9 +CKAN_SOLR_URL=http://${W9_ID}-solr:8983/solr/ckan +TEST_CKAN_SOLR_URL=http://${W9_ID}-solr:8983/solr/ckan REDIS_VERSION=6 -CKAN_REDIS_URL=redis://$W9_ID-redis:6379/1 -TEST_CKAN_REDIS_URL=redis://$W9_ID-redis:6379/1 - -# Datapusher +CKAN_REDIS_URL=redis://${W9_ID}-redis:6379/1 +TEST_CKAN_REDIS_URL=redis://${W9_ID}-redis:6379/1 DATAPUSHER_VERSION=0.0.21 -CKAN_DATAPUSHER_URL=http://$W9_ID-datapusher:8800 -CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://$W9_ID:5000 - -# Extensions +CKAN_DATAPUSHER_URL=http://${W9_ID}-datapusher:8800 +CKAN__DATAPUSHER__CALLBACK_URL_BASE=http://${W9_ID}:5000 CKAN__PLUGINS="image_view text_view datatables_view datastore datapusher envvars" CKAN__HARVEST__MQ__TYPE=redis CKAN__HARVEST__MQ__HOSTNAME=redis CKAN__HARVEST__MQ__PORT=6379 CKAN__HARVEST__MQ__REDIS_DB=1 + +# Not used by default; enable only when needed: +# USE_DEBUGPY_FOR_DEV=true +# EXTRA_UWSGI_OPTS= diff --git a/apps/ckan/CHANGELOG.md b/apps/ckan/CHANGELOG.md index 582cf46c5..9627bf03e 100644 --- a/apps/ckan/CHANGELOG.md +++ b/apps/ckan/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Update CKAN from `2.11.0` to `2.12.0` and align the Solr and PostgreSQL dependency tags with the upstream 2.12 stack. +- Normalize `.env` and `docker-compose.yml` variable references to `${VAR}` syntax and refresh upstream metadata sources. +- Add app-specific validation coverage for the CKAN login page and replace the placeholder changelog format with the repository-standard date heading. +## 2026-10-13 +- aligned CKAN PostgreSQL environment with the upstream `ckan-postgres:2.12` role/database naming (`ckan_default`, `datastore_write`, `datastore_read`) so the app and bundled database image bootstrap the same credentials +- switched the bundled database service from `ckan/ckan-postgres-dev:2.12` to plain `postgres:16` plus app-local init scripts, because the upstream dev image ships preloaded `/data` state that prevented clean validation reinitialization and kept rejecting the packaged credentials diff --git a/apps/ckan/README.md b/apps/ckan/README.md index 799e58d93..042e015ee 100644 --- a/apps/ckan/README.md +++ b/apps/ckan/README.md @@ -1,26 +1,94 @@ -# Ckan on Docker +# Ckan on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Ckan: +## Quick Start +### Deploy Verification - - community: 2.11.0 +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Ckan**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Ckan admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://docs.ckan.org/en/2.9/maintaining/installing/install-from-docker-compose.html): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Ckan by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Ckan Docker image](https://hub.docker.com/r/ckan/ckan-base) and makes some improvements below. -If you want use Ckan with **Websoft9 Business Support** free, you can [subscribe Ckan](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Ckan Administrator Guide](https://support.websoft9.com/docs/ckan) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 2.12.0. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 5000 | + + +### Data Directory + + +- `ckan_storage` → `/var/lib/ckan` +- `pip_cache` → `/root/.cache/pip` +- `site_packages` → `/usr/lib/python3.10/site-packages` +- `vscode_server` → `/root/.vscode-server` +- `pg_data` → `/var/lib/postgresql/data` +- `solr_data` → `/var/solr` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/postgresql/docker-entrypoint-initdb.d` to `/docker-entrypoint-initdb.d`. + + +## References + +- [Ckan Administrator Guide](https://support.websoft9.com/docs/ckan) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/ckan/ckan-base) + +- [Releases](https://github.com/ckan/ckan/releases) + +- [Official compose](https://raw.githubusercontent.com/ckan/ckan-docker/master/docker-compose.yml) + +- [Official env example](https://raw.githubusercontent.com/ckan/ckan-docker/master/.env.example) + +- [GitHub docs](https://github.com/ckan/ckan-docker) + +- [Official docs](https://docs.ckan.org/en/2.12/changelog.html#v-2-12-0-2026-08-26) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/ckan/docker-compose.yml b/apps/ckan/docker-compose.yml index d6244a65f..b05ffbefe 100644 --- a/apps/ckan/docker-compose.yml +++ b/apps/ckan/docker-compose.yml @@ -1,17 +1,13 @@ -# image: https://hub.docker.com/r/ckan/ckan-base -# compose refer to: https://github.com/ckan/ckan-docker/blob/master/docker-compose.yml -# docs: https://docs.ckan.org/en/2.11/maintaining/installing/index.html - version: "3.8" services: ckan-base: - container_name: $W9_ID - image: $W9_REPO:$W9_VERSION + container_name: ${W9_ID} + image: ${W9_REPO}:${W9_VERSION} env_file: - .env ports: - - $W9_HTTP_PORT_SET:5000 + - "${W9_HTTP_PORT_SET}:5000" # Web Console volumes: - ckan_storage:/var/lib/ckan - pip_cache:/root/.cache/pip @@ -19,14 +15,14 @@ services: - vscode_server:/root/.vscode-server restart: unless-stopped healthcheck: - test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:5000"] + test: ["CMD-SHELL", "curl -fsS http://localhost:5000/ >/dev/null || exit 1"] interval: 60s timeout: 10s retries: 3 datapusher: - container_name: $W9_ID-datapusher - image: $W9_REPO-datapusher:${DATAPUSHER_VERSION} + container_name: ${W9_ID}-datapusher + image: ${W9_REPO}-datapusher:${DATAPUSHER_VERSION} restart: unless-stopped healthcheck: test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:8800"] @@ -35,29 +31,31 @@ services: retries: 3 db: - container_name: $W9_ID-postgres - image: ckan/ckan-postgres-dev:2.11 + container_name: ${W9_ID}-postgres + image: postgres:${W9_DB_VERSION} environment: - POSTGRES_USER - POSTGRES_PASSWORD - POSTGRES_DB - - CKAN_DB_USER - - CKAN_DB_PASSWORD - - CKAN_DB - - DATASTORE_READONLY_USER - - DATASTORE_READONLY_PASSWORD - - DATASTORE_DB + - CKAN_POSTGRES_DB + - CKAN_POSTGRES_USER + - CKAN_POSTGRES_USER_PWD + - CKAN_DATASTORE_POSTGRES_DB + - CKAN_DATASTORE_POSTGRES_READ_USER + - CKAN_DATASTORE_POSTGRES_READ_PWD + - CKAN_DATASTORE_POSTGRES_WRITE_USER + - CKAN_DATASTORE_POSTGRES_WRITE_PWD volumes: - ./src/postgresql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d - pg_data:/var/lib/postgresql/data restart: unless-stopped - env_file: + env_file: - .env healthcheck: test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}"] - + solr: - container_name: $W9_ID-solr + container_name: ${W9_ID}-solr image: ckan/ckan-solr:${SOLR_IMAGE_VERSION} volumes: - solr_data:/var/solr @@ -66,7 +64,7 @@ services: test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:8983/solr/"] redis: - container_name: $W9_ID-redis + container_name: ${W9_ID}-redis image: redis:${REDIS_VERSION} restart: unless-stopped healthcheck: @@ -82,5 +80,5 @@ volumes: networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/10_create_ckandb.sh b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/10_create_ckandb.sh index 1c9c4ca5a..f16538e10 100644 --- a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/10_create_ckandb.sh +++ b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/10_create_ckandb.sh @@ -2,6 +2,6 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE ROLE "$CKAN_DB_USER" NOSUPERUSER CREATEDB CREATEROLE LOGIN PASSWORD '$CKAN_DB_PASSWORD'; - CREATE DATABASE "$CKAN_DB" OWNER "$CKAN_DB_USER" ENCODING 'utf-8'; + CREATE ROLE "$CKAN_POSTGRES_USER" NOSUPERUSER CREATEDB CREATEROLE LOGIN PASSWORD '$CKAN_POSTGRES_USER_PWD'; + CREATE DATABASE "$CKAN_POSTGRES_DB" OWNER "$CKAN_POSTGRES_USER" ENCODING 'utf-8'; EOSQL diff --git a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/20_create_datastore.sh b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/20_create_datastore.sh index 968e44360..73af180a9 100644 --- a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/20_create_datastore.sh +++ b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/20_create_datastore.sh @@ -2,6 +2,7 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE ROLE "$DATASTORE_READONLY_USER" NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN PASSWORD '$DATASTORE_READONLY_PASSWORD'; - CREATE DATABASE "$DATASTORE_DB" OWNER "$CKAN_DB_USER" ENCODING 'utf-8'; -EOSQL \ No newline at end of file + CREATE ROLE "$CKAN_DATASTORE_POSTGRES_READ_USER" NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN PASSWORD '$CKAN_DATASTORE_POSTGRES_READ_PWD'; + CREATE ROLE "$CKAN_DATASTORE_POSTGRES_WRITE_USER" NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN PASSWORD '$CKAN_DATASTORE_POSTGRES_WRITE_PWD'; + CREATE DATABASE "$CKAN_DATASTORE_POSTGRES_DB" OWNER "$CKAN_DATASTORE_POSTGRES_WRITE_USER" ENCODING 'utf-8'; +EOSQL diff --git a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/30_setup_test_databases.sh b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/30_setup_test_databases.sh index da55af365..87dbb9341 100644 --- a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/30_setup_test_databases.sh +++ b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/30_setup_test_databases.sh @@ -2,6 +2,7 @@ set -e psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE DATABASE ckan_test OWNER "$CKAN_DB_USER" ENCODING 'utf-8'; - CREATE DATABASE datastore_test OWNER "$CKAN_DB_USER" ENCODING 'utf-8'; + CREATE DATABASE ckan_test OWNER "$CKAN_POSTGRES_USER" ENCODING 'utf-8'; + CREATE DATABASE datastore_test OWNER "$CKAN_DATASTORE_POSTGRES_WRITE_USER" ENCODING 'utf-8'; + GRANT CONNECT ON DATABASE datastore_test TO "$CKAN_DATASTORE_POSTGRES_READ_USER"; EOSQL diff --git a/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/40_datastore_permissions.sh b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/40_datastore_permissions.sh new file mode 100644 index 000000000..5affc264b --- /dev/null +++ b/apps/ckan/src/postgresql/docker-entrypoint-initdb.d/40_datastore_permissions.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$CKAN_DATASTORE_POSTGRES_DB" <<-EOSQL + GRANT ALL PRIVILEGES ON DATABASE "$CKAN_DATASTORE_POSTGRES_DB" TO "$CKAN_DATASTORE_POSTGRES_WRITE_USER"; + GRANT CONNECT ON DATABASE "$CKAN_DATASTORE_POSTGRES_DB" TO "$CKAN_DATASTORE_POSTGRES_READ_USER"; +EOSQL diff --git a/apps/ckan/tests/cases.yml b/apps/ckan/tests/cases.yml new file mode 100644 index 000000000..68247bea8 --- /dev/null +++ b/apps/ckan/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: login-page + type: web-access + path: /user/login + expect_status: 200 diff --git a/apps/ckan/variables.json b/apps/ckan/variables.json index 332d692bc..10d694635 100644 --- a/apps/ckan/variables.json +++ b/apps/ckan/variables.json @@ -1,12 +1,12 @@ { "name": "ckan", "trademark": "Ckan", - "release": false, + "release": true, "edition": [ { "dist": "community", "version": [ - "2.11.0" + "2.12.0" ] } ], @@ -23,6 +23,22 @@ "disk": "1" }, "upstream": { - "image": "https://hub.docker.com/r/ckan/ckan-base" + "image": "https://hub.docker.com/r/ckan/ckan-base", + "releases": "https://github.com/ckan/ckan/releases", + "compose": { + "compose": "https://raw.githubusercontent.com/ckan/ckan-docker/master/docker-compose.yml", + "env": "https://raw.githubusercontent.com/ckan/ckan-docker/master/.env.example" + }, + "docs": [ + "https://github.com/ckan/ckan-docker", + "https://docs.ckan.org/en/2.12/changelog.html#v-2-12-0-2026-08-26" + ] + }, + "env": { + "secrets": [ + "CKAN___BEAKER__SESSION__SECRET", + "CKAN___API_TOKEN__JWT__ENCODE__SECRET", + "CKAN___API_TOKEN__JWT__DECODE__SECRET" + ] } } diff --git a/apps/clickhouse/.env b/apps/clickhouse/.env index 8335b252c..e3300a3e9 100644 --- a/apps/clickhouse/.env +++ b/apps/clickhouse/.env @@ -1,6 +1,6 @@ W9_REPO=clickhouse/clickhouse-server W9_DIST=community -W9_VERSION=26.8 +W9_VERSION=26.9 # Optional password seed: enable only when the package actually controls a DB or built-in login. # See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. @@ -18,7 +18,7 @@ W9_HTTP_PORT_SET=8123 # Built-in login: ClickHouse creates this user on first start. W9_LOGIN_USER=admin W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} -W9_ADMIN_PATH=/dashboard +W9_ADMIN_PATH=/play W9_URL=appname.example.com diff --git a/apps/clickhouse/CHANGELOG.md b/apps/clickhouse/CHANGELOG.md index dab3949bf..fe53ff34b 100644 --- a/apps/clickhouse/CHANGELOG.md +++ b/apps/clickhouse/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## 2026-10-13 + +- Update ClickHouse from `26.8` to `26.9` based on the latest stable upstream branch tag. +- Fix the app metadata/admin path drift to point at the actual Play UI path `/play`. +- Record first-startup-only ClickHouse init envs and declarative login credential metadata. +- Expand `tests/cases.yml` with an app-specific Play UI reachability check. + ## 2026-09-15 - Update ClickHouse to `26.8` (alias `latest`). diff --git a/apps/clickhouse/README.md b/apps/clickhouse/README.md index d9c91931b..d236b29fe 100644 --- a/apps/clickhouse/README.md +++ b/apps/clickhouse/README.md @@ -25,7 +25,6 @@ Websoft9 packages this app from the official [ClickHouse Docker image](https://hub.docker.com/r/clickhouse/clickhouse-server) and makes some improvements below. - ### ClickHouse SQL ``` @@ -40,7 +39,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 26.8, latest. +Supported versions: 26.9, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -67,6 +66,9 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. +Note: `CLICKHOUSE_DB`, `CLICKHOUSE_USER`, `CLICKHOUSE_PASSWORD`, `CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + ### Configuration Files diff --git a/apps/clickhouse/tests/cases.yml b/apps/clickhouse/tests/cases.yml index b401b4153..7b1b406aa 100644 --- a/apps/clickhouse/tests/cases.yml +++ b/apps/clickhouse/tests/cases.yml @@ -1,4 +1,8 @@ optional: + - id: play-ui + type: web-access + path: /play + expect_status: 200 - id: ping type: web-access path: /ping diff --git a/apps/clickhouse/variables.json b/apps/clickhouse/variables.json index c222529c4..cbab9dbfe 100644 --- a/apps/clickhouse/variables.json +++ b/apps/clickhouse/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "26.8", + "26.9", "latest" ] } @@ -30,9 +30,23 @@ "memory": "1", "disk": "2" }, - "credentials": {}, + "credentials": { + "username": { + "source": "container-env", + "name": "W9_LOGIN_USER" + }, + "password": { + "source": "container-env", + "name": "W9_LOGIN_PASSWORD" + } + }, "env": { - "first_startup_only": [] + "first_startup_only": [ + "CLICKHOUSE_DB", + "CLICKHOUSE_USER", + "CLICKHOUSE_PASSWORD", + "CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT" + ] }, "help": {} } diff --git a/apps/codeserver/.env b/apps/codeserver/.env index 3ebfa0bb9..2a2e91445 100644 --- a/apps/codeserver/.env +++ b/apps/codeserver/.env @@ -1,4 +1,4 @@ -W9_VERSION='4.106.3' +W9_VERSION='4.141.0' W9_DIST='community' W9_REPO=linuxserver/code-server W9_POWER_PASSWORD='8bgj9nf7!fQDkGiL' @@ -7,22 +7,29 @@ W9_POWER_PASSWORD='8bgj9nf7!fQDkGiL' W9_ID='codeserver' W9_HTTP_PORT=8443 W9_HTTP_PORT_SET='9001' -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD W9_URL='appname.example.com' -W9_URL_REPLACE=true W9_NETWORK=websoft9 #### --------------------------------------------------------------------------------------- #### -# Codeserver environments +# ============================================================ +# CodeServer image environment variables +# Docs: https://docs.linuxserver.io/images/docker-code-server/ +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: PUID=1000 PGID=1000 # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List TZ=Europe/London -PASSWORD=$W9_LOGIN_PASSWORD +PASSWORD=${W9_POWER_PASSWORD} HASHED_PASSWORD= -SUDO_PASSWORD=$W9_POWER_PASSWORD +SUDO_PASSWORD=${W9_POWER_PASSWORD} SUDO_PASSWORD_HASH= +# Not used by default; enable only when needed: # 此代理是全局域名,用于将codeserver上的多个应用自动提供子域名访问 -# PROXY_DOMAIN=$W9_URL +# PROXY_DOMAIN=${W9_URL} DEFAULT_WORKSPACE=/config/workspace diff --git a/apps/codeserver/CHANGELOG.md b/apps/codeserver/CHANGELOG.md index 582cf46c5..1106ccfdf 100644 --- a/apps/codeserver/CHANGELOG.md +++ b/apps/codeserver/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Updated CodeServer from `4.106.3` to `4.141.0` using the trusted `linuxserver/code-server` image. +- Brought the touched `.env` and `docker-compose.yml` files into current repository policy by converting variable references to `${VAR}` form and adding the required image-env docs block and port-purpose comment. +- Added app-specific validation coverage under `tests/cases.yml` and `tests/check.sh` for the password-protected console login page. diff --git a/apps/codeserver/README.md b/apps/codeserver/README.md index a47107ee6..feb19072a 100644 --- a/apps/codeserver/README.md +++ b/apps/codeserver/README.md @@ -3,12 +3,12 @@ This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for CodeServer: - - community: 4.98.2, latest + - community: 4.141.0, latest ## System Requirements -The following are the minimal [recommended requirements](https://github.com/cdr/code-server/blob/main/docs/guide.md#requirements): +The following are the minimal [recommended requirements](https://github.com/coder/code-server/blob/main/docs/guide.md#requirements): * **RAM**: 1 GB or more * **CPU**: 1 cores or higher @@ -23,4 +23,4 @@ If you want use CodeServer with **Websoft9 Business Support** free, you can [sub ## Documentation -[CodeServer Administrator Guide](https://support.websoft9.com/docs/codeserver) powered by Websoft9 \ No newline at end of file +[CodeServer Administrator Guide](https://support.websoft9.com/docs/codeserver) powered by Websoft9 diff --git a/apps/codeserver/docker-compose.yml b/apps/codeserver/docker-compose.yml index 0388681d1..848871742 100644 --- a/apps/codeserver/docker-compose.yml +++ b/apps/codeserver/docker-compose.yml @@ -1,18 +1,15 @@ -# image: https://hub.docker.com/r/linuxserver/code-server - -version: "3.8" services: code-server: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} env_file: .env cpu_percent: 50 mem_limit: 4g volumes: - "code:/config" ports: - - $W9_HTTP_PORT_SET:8443 - #- 9003:3000 # for webserver when development test + - "${W9_HTTP_PORT_SET}:8443" # Web Console + #- "9003:3000" # App preview during development restart: unless-stopped networks: diff --git a/apps/codeserver/tests/cases.yml b/apps/codeserver/tests/cases.yml new file mode 100644 index 000000000..317b11a34 --- /dev/null +++ b/apps/codeserver/tests/cases.yml @@ -0,0 +1,4 @@ +custom: + - id: login-page + type: script + script: check.sh diff --git a/apps/codeserver/tests/check.sh b/apps/codeserver/tests/check.sh new file mode 100644 index 000000000..a456e167f --- /dev/null +++ b/apps/codeserver/tests/check.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +base_url="${BASE_URL%/}" + +login_page_status="$(curl -k -sS -o /dev/null -w "%{http_code}" "${base_url}/login")" +if [ "${login_page_status}" != "200" ]; then + echo "expected /login to return 200, got ${login_page_status}" + exit 1 +fi + +session_headers="$(mktemp)" +session_body="$(mktemp)" +trap 'rm -f "${session_headers}" "${session_body}"' EXIT + +login_status="$(curl -k -sS -o "${session_body}" -w "%{http_code}" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -D "${session_headers}" \ + --data-urlencode "password=${W9_POWER_PASSWORD}" \ + --data-urlencode "base=." \ + --data-urlencode "href=${base_url}/" \ + "${base_url}/login")" + +if [ "${login_status}" != "302" ]; then + echo "expected login POST to return 302, got ${login_status}" + cat "${session_headers}" + cat "${session_body}" + exit 1 +fi + +if ! grep -qi '^set-cookie: code-server-session=' "${session_headers}"; then + echo "missing code-server-session cookie after successful login" + cat "${session_headers}" + exit 1 +fi diff --git a/apps/codeserver/variables.json b/apps/codeserver/variables.json index 48eece766..ef051a737 100644 --- a/apps/codeserver/variables.json +++ b/apps/codeserver/variables.json @@ -9,7 +9,7 @@ { "dist": "community", "version": [ - "4.106.3", + "4.141.0", "latest" ] } @@ -21,6 +21,12 @@ "path": "/" } }, + "credentials": { + "password": { + "source": "container-env", + "name": "W9_POWER_PASSWORD" + } + }, "requirements": { "cpu": "1", "memory": "1", diff --git a/apps/consul/.env b/apps/consul/.env index 21bd440bc..518f14999 100644 --- a/apps/consul/.env +++ b/apps/consul/.env @@ -1,17 +1,36 @@ -W9_REPO="hashicorp/consul" -W9_DIST='community' -W9_VERSION='1.22' -W9_POWER_PASSWORD='IFpSQvp6K!3KlubG' +W9_REPO=hashicorp/consul +W9_DIST=community +W9_VERSION=2.0.4 -# Environments which for user settings when create application -W9_HTTP_PORT_SET='9001' -W9_DNS_TCP_PORT_SET='8600' -W9_DNS_UDP_PORT_SET='8600' +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='Consul' + +W9_ID=Consul W9_HTTP_PORT=8500 -W9_URL='example.youdomain.com' +W9_HTTP_PORT_SET=9185 +W9_URL=example.youdomain.com W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### + +#W9_NAME= +#W9_RCODE= + +# ============================================================ +# Consul image environment variables +# Docs: https://hub.docker.com/r/hashicorp/consul +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# CONSUL_BIND_INTERFACE= +# CONSUL_CLIENT_INTERFACE= +# CONSUL_DATACENTER= +# CONSUL_DOMAIN= +# CONSUL_LOCAL_CONFIG= diff --git a/apps/consul/CHANGELOG.md b/apps/consul/CHANGELOG.md index 582cf46c5..a121ca3c6 100644 --- a/apps/consul/CHANGELOG.md +++ b/apps/consul/CHANGELOG.md @@ -1,5 +1,6 @@ # CHANGELOG -## Release -### Fixes and Enhancements - +## 2026-10-13 +- Update Consul from `1.22` to `2.0.4` based on the latest stable upstream release line. +- Align `.env` and `docker-compose.yml` with current repository policy for braced variables, protected port layout, and inline published-port purpose comments. +- Simplify the package to expose the Consul HTTP UI/API port only and add app-specific deploy validation coverage. diff --git a/apps/consul/README.md b/apps/consul/README.md index d67e6cd66..c59ac7c8c 100644 --- a/apps/consul/README.md +++ b/apps/consul/README.md @@ -1,26 +1,86 @@ -# Consul on Docker +# Consul on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Consul: +## Quick Start +### Deploy Verification - - community: 1.21, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Consul**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Consul admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.consul.io): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Consul by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Consul Docker image](https://hub.docker.com/r/hashicorp/consul) and makes some improvements below. -If you want use Consul with **Websoft9 Business Support** free, you can [subscribe Consul](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Consul Administrator Guide](https://support.websoft9.com/docs/consul) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 2.0.4, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web UI and HTTP API | 8500 | + + +### Data Directory + + +Data is persisted in the `consul-data` volume, mounted at `/consul/data`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/consul-config` to `/consul/config`. + + +## References + +- [Consul Administrator Guide](https://support.websoft9.com/docs/consul) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/hashicorp/consul) + +- [Releases](https://github.com/hashicorp/consul/releases) + +- [Official docs](https://developer.hashicorp.com/consul/docs/release-notes) + +- [Official docs](https://developer.hashicorp.com/consul/docs/install/docker) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/consul/docker-compose.yml b/apps/consul/docker-compose.yml index f48fd2019..b8f36056c 100644 --- a/apps/consul/docker-compose.yml +++ b/apps/consul/docker-compose.yml @@ -1,22 +1,20 @@ services: consul-server: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} env_file: .env ports: - - $W9_HTTP_PORT_SET:8500 - - $W9_DNS_TCP_PORT_SET:8600/tcp - - $W9_DNS_UDP_PORT_SET:8600/udp + - "${W9_HTTP_PORT_SET}:8500" # Web UI and HTTP API volumes: - - ./src/consul-config:/consul/config - - consul-data:/consul/data + - ./src/consul-config:/consul/config + - consul-data:/consul/data restart: unless-stopped - command: agent + command: agent -server -bootstrap-expect=1 -ui -client=0.0.0.0 volumes: consul-data: - + networks: default: - name: $W9_NETWORK - external: true \ No newline at end of file + name: ${W9_NETWORK} + external: true diff --git a/apps/consul/tests/cases.yml b/apps/consul/tests/cases.yml new file mode 100644 index 000000000..4874a7ffc --- /dev/null +++ b/apps/consul/tests/cases.yml @@ -0,0 +1,4 @@ +custom: + - id: consul-members + type: script + script: members.sh diff --git a/apps/consul/tests/members.sh b/apps/consul/tests/members.sh new file mode 100755 index 000000000..289ad24b4 --- /dev/null +++ b/apps/consul/tests/members.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +container_name="${W9_ID}" +members_output="$(docker exec "${container_name}" consul members)" + +if [[ -z "${members_output}" ]]; then + echo "consul members returned empty output" + exit 1 +fi + +if ! grep -Eq 'alive' <<<"${members_output}"; then + echo "no alive consul member reported" + exit 1 +fi diff --git a/apps/consul/variables.json b/apps/consul/variables.json index 2c9e43822..be8a66726 100644 --- a/apps/consul/variables.json +++ b/apps/consul/variables.json @@ -3,13 +3,18 @@ "trademark": "Consul", "release": true, "upstream": { - "image": "https://hub.docker.com/r/hashicorp/consul" + "image": "https://hub.docker.com/r/hashicorp/consul", + "releases": "https://github.com/hashicorp/consul/releases", + "docs": [ + "https://developer.hashicorp.com/consul/docs/release-notes", + "https://developer.hashicorp.com/consul/docs/install/docker" + ] }, "edition": [ { "dist": "community", "version": [ - "1.22", + "2.0.4", "latest" ] } diff --git a/apps/couchbase/.env b/apps/couchbase/.env index cce199ec5..ff1c4d1be 100644 --- a/apps/couchbase/.env +++ b/apps/couchbase/.env @@ -1,11 +1,9 @@ -W9_REPO=couchbase +W9_REPO=couchbase/server W9_DIST=community -W9_VERSION=community +W9_VERSION=8.0.3 -W9_HTTP_PORT_SET=9027 W9_ID=couchbase W9_HTTP_PORT=8091 +W9_HTTP_PORT_SET=9027 W9_URL=example.youdomain.com -W9_URL_REPLACE=true -W9_URL_WITH_PORT=false W9_NETWORK=websoft9 diff --git a/apps/couchbase/CHANGELOG.md b/apps/couchbase/CHANGELOG.md index 582cf46c5..2eabade07 100644 --- a/apps/couchbase/CHANGELOG.md +++ b/apps/couchbase/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Updated Couchbase Community packaging target to the current stable image tag `community-8.0.3` after verifying the floating `8.0` image tag is not published. +- Normalized `.env` and `docker-compose.yml` to current repository policy by using the official image repository, braced variable references, and inline published-port comments. +- Added app-specific validation coverage for the Couchbase setup screen. +## 2026-10-13 + +- switched the package from the non-existent `community-8.0.3` / `8.0` tags to the verified official `couchbase/server:8.0.3` image tag +- refreshed the setup-screen smoke check to match the current Couchbase 8.0 web shell content exposed before cluster initialization diff --git a/apps/couchbase/README.md b/apps/couchbase/README.md index d2b64de98..f3e444528 100644 --- a/apps/couchbase/README.md +++ b/apps/couchbase/README.md @@ -1,26 +1,84 @@ -# Couchbase on Docker +# Couchbase on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Couchbase: +## Quick Start +### Deploy Verification - - community: community-7.6.2, community +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Couchbase**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Couchbase admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://docs.couchbase.com/server/current/install/pre-install.html): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 8 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Couchbase by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Couchbase Docker image](https://hub.docker.com/r/couchbase/server) and makes some improvements below. -If you want use Couchbase with **Websoft9 Business Support** free, you can [subscribe Couchbase](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Couchbase Administrator Guide](https://support.websoft9.com/docs/couchbase) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 8.0.3. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 8091 | + + +### Data Directory + + +Data is kept inside the container; a named volume is recommended for persistence. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Couchbase Administrator Guide](https://support.websoft9.com/docs/couchbase) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/couchbase/server) + +- [Official docs](https://docs.couchbase.com/server/current/release-notes/relnotes.html) + +- [Official docs](https://docs.couchbase.com/server/current/install/getting-started-docker.html) + +- [Official docs](https://docs.couchbase.com/server/current/install/pre-install.html) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/couchbase/docker-compose.yml b/apps/couchbase/docker-compose.yml index 6e01eef5a..3517fbf8c 100644 --- a/apps/couchbase/docker-compose.yml +++ b/apps/couchbase/docker-compose.yml @@ -1,25 +1,16 @@ -# image: https://hub.docker.com/r/couchbase/server -# docs: https://docs.couchbase.com/server/current/getting-started/do-a-quick-install.html - version: '3.8' services: couchbase-server: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} restart: unless-stopped ports: - - $W9_HTTP_PORT_SET:8091 - # - 8091-8097:8091-8097 - # - 9123:9123 - # - 11207:11207 - # - 11210:11210 - # - 11280:11280 - # - 18091-18097:18091-18097 + - "${W9_HTTP_PORT_SET}:8091" # Web Console env_file: .env networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/couchbase/tests/cases.yml b/apps/couchbase/tests/cases.yml new file mode 100644 index 000000000..aee767a38 --- /dev/null +++ b/apps/couchbase/tests/cases.yml @@ -0,0 +1,4 @@ +custom: + - id: setup-screen + type: script + script: verify-setup-screen.sh diff --git a/apps/couchbase/tests/verify-setup-screen.sh b/apps/couchbase/tests/verify-setup-screen.sh new file mode 100755 index 000000000..ff80b0873 --- /dev/null +++ b/apps/couchbase/tests/verify-setup-screen.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail + +curl -fsSL "${BASE_URL}/" | grep -qi "Couchbase Server" diff --git a/apps/couchbase/variables.json b/apps/couchbase/variables.json index 6d6c71484..f399e4f06 100644 --- a/apps/couchbase/variables.json +++ b/apps/couchbase/variables.json @@ -6,8 +6,7 @@ { "dist": "community", "version": [ - "community-7.6.2", - "community" + "8.0.3" ] } ], @@ -18,12 +17,21 @@ "path": "/" } }, + "credentials": {}, + "env": { + "first_startup_only": [] + }, "requirements": { "cpu": "2", "memory": "4", "disk": "8" }, "upstream": { - "image": "https://hub.docker.com/r/couchbase/server" + "image": "https://hub.docker.com/r/couchbase/server", + "docs": [ + "https://docs.couchbase.com/server/current/release-notes/relnotes.html", + "https://docs.couchbase.com/server/current/install/getting-started-docker.html", + "https://docs.couchbase.com/server/current/install/pre-install.html" + ] } } diff --git a/apps/couchdb/.env b/apps/couchdb/.env index 93828aaf2..e84b7ef21 100644 --- a/apps/couchdb/.env +++ b/apps/couchdb/.env @@ -1,15 +1,37 @@ -W9_POWER_PASSWORD='Aklvinyb!6!yQgJ6' -W9_VERSION='3.5.0' -W9_DIST='community' W9_REPO=couchdb +W9_DIST=community +W9_VERSION=3.5 +W9_POWER_PASSWORD="Aklvinyb!6!yQgJ6" + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='couchdb' + +W9_ID=couchdb W9_HTTP_PORT=5984 -W9_HTTP_PORT_SET='5984' +W9_HTTP_PORT_SET=5984 W9_LOGIN_USER=admin -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_URL='appname.example.com' -W9_ADMIN_PATH="/_utils" +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +W9_URL=appname.example.com +W9_ADMIN_PATH=/_utils W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# CouchDB image environment variables +# Docs: https://hub.docker.com/_/couchdb +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# NODENAME= +# ERL_FLAGS= +# COUCHDB_SECRET= +# COUCHDB_ERLANG_COOKIE= +# COUCHDB_UUID= diff --git a/apps/couchdb/CHANGELOG.md b/apps/couchdb/CHANGELOG.md index 582cf46c5..9ed1efefa 100644 --- a/apps/couchdb/CHANGELOG.md +++ b/apps/couchdb/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Upgrade CouchDB community from `3.5.0` to the stable `3.5` track, verified against upstream Apache tags through `3.5.3`. +- Normalize the package to current repository conventions for `.env` layout, braced variable references, and documented published port purpose. +- Add app-specific authenticated validation coverage for the CouchDB HTTP API. diff --git a/apps/couchdb/Notes.md b/apps/couchdb/Notes.md index 26939d1e3..cb61cf820 100644 --- a/apps/couchdb/Notes.md +++ b/apps/couchdb/Notes.md @@ -1,3 +1,3 @@ # CouchDB -GUI: http://Internet IP:5984/_utils/#login \ No newline at end of file +GUI: http://${W9_URL}:${W9_HTTP_PORT_SET}/_utils/#login diff --git a/apps/couchdb/README.md b/apps/couchdb/README.md index b4ad9ca80..dbecfdb00 100644 --- a/apps/couchdb/README.md +++ b/apps/couchdb/README.md @@ -1,26 +1,89 @@ -# CouchDB on Docker +# CouchDB on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for CouchDB: +## Quick Start +### Deploy Verification - - community: 3.5.0, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **CouchDB**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the CouchDB admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://docs.couchdb.org/en/latest/install/index.html): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this CouchDB by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [CouchDB Docker image](https://hub.docker.com/_/couchdb) and makes some improvements below. -If you want use CouchDB with **Websoft9 Business Support** free, you can [subscribe CouchDB](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[CouchDB Administrator Guide](https://support.websoft9.com/docs/couchdb) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 3.5, 3.4, 3.3, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console and API | 5984 | + + +### Data Directory + + +- `couchdb_data` → `/opt/couchdb/data` +- `couchdb_config` → `/opt/couchdb/etc/local.d` +- `couchdb_log` → `/opt/couchdb/var/log` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/my.ini` to `/opt/couchdb/etc/local.d/my.ini`. + + +## References + +- [CouchDB Administrator Guide](https://support.websoft9.com/docs/couchdb) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/couchdb) + +- [Releases](https://github.com/apache/couchdb) + +- [Official docs](https://docs.couchdb.org/en/stable/install/docker.html) + +- [GitHub docs](https://github.com/apache/couchdb-docker) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/couchdb/docker-compose.yml b/apps/couchdb/docker-compose.yml index affcd4d7a..626421d12 100644 --- a/apps/couchdb/docker-compose.yml +++ b/apps/couchdb/docker-compose.yml @@ -1,9 +1,3 @@ -# docs: https://docs.couchdb.org/en/latest/install/docker.html -# source: https://github.com/apache/couchdb-docker -# image: https://hub.docker.com/_/couchdb - -version: '3.8' - services: couchdb: @@ -11,12 +5,12 @@ services: container_name: ${W9_ID} restart: unless-stopped ports: - - ${W9_HTTP_PORT_SET}:5984 + - "${W9_HTTP_PORT_SET}:5984" # Web Console and API volumes: - - couchdb_data:/opt/couchdb/data - - couchdb_config:/opt/couchdb/etc/local.d - - ./src/my.ini:/opt/couchdb/etc/local.d/my.ini - - couchdb_log:/opt/couchdb/var/log + - couchdb_data:/opt/couchdb/data + - couchdb_config:/opt/couchdb/etc/local.d + - ./src/my.ini:/opt/couchdb/etc/local.d/my.ini + - couchdb_log:/opt/couchdb/var/log env_file: .env environment: COUCHDB_USER: ${W9_LOGIN_USER} diff --git a/apps/couchdb/tests/cases.yml b/apps/couchdb/tests/cases.yml new file mode 100644 index 000000000..555a33c15 --- /dev/null +++ b/apps/couchdb/tests/cases.yml @@ -0,0 +1,7 @@ +# CouchDB's core path is accepting authenticated HTTP API requests after init. +# The default web-access check only proves the port is reachable, so a custom +# script verifies authenticated access to the root endpoint. +custom: + - id: couchdb-authenticated-api + type: script + script: check.sh diff --git a/apps/couchdb/tests/check.sh b/apps/couchdb/tests/check.sh new file mode 100755 index 000000000..0b5f814d0 --- /dev/null +++ b/apps/couchdb/tests/check.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -euo pipefail + +container="${W9_ID:?W9_ID is required}" +user="${W9_LOGIN_USER:?W9_LOGIN_USER is required}" +password="${W9_LOGIN_PASSWORD:?W9_LOGIN_PASSWORD is required}" + +deadline=$((SECONDS + 180)) +while [ "${SECONDS}" -lt "${deadline}" ]; do + if docker exec "${container}" curl -fsS -u "${user}:${password}" "http://127.0.0.1:5984/" >/dev/null 2>&1; then + echo "CouchDB accepted an authenticated local API request" + exit 0 + fi + sleep 5 +done + +echo "CouchDB did not accept an authenticated API request before timeout" >&2 +exit 1 diff --git a/apps/couchdb/variables.json b/apps/couchdb/variables.json index 23b509da7..9e01ed015 100644 --- a/apps/couchdb/variables.json +++ b/apps/couchdb/variables.json @@ -3,13 +3,20 @@ "trademark": "CouchDB", "release": true, "upstream": { - "image": "https://hub.docker.com/_/couchdb" + "image": "https://hub.docker.com/_/couchdb", + "releases": "https://github.com/apache/couchdb", + "docs": [ + "https://docs.couchdb.org/en/stable/install/docker.html", + "https://github.com/apache/couchdb-docker" + ] }, "edition": [ { "dist": "community", "version": [ - "3.5.0", + "3.5", + "3.4", + "3.3", "latest" ] } diff --git a/apps/directus/.env b/apps/directus/.env index 8ababf9d6..0760e56d3 100644 --- a/apps/directus/.env +++ b/apps/directus/.env @@ -1,31 +1,55 @@ -W9_VERSION='11.13' -W9_DIST='community' W9_REPO=directus/directus +W9_DIST=community +W9_VERSION=12.5.0 + W9_POWER_PASSWORD='KL70ofeR!Hz699!h' +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='directus' + +W9_ID=directus W9_HTTP_PORT=8055 -W9_HTTP_PORT_SET='9001' +W9_HTTP_PORT_SET=9001 +W9_DB_EXPOSE=postgresql +W9_DB_VERSION=13 W9_LOGIN_USER=websoft9@example.com -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_DB_EXPOSE="postgresql" -W9_DB_POSTGRE_VERSION="13" -W9_URL='appname.example.com' +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +W9_URL=directus.example.com +W9_URL_REPLACE=true W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### - -# Directus environments: https://docs.directus.io/self-hosted/config-options.html -KEY='255d861b-5ea1-${W9_POWER_PASSWORD}' -SECRET='6116487b-cda1-${W9_POWER_PASSWORD}' -DB_CLIENT='postgres' -DB_HOST=$W9_ID-postgresql -DB_PORT='5432' -DB_DATABASE=$W9_ID -DB_USER=$W9_ID -DB_PASSWORD=$W9_POWER_PASSWORD -ADMIN_EMAIL=$W9_LOGIN_USER -ADMIN_PASSWORD=$W9_POWER_PASSWORD + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Directus image environment variables +# Docs: https://directus.io/docs/configuration/general +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +KEY=255d861b-5ea1-${W9_POWER_PASSWORD} +SECRET=6116487b-cda1-${W9_POWER_PASSWORD} +DB_CLIENT=pg +DB_HOST=${W9_ID}-postgresql +DB_PORT=5432 +DB_DATABASE=${W9_ID} +DB_USER=${W9_ID} +DB_PASSWORD=${W9_POWER_PASSWORD} +ADMIN_EMAIL=${W9_LOGIN_USER} +ADMIN_PASSWORD=${W9_LOGIN_PASSWORD} CACHE_ENABLED=true +CACHE_AUTO_PURGE=true CACHE_STORE=redis -REDIS=redis://$W9_ID-redis:6379 +REDIS=redis://${W9_ID}-redis:6379 +PUBLIC_URL=http://${W9_URL} + +# Not used by default; enable only when needed: +# TELEMETRY=false +# WEBSOCKETS_ENABLED=true +# CORS_ENABLED=true +# CORS_ORIGIN=true +# IMPORT_MAX_FILE_SIZE=50mb diff --git a/apps/directus/CHANGELOG.md b/apps/directus/CHANGELOG.md index 582cf46c5..2ed903b88 100644 --- a/apps/directus/CHANGELOG.md +++ b/apps/directus/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Update Directus from 11.13 to 12.5.0. +- Align `.env` and `docker-compose.yml` with current repository policy and current Directus self-hosting guidance. +- Extend the main container healthcheck window for Directus first-start bootstrap and add app-specific validation coverage for the Directus health endpoint. diff --git a/apps/directus/README.md b/apps/directus/README.md index 05edb5b6b..7235790ce 100644 --- a/apps/directus/README.md +++ b/apps/directus/README.md @@ -1,26 +1,95 @@ -# Directus on Docker +# Directus on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Directus: +## Quick Start +### Deploy Verification - - community: 11.8, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Directus**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Directus admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://docs.directus.io/getting-started/installation): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Directus by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Directus Docker image](https://hub.docker.com/r/directus/directus) and makes some improvements below. -If you want use Directus with **Websoft9 Business Support** free, you can [subscribe Directus](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Directus Administrator Guide](https://support.websoft9.com/docs/directus) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 12.5.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 8055 | + + +### Data Directory + + +- `directus_uploads` → `/directus/uploads` +- `directus_extensions` → `/directus/extensions` +- `directus_sqlite` → `/directus/database` +- `postgres` → `/var/lib/postgresql/data` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +Note: `ADMIN_EMAIL`, `ADMIN_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Directus Administrator Guide](https://support.websoft9.com/docs/directus) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/directus/directus) + +- [Releases](https://github.com/directus/directus/releases) + +- [Official docs](https://directus.io/docs/self-hosting/quickstart) + +- [Official docs](https://directus.io/docs/configuration/general) + +- [GitHub docs](https://github.com/directus/directus/releases/tag/v12.5.0) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/directus/docker-compose.yml b/apps/directus/docker-compose.yml index 8a632ef3f..aabebd622 100644 --- a/apps/directus/docker-compose.yml +++ b/apps/directus/docker-compose.yml @@ -1,41 +1,55 @@ -# image: https://hub.docker.com/r/directus/directus -# docs: https://docs.directus.io/self-hosted/docker-guide.html -# compose: https://docs.directus.io/self-hosted/docker-guide.html#example-docker-compose - - -version: '3.8' - services: directus: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID - env_file: .env + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + env_file: + - .env ports: - - $W9_HTTP_PORT_SET:$W9_HTTP_PORT + - "${W9_HTTP_PORT_SET}:8055" # Web Console volumes: - directus_uploads:/directus/uploads - directus_extensions:/directus/extensions - directus_sqlite:/directus/database restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:8055/server/ping || exit 1"] + interval: 10s + timeout: 5s + retries: 12 + start_period: 120s depends_on: - - cache - - postgresql + cache: + condition: service_healthy + postgresql: + condition: service_healthy postgresql: - image: postgres:$W9_DB_POSTGRE_VERSION - container_name: $W9_ID-postgresql + image: postgres:${W9_DB_VERSION} + container_name: ${W9_ID}-postgresql restart: unless-stopped volumes: - postgres:/var/lib/postgresql/data environment: - POSTGRES_DB: $W9_ID - POSTGRES_USER: $W9_ID - POSTGRES_PASSWORD: $W9_POWER_PASSWORD + POSTGRES_DB: ${W9_ID} + POSTGRES_USER: ${W9_ID} + POSTGRES_PASSWORD: ${W9_POWER_PASSWORD} + healthcheck: + test: ["CMD", "pg_isready", "--host=localhost", "--username=${W9_ID}"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s cache: - image: redis:6 - container_name: $W9_ID-redis + image: redis:7 + container_name: ${W9_ID}-redis restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "[ $$(redis-cli ping) = 'PONG' ]"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s networks: default: diff --git a/apps/directus/tests/cases.yml b/apps/directus/tests/cases.yml new file mode 100644 index 000000000..6645c2f16 --- /dev/null +++ b/apps/directus/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: directus-server-ping + type: web-access + path: /server/ping + expect_status: 200 diff --git a/apps/directus/variables.json b/apps/directus/variables.json index 3a458ed9b..2bf8ab13a 100644 --- a/apps/directus/variables.json +++ b/apps/directus/variables.json @@ -2,11 +2,20 @@ "name": "directus", "trademark": "Directus", "release": true, + "upstream": { + "image": "https://hub.docker.com/r/directus/directus", + "releases": "https://github.com/directus/directus/releases", + "docs": [ + "https://directus.io/docs/self-hosting/quickstart", + "https://directus.io/docs/configuration/general", + "https://github.com/directus/directus/releases/tag/v12.5.0" + ] + }, "edition": [ { "dist": "community", "version": [ - "11.13", + "12.5.0", "latest" ] } @@ -23,7 +32,10 @@ "memory": "2", "disk": "4" }, - "upstream": { - "image": "https://hub.docker.com/r/directus/directus" + "env": { + "first_startup_only": [ + "ADMIN_EMAIL", + "ADMIN_PASSWORD" + ] } } diff --git a/apps/dolibarr/.env b/apps/dolibarr/.env index 502e68ec3..128d8cb6a 100644 --- a/apps/dolibarr/.env +++ b/apps/dolibarr/.env @@ -1,6 +1,6 @@ -W9_REPO=tuxgasy/dolibarr +W9_REPO=dolibarr/dolibarr W9_DIST=community -W9_VERSION=19.0.2 +W9_VERSION=24.0.1 W9_POWER_PASSWORD="spJNF09yzwWJaG!" @@ -24,6 +24,7 @@ W9_DB_VERSION=12.3 W9_LOGIN_USER=admin W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} W9_URL=appname.example.com +W9_URL_REPLACE=true W9_NETWORK=websoft9 @@ -31,14 +32,14 @@ W9_NETWORK=websoft9 # ============================================================ # Dolibarr image environment variables -# Docs: https://github.com/tuxgasy/docker-dolibarr +# Docs: https://github.com/Dolibarr/dolibarr-docker # Follow docs/w9-env-spec.md when deciding which vars belong here. # Enable the vars actually used in docker-compose.yml below; list up # to 5 unused vars commented out. Full reference lives in the Docs URL. # ============================================================ # Used by docker-compose.yml: -DOLI_URL_ROOT=http://0.0.0.0 +DOLI_URL_ROOT=http://${W9_URL} DOLI_DB_HOST=${W9_ID}-mariadb DOLI_DB_USER=${W9_ID} DOLI_DB_PASSWORD=${W9_POWER_PASSWORD} @@ -51,6 +52,6 @@ PHP_INI_MEMORY_LIMIT=512M # Not used by default; enable only when needed: # DOLI_AUTH=dolibarr # DOLI_INSTALL_AUTO=1 -# DOLI_DB_PORT=3306 +# DOLI_DB_HOST_PORT=3306 # PHP_INI_UPLOAD_MAX_FILESIZE=2M # PHP_INI_MAX_EXECUTION_TIME=120 diff --git a/apps/dolibarr/CHANGELOG.md b/apps/dolibarr/CHANGELOG.md index 4c8ca2ac9..bdb13ce6b 100644 --- a/apps/dolibarr/CHANGELOG.md +++ b/apps/dolibarr/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-13 + +- Switched Dolibarr from the archived `tuxgasy/dolibarr` image to the maintained official `dolibarr/dolibarr` image. +- Updated the packaged Dolibarr target from `19.0.2` to `24.0.1`, matching the latest stable upstream release and the official Docker packaging. +- Wired `DOLI_URL_ROOT` to `${W9_URL}` with `W9_URL_REPLACE=true`, corrected the optional DB port variable name to `DOLI_DB_HOST_PORT`, and recorded both login seed variables as first-startup-only metadata for README generation. + ## 2026-09-17 - Fixed the version drift: pinned `W9_VERSION` from `18` to `19.0.2`, matching `variables.json.edition` and the current upstream release. diff --git a/apps/dolibarr/README.md b/apps/dolibarr/README.md index 5258b02eb..d4933778c 100644 --- a/apps/dolibarr/README.md +++ b/apps/dolibarr/README.md @@ -24,7 +24,7 @@ ## Configuration Reference -Websoft9 packages this app from the official [Dolibarr Docker image](https://hub.docker.com/r/tuxgasy/dolibarr) and makes some improvements below. +Websoft9 packages this app from the official [Dolibarr Docker image](https://hub.docker.com/r/dolibarr/dolibarr) and makes some improvements below. The package bundles MariaDB and passes the database connection plus the initial administrator credentials through `.env` (`DOLI_*`). The image installs Dolibarr automatically on first start. @@ -34,7 +34,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 19.0.2, latest. +Supported versions: 24.0.1, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -60,7 +60,7 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. -Note: `W9_LOGIN_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. +Note: `W9_LOGIN_USER`, `W9_LOGIN_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. ### Configuration Files @@ -73,9 +73,11 @@ Configuration files live inside the image; mount a single file read-only to over - [Dolibarr Administrator Guide](https://support.websoft9.com/docs/dolibarr) by Websoft9 -- [Docker Hub image](https://hub.docker.com/r/tuxgasy/dolibarr) +- [Docker Hub image](https://hub.docker.com/r/dolibarr/dolibarr) -- [GitHub docs](https://github.com/tuxgasy/docker-dolibarr) +- [Releases](https://github.com/Dolibarr/dolibarr/releases) + +- [GitHub docs](https://github.com/Dolibarr/dolibarr-docker) - [GitHub docs](https://github.com/Dolibarr/dolibarr) diff --git a/apps/dolibarr/variables.json b/apps/dolibarr/variables.json index 3aeaa586a..102c03de0 100644 --- a/apps/dolibarr/variables.json +++ b/apps/dolibarr/variables.json @@ -3,9 +3,10 @@ "trademark": "Dolibarr", "release": true, "upstream": { - "image": "https://hub.docker.com/r/tuxgasy/dolibarr", + "image": "https://hub.docker.com/r/dolibarr/dolibarr", + "releases": "https://github.com/Dolibarr/dolibarr/releases", "docs": [ - "https://github.com/tuxgasy/docker-dolibarr", + "https://github.com/Dolibarr/dolibarr-docker", "https://github.com/Dolibarr/dolibarr" ] }, @@ -13,7 +14,7 @@ { "dist": "community", "version": [ - "19.0.2", + "24.0.1", "latest" ] } @@ -35,6 +36,7 @@ }, "env": { "first_startup_only": [ + "W9_LOGIN_USER", "W9_LOGIN_PASSWORD" ] }, diff --git a/apps/drupal/CHANGELOG.md b/apps/drupal/CHANGELOG.md index 370f936f1..a6909ef58 100644 --- a/apps/drupal/CHANGELOG.md +++ b/apps/drupal/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-13 + +- Confirmed the Drupal package stays on the stable `11.4-apache` image line while upstream Drupal 11 latest stable is `11.4.9`. +- Fixed version metadata drift so `variables.json` matches the shipped image tag and generated documentation. + ## 2026-09-30 - Updated Drupal from `11.2.2-apache` to `11.4-apache`. diff --git a/apps/drupal/README.md b/apps/drupal/README.md index 18f8d2d37..37e3f4956 100644 --- a/apps/drupal/README.md +++ b/apps/drupal/README.md @@ -33,7 +33,9 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 11.4-apache, 11.2.2-apache, 10.3.2-apache. +Supported versions: 11.4-apache, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. ### Ports diff --git a/apps/drupal/variables.json b/apps/drupal/variables.json index 8e408b3cc..8deabab45 100644 --- a/apps/drupal/variables.json +++ b/apps/drupal/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "11.4", + "11.4-apache", "latest" ] } diff --git a/apps/elasticsearch/.env b/apps/elasticsearch/.env index 594f5d7eb..24de9bee1 100644 --- a/apps/elasticsearch/.env +++ b/apps/elasticsearch/.env @@ -1,16 +1,15 @@ -W9_VERSION='9.1.0' +W9_VERSION='9.5.5' W9_DIST='community' W9_REPO=docker.elastic.co/elasticsearch/elasticsearch W9_POWER_PASSWORD='GfQ8YNvW!7s8QbvV' #### -- Not allowed to edit below environments when recreate app based on existing data -- #### W9_ID='elasticsearch' -W9_HTTPS_PORT=9200 -W9_HTTPS_PORT_SET='9200' +W9_HTTP_PORT=9200 +W9_HTTP_PORT_SET='9200' # This environment can not set, it constant value W9_LOGIN_USER=elastic W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} -W9_LOGIN_GET_Kibaba_TOKEN="Reset it by container command [/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana]" W9_URL='' W9_NETWORK=websoft9 #### --------------------------------------------------------------------------------------- #### diff --git a/apps/elasticsearch/CHANGELOG.md b/apps/elasticsearch/CHANGELOG.md index e4d0070a3..43bbf249e 100644 --- a/apps/elasticsearch/CHANGELOG.md +++ b/apps/elasticsearch/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGELOG +## 2026-10-13 +- Updated Elasticsearch community to `9.5.5` (full patch tag, since upstream publishes no `9.5` alias). +- Corrected the access scheme to `http`: the official image serves the REST API as plain HTTP on `9200` (TLS is terminated by the platform), so declaring `https` made the platform expose a broken HTTPS URL. +- Renamed the port variables from `W9_HTTPS_PORT`/`W9_HTTPS_PORT_SET` to `W9_HTTP_PORT`/`W9_HTTP_PORT_SET` to match the actual transport. +- Removed the meaningless `W9_LOGIN_GET_Kibaba_TOKEN` variable and its i18n entry. +- Updated the app test to probe cluster health over HTTP. +- Regenerated the README. + ## 2026-09-12 - Replaced the legacy `W9_LOGIN_GET_PASSWORD` usage with the literal `W9_LOGIN_PASSWORD`, because Elasticsearch already controls the initial password directly from `ELASTIC_PASSWORD`. - Normalized `.env` variable references to the braced `${VAR}` form. diff --git a/apps/elasticsearch/README.md b/apps/elasticsearch/README.md index 9d46ded49..1f2f73273 100644 --- a/apps/elasticsearch/README.md +++ b/apps/elasticsearch/README.md @@ -33,7 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 9.1.0. +Supported versions: 9.5.5. ### Ports diff --git a/apps/elasticsearch/docker-compose.yml b/apps/elasticsearch/docker-compose.yml index db3a754e2..67f4e3b43 100644 --- a/apps/elasticsearch/docker-compose.yml +++ b/apps/elasticsearch/docker-compose.yml @@ -21,7 +21,7 @@ services: volumes: - elasticsearch:/usr/share/elasticsearch/data ports: - - ${W9_HTTPS_PORT_SET}:9200 # api + - ${W9_HTTP_PORT_SET}:9200 # api #- 9300:9300 # cluster env_file: .env diff --git a/apps/elasticsearch/tests/cases.yml b/apps/elasticsearch/tests/cases.yml new file mode 100644 index 000000000..15a66b065 --- /dev/null +++ b/apps/elasticsearch/tests/cases.yml @@ -0,0 +1,7 @@ +# The Elasticsearch API is served over plain HTTP on W9_HTTP_PORT_SET; the +# platform terminates TLS in front of it. Besides the adaptive web-access check, +# verify the cluster is actually healthy with an authenticated HTTP call. +custom: + - id: cluster-health + type: script + script: check.sh diff --git a/apps/elasticsearch/tests/check.sh b/apps/elasticsearch/tests/check.sh new file mode 100755 index 000000000..9aefc9e47 --- /dev/null +++ b/apps/elasticsearch/tests/check.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Elasticsearch first boot can take over a minute, and custom cases are not +# auto-retried by the harness, so poll the cluster health endpoint here. +# The API is plain HTTP with basic auth; TLS is terminated by the platform. +set -u + +port="${W9_HTTP_PORT_SET:-9200}" +user="${W9_LOGIN_USER:-elastic}" +pass="${W9_LOGIN_PASSWORD:-${W9_POWER_PASSWORD:-}}" + +code="" +for _ in $(seq 1 30); do + code="$(curl -s -o /dev/null -w '%{http_code}' -u "${user}:${pass}" "http://localhost:${port}/_cluster/health" 2>/dev/null || true)" + if [ "${code}" = "200" ]; then + echo "elasticsearch cluster health ok" + exit 0 + fi + sleep 5 +done + +echo "elasticsearch cluster health returned HTTP ${code}" >&2 +exit 1 diff --git a/apps/elasticsearch/variables.json b/apps/elasticsearch/variables.json index 6b1d42afd..ae836b5da 100644 --- a/apps/elasticsearch/variables.json +++ b/apps/elasticsearch/variables.json @@ -6,12 +6,12 @@ { "dist": "community", "version": [ - "9.1.0" + "9.5.5" ] } ], "access": { - "defaultScheme": "https", + "defaultScheme": "http", "api": { "port": 9200, "path": "/" diff --git a/apps/ffmpeg/.env b/apps/ffmpeg/.env index d6c646cb5..782229718 100644 --- a/apps/ffmpeg/.env +++ b/apps/ffmpeg/.env @@ -1,6 +1,6 @@ W9_REPO=linuxserver/ffmpeg W9_DIST=community -W9_VERSION=9.0-cli-ls78 +W9_VERSION=9.0-cli-ls84 #### -- Not allowed to edit below environments when recreate app based on existing data -- #### diff --git a/apps/ffmpeg/CHANGELOG.md b/apps/ffmpeg/CHANGELOG.md new file mode 100644 index 000000000..f2386c8fd --- /dev/null +++ b/apps/ffmpeg/CHANGELOG.md @@ -0,0 +1,7 @@ +# CHANGELOG + +## 2026-10-13 + +- Added this changelog for the FFmpeg package. +- Updated FFmpeg (linuxserver build) from `9.0-cli-ls78` to `9.0-cli-ls84`, keeping the `9.0-cli-ls` release-number convention. +- No compose, port, or volume changes were required. diff --git a/apps/ffmpeg/README.md b/apps/ffmpeg/README.md index e675d01b7..670abeeae 100644 --- a/apps/ffmpeg/README.md +++ b/apps/ffmpeg/README.md @@ -1,45 +1,85 @@ -# FFmpeg on Docker +# FFmpeg on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for FFmpeg: +## Quick Start - - community: 9.0, latest +### Deploy Verification -## About +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **FFmpeg**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. -FFmpeg is a CPU-friendly media toolkit for offline batch jobs on a Linux server: + +### Usage -- Suits: remux/container conversion, audio processing, probing, thumbnails, subtitles, short/low-res transcoding, media library normalization -- Not for: real-time multi-stream transcoding or 4K re-encoding without a GPU +1. Make sure you are signed in to the FFmpeg admin console. +2. Try a core feature. -The container stays alive as a toolbox; run one-shot jobs with `exec` or `run`. +### Change Password -## System Requirements +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -The following are the minimal [recommended requirements](https://ffmpeg.org/documentation.html): +## Configuration Reference -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +Websoft9 packages this app from the official [FFmpeg Docker image](https://hub.docker.com/r/linuxserver/ffmpeg) and makes some improvements below. -## Install + -You can install this FFmpeg by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). + -If you want use FFmpeg with **Websoft9 Business Support** free, you can [subscribe FFmpeg](https://www.websoft9.com/apps) on Cloud platform +Apps run as containers; rebuild after any configuration change. -## Usage +### Version Support -```bash -docker compose up -d # start the live toolbox -docker compose exec ffmpeg "ffmpeg -version" # check version -docker compose exec ffmpeg "ffmpeg -i /media/in.mov /media/out.mp4" # remux -docker compose exec ffmpeg "ffmpeg -i /media/in.mp4 -vf fps=1/10 /media/thumb%03d.jpg" # thumbnails -docker compose run --rm ffmpeg "ffprobe -v error -show_format /media/in.mp4" # one-shot probe -``` +Supported versions: 9.0-cli-ls84, latest. -Put source files under the `media` volume or mount your own path. +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. -## Documentation -[FFmpeg Administrator Guide](https://support.websoft9.com/docs/ffmpeg) powered by Websoft9 +### Ports + +| Purpose | Port | +| --- | --- | + + +### Data Directory + + +Data is persisted in the `media` volume, mounted at `/media`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [FFmpeg Administrator Guide](https://support.websoft9.com/docs/ffmpeg) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/linuxserver/ffmpeg) + +- [Releases](https://github.com/FFmpeg/FFmpeg) + +- [Official docs](https://ffmpeg.org/documentation.html) + +- [Official docs](https://ffmpeg.org/download.html#releases) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/ffmpeg/tests/cases.yml b/apps/ffmpeg/tests/cases.yml new file mode 100644 index 000000000..7b618165d --- /dev/null +++ b/apps/ffmpeg/tests/cases.yml @@ -0,0 +1,4 @@ +# FFmpeg is a toolbox container with no network service exposed. +# The adaptive checks cover its functional path (compose-config, container-up). +# Add cases here only if a future package exposes an HTTP endpoint or a +# remote-runnable script path. diff --git a/apps/ffmpeg/variables.json b/apps/ffmpeg/variables.json index 78d2b793f..4c069eee7 100644 --- a/apps/ffmpeg/variables.json +++ b/apps/ffmpeg/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "9.0-cli-ls78", + "9.0-cli-ls84", "latest" ] } diff --git a/apps/geoserver/.env b/apps/geoserver/.env index ba9938c35..5d4b2626e 100644 --- a/apps/geoserver/.env +++ b/apps/geoserver/.env @@ -1,49 +1,56 @@ -W9_REPO="wordpress" +W9_REPO=docker.osgeo.org/geoserver W9_DIST=community -W9_VERSION="latest" +W9_VERSION=3.0.x +# Password seed for the built-in GeoServer administrator account. W9_POWER_PASSWORD="1PrMxExC45LsCT" -# Environments which for user settings when create application -# Named expression: W9_xxx_xxx_SET, xxx refer to file fields -W9_HTTP_PORT_SET=9001 -# W9_HTTPS_PORT_SET=9002 -# W9_DB_PORT_SET=3306 -# W9_SSH_PORT_SET=23 -W9_KEY_SET="dfsjdkjf77xjxcjcj" +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### W9_ID=geoserver -# W9_HTTP_PORT or W9_HTTPS_PORT is need at leaset and used for proxy for web application -# Some container (e.g teleport) need HTTPS access, then need to set this pra -W9_HTTP_PORT=80 -W9_HTTPS_PORT=81 +W9_HTTP_PORT=8080 +W9_HTTP_PORT_SET=9001 +# Built-in login and URL helpers: keep these in the protected block because the appstore parser +# reads them from the app package metadata surface. W9_LOGIN_USER=admin -# use https://1password.com/zh-cn/password-generator/ to genarate 14 bit password -# this password can also use password file -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_ADMIN_PATH="/wp-login" - -# Container name's suffix must use one of the value -W9_DB_EXPOSE="mysql,postgresql,mariadb,mongodb,redis" - -# It is used when the application APP needs to set an external URL, which can be IP(or domain), IP:PORT -# If have protocols, should be set it in the APP's ENV -W9_URL=example.youdomain.com -# modifies W9_URL on init when it is true +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +W9_ADMIN_PATH="/geoserver/web" +# Use a domain-style placeholder for W9_URL, e.g. appname.example.com or example.youdomain.com. +# Do NOT use internet_ip:${W9_HTTP_PORT_SET}; host substitution is the consumer's concern. +W9_URL=appname.example.com W9_URL_REPLACE=true W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### - -# Below environment is created by this app - -WORDPRESS_DB_HOST=$W9_ID-mariadb -WORDPRESS_DB_USER=wordpress #if use postgresql, it need set to postgres -WORDPRESS_DB_PASSWORD=$W9_POWER_PASSWORD -WORDPRESS_DB_NAME=wordpress \ No newline at end of file +# ============================================================ +# GeoServer image environment variables +# Docs: https://docs.geoserver.org/latest/en/user/installation/docker.html +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +GEOSERVER_ADMIN_USER=${W9_LOGIN_USER} +GEOSERVER_ADMIN_PASSWORD=${W9_LOGIN_PASSWORD} +# Keep the bundled demo data so the web UI and OGC services are usable on first start. +SKIP_DEMO_DATA=false +# Redirect "/" to the GeoServer web interface. +ROOT_WEBAPP_REDIRECT=true +# Public base URL used for generated links when the app sits behind a proxy. +PROXY_BASE_URL=http://${W9_URL}/geoserver +EXTRA_JAVA_OPTS="-Xms512m -Xmx1g" + +# Not used by default; enable only when needed: +# INSTALL_EXTENSIONS=true +# STABLE_EXTENSIONS=wps,ysld +# CORS_ENABLED=true +# POSTGRES_JNDI_ENABLED=true +# RUN_UNPRIVILEGED=true diff --git a/apps/geoserver/CHANGELOG.md b/apps/geoserver/CHANGELOG.md index 582cf46c5..b721f9941 100644 --- a/apps/geoserver/CHANGELOG.md +++ b/apps/geoserver/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-13 +- Rebuilt the package as a standalone GeoServer deployment. The previous package was a WordPress + MariaDB stack mislabeled as GeoServer (`.env`/`docker-compose.yml` carried `WORDPRESS_*` variables and the compose mounted a missing `./src/php_exra.ini`), and `src/` shipped an unrelated GeoServer Cloud microservice stack. +- Switched to the official OSGeo image `docker.osgeo.org/geoserver`, tracked on the rolling `3.0.x` tag. +- Rewrote `.env` for GeoServer: image identity, `W9_HTTP_PORT(_SET)`, built-in `admin` login backed by `W9_POWER_PASSWORD`, `W9_URL`/`W9_URL_REPLACE`, and the GeoServer image variables actually used (`GEOSERVER_ADMIN_USER`, `GEOSERVER_ADMIN_PASSWORD`, `SKIP_DEMO_DATA`, `ROOT_WEBAPP_REDIRECT`, `PROXY_BASE_URL`, `EXTRA_JAVA_OPTS`). +- Rewrote `docker-compose.yml` to a single GeoServer service with a persistent `geoserver_data` volume mounted at `/opt/geoserver_data` and a container healthcheck. +- Removed the unrelated `src/` GeoServer Cloud stack and the missing `php_exra.ini` mount. +- Rebuilt `variables.json` with correct access paths (`/geoserver/web`), requirements, upstream sources, and declarative admin credentials; set `release` to `true` now that the package is deployable. +- Added `tests/cases.yml` covering the web login page and WMS GetCapabilities. +- Regenerated `README.md`. diff --git a/apps/geoserver/Notes.md b/apps/geoserver/Notes.md index 0e0109f4b..a2c4c3d0a 100644 --- a/apps/geoserver/Notes.md +++ b/apps/geoserver/Notes.md @@ -1,3 +1,8 @@ # GeoServer -未测试 \ No newline at end of file +- Image: `docker.osgeo.org/geoserver` (official OSGeo image), tracked on `3.0.x`. +- Web UI: `http://:/geoserver/web` (default internal port `8080`, context `/geoserver`). +- Login: built-in administrator account `admin` with the password from `W9_POWER_PASSWORD` (`W9_LOGIN_PASSWORD`). +- Data directory: the named volume `geoserver_data` is mounted at `/opt/geoserver_data`; back it up before upgrading. +- Demo data is kept enabled (`SKIP_DEMO_DATA=false`) so the web UI and OGC services work immediately. +- `PROXY_BASE_URL` is wired to `${W9_URL}` for deployments behind a reverse proxy; set `W9_URL` to the public host when `W9_URL_REPLACE` is not applied automatically. diff --git a/apps/geoserver/README.md b/apps/geoserver/README.md index ccf13d87e..a902cbe3a 100644 --- a/apps/geoserver/README.md +++ b/apps/geoserver/README.md @@ -1,26 +1,86 @@ -# GeoServer on Docker +# GeoServer on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for GeoServer: +## Quick Start +### Deploy Verification - - community: latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **GeoServer**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the GeoServer admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://github.com/geoserver/geoserver-cloud): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this GeoServer by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [GeoServer Docker image](docker.osgeo.org/geoserver) and makes some improvements below. -If you want use GeoServer with **Websoft9 Business Support** free, you can [subscribe GeoServer](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[GeoServer Administrator Guide](https://support.websoft9.com/docs/geoserver) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 3.0.x, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web UI and OGC services | 8080 | + + +### Data Directory + + +Data is persisted in the `geoserver_data` volume, mounted at `/opt/geoserver_data`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [GeoServer Administrator Guide](https://support.websoft9.com/docs/geoserver) by Websoft9 + +- [Docker Hub image](docker.osgeo.org/geoserver) + +- [Releases](https://geoserver.org/download/) + +- [Official docs](https://docs.geoserver.org/latest/en/user/installation/docker.html) + +- [GitHub docs](https://github.com/geoserver/docker) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/geoserver/docker-compose.yml b/apps/geoserver/docker-compose.yml index e7b2296b4..557bf8578 100644 --- a/apps/geoserver/docker-compose.yml +++ b/apps/geoserver/docker-compose.yml @@ -1,50 +1,24 @@ -# image,docs: https://hub.docker.com/_/wordpress/ - services: - - wordpress: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + geoserver: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} restart: unless-stopped - #This is for access host from container - # extra_hosts: ["host.docker.internal:host-gateway"] - # command: | - # /bin/bash -c "ping -c 3 host.docker.internal" - logging: - driver: "json-file" - options: - max-file: "5" - max-size: 10m - deploy: - resources: - limits: - memory: 5g - cpus: '0.7' ports: - - $W9_HTTP_PORT_SET:80 + - "${W9_HTTP_PORT_SET}:8080" # Web UI and OGC services env_file: .env volumes: - - wordpress:/var/www/html - - ./src/php_exra.ini:/usr/local/etc/php/conf.d/php_exra.ini - - mariadb: - image: mariadb:10.4 - container_name: $W9_ID-mariadb - restart: unless-stopped - command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_log_buffer_size=30M - volumes: - - mysql_data:/var/lib/mysql - environment: - MYSQL_DATABASE: $WORDPRESS_DB_NAME - MYSQL_USER: $WORDPRESS_DB_USER - MYSQL_PASSWORD: $W9_POWER_PASSWORD - MYSQL_ROOT_PASSWORD: $W9_POWER_PASSWORD + - geoserver_data:/opt/geoserver_data + healthcheck: + test: ["CMD-SHELL", "curl --fail --url \"$$(cat $$CATALINA_HOME/conf/healthcheck_url.txt)\" || exit 1"] + interval: 30s + timeout: 20s + retries: 5 + start_period: 60s volumes: - wordpress: - mysql_data: - + geoserver_data: + networks: default: - name: $W9_NETWORK - external: true \ No newline at end of file + name: ${W9_NETWORK} + external: true diff --git a/apps/geoserver/src/config/README.md b/apps/geoserver/src/config/README.md deleted file mode 100644 index 42e728eef..000000000 --- a/apps/geoserver/src/config/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Cloud Native GeoServer Externalized configuration sample repository - -This repository contains sample/default spring configuration files for all -micro-services in the [Cloud Native GeoServer](https://github.com/geoserver/geoserver-cloud) project, as used by the `config-service`, following -[spring-cloud-config](https://cloud.spring.io/spring-cloud-config/reference/html/) guidelines. - diff --git a/apps/geoserver/src/config/application.yml b/apps/geoserver/src/config/application.yml deleted file mode 100644 index 3e05ceac3..000000000 --- a/apps/geoserver/src/config/application.yml +++ /dev/null @@ -1,181 +0,0 @@ -server: - tomcat: - # Maximum number of connections that the server accepts and processes at any given time. - # Once the limit has been reached, the operating system may still accept connections based on the "acceptCount" property. - max-connections: 1000 # default: 8192 - # Maximum queue length for incoming connection requests when all possible request processing threads are in use. - accept-count: 100 # default: 100 - accesslog: - enabled: false - directory: logs - encoding: UTF-8 - threads: - # Minimum amount of worker threads. - min-spare: 2 #default: 10 - # Maximum amount of worker threads. - max: 20 #defaul: 200 - -# Common configuration for all services. Override or add service specific config -# properties on each -service.yml file -geoserver: - security.enabled: true - servlet.filter.session-debug.enabled: false # until the NPE is fixed - catalog: - advertised: true - localWorkspace: true - secure: true - # enable caching if using the catalog-service as backend - caching.enabled: ${geoserver.backend.catalog-service.enabled} - bus: - # whether to send distributed events (i.e. acts as master). All instances receive remote events. - send-events: true - # whether to send the object (CatalogInfo/config info) as payload with the event. Set to false, - # not all possible payload types are properly tested, and full object payload is not needed. - send-object: ${geoserver.backend.data-directory.enabled} - # whether to send a diff of changes as payload with the event. Set to false, not all possible payload types are properly tested nor needed. - send-diff: ${geoserver.backend.data-directory.enabled} - backend: - # configure catalog backends and decide which backend to use on this service. - # All backends are disabled, enable the required one on each service. For example, the catalog microservice - # will enable one backend type, and the front services the catalog-service backend. - # revisit: Could be split into profiles - catalog-service: - enabled: ${backend.catalog:false} - # Base URI of the catalog service. If not set, will be automatically determined using the discovery service, looking for "catalog-service" - # This allows to explicitly set a fixed location for the catalog service. - # uri: http://catalog:8080 - cache-directory: ${java.io.tmpdir}/cngs/catalog-client/resource_store - fallback-resource-directory: ${java.io.tmpdir}/cngs/catalog-client/fallback_resource_store - data-directory: - enabled: ${backend.data-directory:false} - location: ${GEOSERVER_DATA_DIR:${java.io.tmpdir}/cngs/data_directory} - jdbcconfig: - enabled: ${backend.jdbcconfig:false} - initdb: false - web.enabled: false - cache-directory: ${jdbcconfig.cachedir:${java.io.tmpdir}/cngs/jdbcconfig/cache} - datasource: - jdbcUrl: ${jdbcconfig.url:"jdbc:postgresql://database:5432/geoserver_config"} - username: ${jdbcconfig.username:geoserver} - password: ${jdbcconfig.password:geo5erver} - driverClassname: ${jdbcconfig.driverClassname:org.postgresql.Driver} - # optional: - schema: ${jdbcconfig.schema:public} - minimumIdle: ${jdbcconfig.minConnections:2} - maximumPoolSize: ${jdbcconfig.maxConnections:8} - -management: - endpoints: - enabled-by-default: true - web.exposure.include: "*" - endpoint: - info.enabled: true - metrics.enabled: true - shutdown.enabled: true - health: - enabled: true - show-details: always - metrics: - binders: - processor.enabled: true - uptime.enabled: true - jvm.enabled: true - enable.all: true - enable.jvm: true - export: - atlas.enabled: false - -spring: - rabbitmq: - host: ${RABBITMQ_HOST:localhost} - port: ${RABBITMQ_PORT:5672} - username: ${RABBITMQ_URSER:guest} - password: ${RABBITMQ_PASSWORD:guest} - cloud: - bus: - enabled: true - id: ${server.instance-id} # use the same instance id for eureka (see service's' bootstrap.yml) and cloud-bus' rabbitmq instance id - trace.enabled: false #switch on tracing of acks (default off). - stream: - bindings: - springCloudBusOutput: - destination: gscatalog - springCloudBusInput: - destination: gscatalog - jackson: - default-property-inclusion: non_empty - serialization.indent_output: false #set to true if doing manual testing and want formatted output - -reactive.feign.cloud.enabled: true -reactive.feign.hystrix.enabled: false - -logging: - level: - root: WARN - org.springframework: ERROR - org.springframework.cloud.bus: INFO - org.springframework.retry: INFO - # geoserver roots - org.geoserver: INFO - org.geoserver.catalog.plugin: INFO - org.geoserver.wms: WARN #don't flood the logs with every request details - org.geoserver.wfs: WARN - org.geoserver.jackson: INFO - org.geotools.jackson: INFO - org.geoserver.platform: ERROR - org.geoserver.jdbcconfig: INFO - oshi.hardware.platform.linux: ERROR - oshi.software.os: ERROR - # gs-cloud roots - org.geoserver.cloud: INFO - org.geoserver.cloud.autoconfigure: INFO - org.geoserver.cloud.config.factory: INFO - # bus debugging - org.geoserver.cloud.bus: INFO - org.springframework.cloud.bus.BusAutoConfiguration: INFO - org.springframework.cloud.bus.DefaultBusPathMatcher: INFO - # reactivefeign: - reactivefeign.client.log: INFO - org.springframework.cloud.config.server.environment.NativeEnvironmentRepository: WARN - ---- -spring.profiles: local -# provide environment variables that otherwise would be given by docker-compose.yml -jdbcconfig.url: jdbc:postgresql://localhost:5432/geoserver_config -jdbcconfig.username: geoserver -jdbcconfig.password: geo5erver ---- -spring.profiles: datadir -geoserver: - backend: - data-directory: - enabled: true - location: ${GEOSERVER_DATA_DIR:${java.io.tmpdir}/cngs/default_data_directory} - ---- -spring.profiles: debug - -logging: - level: - root: WARN - org.springframework: INFO - # geoserver roots - org.geoserver: INFO - org.geoserver.catalog.plugin: DEBUG - org.geoserver.wms: WARN - org.geoserver.wfs: WARN - org.geoserver.jackson: DEBUG - org.geotools.jackson: DEBUG - org.geoserver.platform: ERROR - org.geoserver.jdbcconfig: INFO - # gs-cloud roots - org.geoserver.cloud: DEBUG - org.geoserver.cloud.autoconfigure: DEBUG - org.geoserver.cloud.config.factory: DEBUG - # bus debugging - org.geoserver.cloud.bus: TRACE - org.springframework.cloud.bus: DEBUG - org.springframework.cloud.bus.BusAutoConfiguration: DEBUG - org.springframework.cloud.bus.DefaultBusPathMatcher: INFO - # reactivefeign: - reactivefeign.client.log: DEBUG diff --git a/apps/geoserver/src/config/catalog-service.yml b/apps/geoserver/src/config/catalog-service.yml deleted file mode 100644 index 72fd89873..000000000 --- a/apps/geoserver/src/config/catalog-service.yml +++ /dev/null @@ -1,33 +0,0 @@ -geoserver: - security.enabled: false - # Disable advertised catalog, it checks the org.geoserver.ows.Dispatcher.REQUEST to check if an OWS is in progress, - # which can never be the case, and causes a java.lang.NoClassDefFoundError on org.springframework.web.servlet.mvc.AbstractController - catalog: - advertised: false - # Disable LocalWorkspaceCatalog decorator, this service exposes a "raw catalog" backend, there's no concept of local workspaces - localWorkspace: false - secure: false - # enable caching while using the jdbcconfig backend, we've disabled its own internal caching due to concurrency related bugs - caching.enabled: ${geoserver.backend.jdbcconfig.enabled} - catalog-service: - io-threads: - # Number of back-end threads to hit the actual catalog with. Defaults 4 * number of cores if unset. - # If using jdbcconfig, let io-threads be about half the size of geoserver.backend.jdbcconfig.datasource.maximumPoolSize, - # it has the tendency to use more than one jdbc connection for some requests. - max-size: ${catalog.io.threads:8} - # maximum number of queued requests per worker thread before rejecting new requests - max-queued: ${catalog.io.maxQueued:10000} - bus: - # receive events but don't publish, it's the front catalogs that publish events to better track where the changes come from - send-events: false - backend: - # decide which catalog backend to use on this service, default to using jdbcconfig - jdbcconfig.enabled: ${backend.jdbcconfig:true} - -#spring: -# error.includeStacktrace: on_trace_param -# jackson.serialization.WRAP_ROOT_VALUE: false - ---- -spring.profiles: local -server.port: 9100 diff --git a/apps/geoserver/src/config/config-service.yml b/apps/geoserver/src/config/config-service.yml deleted file mode 100644 index e167c0bc9..000000000 --- a/apps/geoserver/src/config/config-service.yml +++ /dev/null @@ -1,9 +0,0 @@ -spring: - profiles: - active: native #use native filesystem config by default instead of git. REVISIT. - config.server.native.searchLocations: ${config.path:file:./config} - -logging: - level: - root: WARN - org.springframework.cloud.config.server.environment.NativeEnvironmentRepository: WARN \ No newline at end of file diff --git a/apps/geoserver/src/config/gateway-service.yml b/apps/geoserver/src/config/gateway-service.yml deleted file mode 100644 index 45878a0f9..000000000 --- a/apps/geoserver/src/config/gateway-service.yml +++ /dev/null @@ -1,83 +0,0 @@ -server: - compression: - enabled: true -# Configure routes to services. See https://cloud.spring.io/spring-cloud-gateway/single/spring-cloud-gateway.html - -management: - endpoint.gateway.enabled: true # default value - endpoints: - enabled-by-default: true - web.exposure.include: "*" - #web.exposure.include: gateway, info, health - -spring: - cloud: - gateway: - actuator: - verbose: - enabled: true - routes: - - id: catalog - uri: lb://catalog-service - predicates: - - Path=/api/v1/** - filters: # Expose the catalog and configuration API only if the dev profile is active - - RouteProfile=dev,403 -# WFS routes - - id: wfs # proxies requests to gateway-service:/wfs to wfs-service:/wfs - uri: lb://wfs-service #load balanced to the wfs-service instances - predicates: - - Path=/wfs,/{segment}/wfs,/schemas/wfs/** -# proxy [/{workspace}]/ows?SERVICE=wfs to wfs-service:[/{workspace}]/ows?SERVICE=wfs. Param value is case insensitive, name is not. - - id: wfs_ows - uri: lb://wfs-service - predicates: - - Path=/ows,/{segment}/ows - - RegExpQuery=(?i:service),(?i:wfs) # match service=wfs case insensitively -# WMS routes - - id: wms # proxies requests to gateway-service:/wms to wms-service:/wms - uri: lb://wms-service #load balanced to the wms-service instances - predicates: - - Path=/wms,/{segment}/wms,/schemas/wms/**,/openlayers/**,/openlayers3/** - - id: wms_ows # proxy [/{workspace}]/ows?SERVICE=wms to wms-service:[/{workspace}]/ows?SERVICE=wms. Param value is case insensitive, name is not. - uri: lb://wms-service - predicates: - - Path=/ows,/{segment}/ows - - RegExpQuery=(?i:service),(?i:wms) # match service=wms case insensitively -# WCS routes - - id: wcs # proxies requests to gateway-service:/wcs to wcs-service:/wcs - uri: lb://wcs-service #load balanced to the wps-service instances - predicates: - - Path=/wcs,/{segment}/wcs,/schemas/wcs/** - - id: wcs_ows # proxy [/{workspace}]/ows?SERVICE=wcs to wcs-service:[/{workspace}]/ows?SERVICE=wcs. Param value is case insensitive, name is not. - uri: lb://wcs-service - predicates: - - Path=/ows,/{segment}/ows - - RegExpQuery=(?i:service),(?i:wcs) # match service=wcs case insensitively -# WPS routes - - id: wps # proxies requests to gateway-service:/wps to wfs-service:/wps - uri: lb://wps-service #load balanced to the wps-service instances - predicates: - - Path=/wps,/{segment}/wps,/schemas/wps/** - - id: wps_ows # proxy [/{workspace}]/ows?SERVICE=wps to wps-service:[/{workspace}]/ows?SERVICE=wps. Param value is case insensitive, name is not. - uri: lb://wps-service - predicates: - - Path=/ows,/{segment}/ows - - RegExpQuery=(?i:service),(?i:wps) # match service=wps case insensitively -# REST configuration routes - - id: restconfig - uri: lb://restconfig-v1 #load balanced to the restconfig-v1 instances - predicates: - - Path=/rest/** -# Web UI configuration routes - - id: restconfig - uri: lb://web-ui - predicates: - - Path=/,/index.html,/web,/web/**,/j_spring_security_check,/j_spring_security_logout - -logging: - level: - root: WARN - com.netflix.discovery: WARN - com.netflix.eureka: WARN - diff --git a/apps/geoserver/src/config/restconfig-v1.yml b/apps/geoserver/src/config/restconfig-v1.yml deleted file mode 100644 index 40eb2ec1c..000000000 --- a/apps/geoserver/src/config/restconfig-v1.yml +++ /dev/null @@ -1,5 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} ---- -spring.profiles: local -server.port: 9105 diff --git a/apps/geoserver/src/config/wcs-service.yml b/apps/geoserver/src/config/wcs-service.yml deleted file mode 100644 index 0ba695255..000000000 --- a/apps/geoserver/src/config/wcs-service.yml +++ /dev/null @@ -1,6 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} ---- -spring.profiles: local -server.port: 9103 - \ No newline at end of file diff --git a/apps/geoserver/src/config/web-ui.yml b/apps/geoserver/src/config/web-ui.yml deleted file mode 100644 index 6f4049df9..000000000 --- a/apps/geoserver/src/config/web-ui.yml +++ /dev/null @@ -1,33 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} - web-ui: - file-browser.hide-file-system: true - # These are all default values, here just for reference. You can omit them and add only the ones to disable or further configure - security.enabled: true - wfs.enabled: true - wms.enabled: true - wcs.enabled: true - wps.enabled: false # not working yet - gwc.enabled: false # not ready yet - extensions: - importer.enabled: true - demos: - enabled: true - wps-request-builder: true - wcs-request-builder: true - demo-requests: true - srs-list: true - reprojection-console: true - layer-preview-page: - enabled: true - common-formats: - open-layers: true - gml: true - kml: false #kml links are broken - tools: - enabled: true - resource-browser: true - catalog-bulk-load: true ---- -spring.profiles: local -server.port: 9106 diff --git a/apps/geoserver/src/config/wfs-service.yml b/apps/geoserver/src/config/wfs-service.yml deleted file mode 100644 index adf6ff15e..000000000 --- a/apps/geoserver/src/config/wfs-service.yml +++ /dev/null @@ -1,6 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} ---- -spring.profiles: local -server.port: 9101 - \ No newline at end of file diff --git a/apps/geoserver/src/config/wms-service.yml b/apps/geoserver/src/config/wms-service.yml deleted file mode 100644 index 8332d4f5e..000000000 --- a/apps/geoserver/src/config/wms-service.yml +++ /dev/null @@ -1,5 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} ---- -spring.profiles: local -server.port: 9102 diff --git a/apps/geoserver/src/config/wps-service.yml b/apps/geoserver/src/config/wps-service.yml deleted file mode 100644 index 5c4059be0..000000000 --- a/apps/geoserver/src/config/wps-service.yml +++ /dev/null @@ -1,5 +0,0 @@ -geoserver: - backend.catalog-service.enabled: ${backend.catalog:true} ---- -spring.profiles: local -server.port: 9104 diff --git a/apps/geoserver/src/docker-compose.yml b/apps/geoserver/src/docker-compose.yml deleted file mode 100644 index 45a4b51e5..000000000 --- a/apps/geoserver/src/docker-compose.yml +++ /dev/null @@ -1,248 +0,0 @@ -version: "3.8" - -volumes: - postgresql_config_data: # volume for postgresql data, used to store the geoserver config through jdbcconfig - rabbitmq_data: # volume for rabbitmq data, so it doesn't create an anonymous one on each container - -networks: - gs-cloud-network: -# driver: bridge - -services: - rabbitmq: - image: rabbitmq:3.9-management - restart: always - volumes: - - rabbitmq_data:/var/lib/rabbitmq - networks: - - gs-cloud-network - ports: - - "5672:5672" - - "15672:15672" - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - - database: - image: geoservercloud/geoserver-cloud-postgres-jdbcconfig:${TAG} - environment: - POSTGRES_DB: "${JDBCCONFIG_DBNAME}" - POSTGRES_USER: "${JDBCCONFIG_USERNAME}" - POSTGRES_PASSWORD: "${JDBCCONFIG_PASSWORD}" - ports: - - 5432:5432 - networks: - - gs-cloud-network - volumes: - - postgresql_config_data:/var/lib/postgresql/data - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - - # Eureka service discovery. This is a Discovery First Bootstrap configuration. - # The discovery service is the only fixed entry point. - # Browse to http://localhost:8761 to check all services are registered. - # Run docker-compose -f docker-compose.yml -f docker-compose-discovery-ha.yml to run extra discovery service instances for HA - discovery: - image: geoservercloud/geoserver-cloud-discovery:${TAG} - environment: - SERVER_PORT: 8761 - EUREKA_INSTANCE_HOSTNAME: discovery - JAVA_OPTS: "${DISCOVERY_JAVA_OPTS}" - ports: - - 8761:8761 # for development, so services can be run from localhost and find the discovery service running on docker - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '2.0' - memory: 512M - - # Spring Cloud Config service, provides centralized configuration to all - # microservices. Being a Discovery First Bootstrap configuration, it'll - # register itself with the Eureka discovery service and can be scaled - config: - image: geoservercloud/geoserver-cloud-config:${TAG} - depends_on: - - discovery - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${CONFIG_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - # Either 'git' or 'native'. Use the default sample git repository to download the services configuration from - # If 'git', BEWARE config server will look for a branch called "master", and github changed the default branch name to "main" - # For more information, see https://cloud.spring.io/spring-cloud-config/multi/multi__spring_cloud_config_server.html#_git_backend - SPRING_PROFILES_ACTIVE: native - # 'git' profile config - CONFIG_GIT_URI: https://github.com/groldan/geoserver-cloud-config - CONFIG_GIT_BASEDIR: /opt/app/git_config - # 'native' profile config - CONFIG_NATIVE_PATH: /opt/app/config - networks: - - gs-cloud-network - volumes: - - ./config:/opt/app/config - deploy: - resources: - limits: - cpus: '2.0' - memory: 512M - - # Application facade, provides a single entry point routing to all - # microservices (e.g. http://localhost:9090/geoserver/wms, http://localhost:9090/geoserver/wfs, etc) - gateway: - image: geoservercloud/geoserver-cloud-gateway:${TAG} - depends_on: - - discovery - - config - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: ${GATEWAY_JAVA_OPTS} - SPRING_PROFILES_ACTIVE: dev #exposes the catalog and config API at /api/v1/** - ports: - - 9090:8080 - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '4.0' - memory: 1G - - # catalog microservice, provides a unified catalog backend to all services - catalog: - image: geoservercloud/geoserver-cloud-catalog:${TAG} - depends_on: - - discovery - - config - - database - - rabbitmq - environment: - # Force the max RAM (-XX:MaxRAM) seen by the JVM in case --compatibility wasn't used to launch the composition - JAVA_OPTS: "${CATALOG_JAVA_OPTS}" - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - RABBITMQ_HOST: rabbitmq - CATALOG_IO_THREADS: 8 - CATALOG_IO_MAX_QUEUED: 10000 - BACKEND_JDBCCONFIG: "true" - JDBCCONFIG_URL: "${JDBCCONFIG_URL}" - JDBCCONFIG_USERNAME: "${JDBCCONFIG_USERNAME}" - JDBCCONFIG_PASSWORD: "${JDBCCONFIG_PASSWORD}" - JDBCCONFIG_MIN_CONNECTIONS: 2 - JDBCCONFIG_MAX_CONNECTIONS: 16 # 2 x CATALOG_IO_THREADS - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - - # WFS microservice, port dynamically allocated to allow scaling (e.g docker-compose scale wfs=5) - wfs: - image: geoservercloud/geoserver-cloud-wfs:${TAG} - depends_on: - - catalog - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${WFS_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - networks: - - gs-cloud-network - #tmpfs: #TODO: avoid runs creating volumes at all - # - /tmp - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - - # WMS microservice, port dynamically allocated to allow scaling (e.g docker-compose scale wms=5) - wms: - image: geoservercloud/geoserver-cloud-wms:${TAG} - depends_on: - - catalog - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${WMS_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - - # WCS microservice, port dynamically allocated to allow scaling (e.g docker-compose scale wcs=5) - wcs: - image: geoservercloud/geoserver-cloud-wcs:${TAG} - depends_on: - - catalog - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${WCS_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G - -# # WPS microservice, port dynamically allocated to allow scaling (e.g docker-compose scale wps=5) -# wps: -# image: geoservercloud/geoserver-cloud-wps:${TAG} -# depends_on: -# - rabbitmq -# - catalog -# environment: -# EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} -# JAVA_OPTS: ${WPS_JAVA_OPTS} -# RABBITMQ_HOST: rabbitmq -# networks: -# - gs-cloud-network - - # REST config microservice, port dynamically allocated to allow scaling (e.g docker-compose scale rest=5) - rest: - image: geoservercloud/geoserver-cloud-rest:${TAG} - depends_on: - - rabbitmq - - catalog - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${REST_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - networks: - - gs-cloud-network - deploy: - mode: replicated - replicas: 1 - resources: - limits: - cpus: '1.5' - memory: 1G - - # WEB UI microservice - webui: - image: geoservercloud/geoserver-cloud-webui:${TAG} - depends_on: - - rabbitmq - - catalog - environment: - EUREKA_SERVER_URL: ${EUREKA_SERVER_URL} - JAVA_OPTS: "${WEBUI_JAVA_OPTS}" - RABBITMQ_HOST: rabbitmq - networks: - - gs-cloud-network - deploy: - resources: - limits: - cpus: '2.0' - memory: 1G \ No newline at end of file diff --git a/apps/geoserver/src/filelist b/apps/geoserver/src/filelist deleted file mode 100644 index 7faa02bfc..000000000 --- a/apps/geoserver/src/filelist +++ /dev/null @@ -1,2 +0,0 @@ -config -docker-compose.yml \ No newline at end of file diff --git a/apps/geoserver/tests/cases.yml b/apps/geoserver/tests/cases.yml new file mode 100644 index 000000000..184acfeb8 --- /dev/null +++ b/apps/geoserver/tests/cases.yml @@ -0,0 +1,10 @@ +optional: + - id: web-login + type: web-access + path: /geoserver/web/ + expect_status: 200 + + - id: wms-capabilities + type: web-access + path: /geoserver/wms?service=WMS&request=GetCapabilities + expect_status: 200 diff --git a/apps/geoserver/variables.json b/apps/geoserver/variables.json index 6908b7b84..e1ef6babf 100644 --- a/apps/geoserver/variables.json +++ b/apps/geoserver/variables.json @@ -1,25 +1,51 @@ { "name": "geoserver", "trademark": "GeoServer", - "release": false, + "release": true, "edition": [ { "dist": "community", "version": [ + "3.0.x", "latest" ] } ], + "access": { + "defaultScheme": "http", + "web": { + "port": 8080, + "path": "/geoserver/web" + }, + "admin": { + "port": 8080, + "path": "/geoserver/web" + } + }, "requirements": { "cpu": "1", "memory": "2", - "disk": "1" + "disk": "2" }, - "access": { - "defaultScheme": "http", - "web": { - "port": 80, - "path": "/" + "upstream": { + "image": "docker.osgeo.org/geoserver", + "releases": "https://geoserver.org/download/", + "docs": [ + "https://docs.geoserver.org/latest/en/user/installation/docker.html", + "https://github.com/geoserver/docker" + ] + }, + "credentials": { + "username": { + "source": "inline", + "value": "admin" + }, + "password": { + "source": "container-env", + "name": "W9_LOGIN_PASSWORD" } + }, + "help": { + "login": "Log in at /geoserver/web with the built-in administrator account shown below. Change the default password from the GeoServer security settings after first login." } } diff --git a/apps/ghost/.env b/apps/ghost/.env index 3a9432b2c..c331a2f36 100644 --- a/apps/ghost/.env +++ b/apps/ghost/.env @@ -1,6 +1,6 @@ W9_REPO=ghost W9_DIST=community -W9_VERSION=6.65 +W9_VERSION=6.69 W9_POWER_PASSWORD="upxOisMYI5V!0UXx" #### -- Not allowed to edit below environments when recreate app based on existing data -- #### diff --git a/apps/ghost/CHANGELOG.md b/apps/ghost/CHANGELOG.md index a56b58810..4fcc451fa 100644 --- a/apps/ghost/CHANGELOG.md +++ b/apps/ghost/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-13 +- Updated Ghost community to 6.69. +- Regenerated the README. + ## 2026-09-29 - Update Ghost community to 6.65. diff --git a/apps/ghost/Notes.md b/apps/ghost/Notes.md deleted file mode 100644 index 760d5649d..000000000 --- a/apps/ghost/Notes.md +++ /dev/null @@ -1,9 +0,0 @@ -# Ghost - -## FAQ - -#### 环境变量 URL 的作用域? - -1. 后台 View Sites 链接 -2. 前端页面的菜单链接 - diff --git a/apps/ghost/README.md b/apps/ghost/README.md index e9eab051d..90ef08a23 100644 --- a/apps/ghost/README.md +++ b/apps/ghost/README.md @@ -38,7 +38,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 6.65, latest. +Supported versions: 6.69, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/ghost/variables.json b/apps/ghost/variables.json index 625f3e948..26f0580b7 100644 --- a/apps/ghost/variables.json +++ b/apps/ghost/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "6.65", + "6.69", "latest" ] } diff --git a/apps/gitea/.env b/apps/gitea/.env index a666bcdbd..b8da7994f 100644 --- a/apps/gitea/.env +++ b/apps/gitea/.env @@ -1,6 +1,6 @@ W9_REPO=gitea/gitea W9_DIST=community -W9_VERSION=1.27 +W9_VERSION=28.1 # Canonical semantics live in docs/w9-env-spec.md. # This template controls layout; the spec controls meaning and decision rules. diff --git a/apps/gitea/CHANGELOG.md b/apps/gitea/CHANGELOG.md index 3b6f5b1fa..03638354e 100644 --- a/apps/gitea/CHANGELOG.md +++ b/apps/gitea/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-13 + +- Updated Gitea from `1.27` to `28.1`; upstream renumbered from the `1.x` line to the new `28.x` scheme and `28.1` is the current stable `x.x` tag. +- Back up the data volume and let Gitea run its automatic database migration on first start; do not roll back the image after the migration. +- Regenerated `README.md` from the updated version metadata. + ## 2026-09-13 - Updated Gitea from `1.25` to `1.27`. diff --git a/apps/gitea/README.md b/apps/gitea/README.md index aec0139b9..97013596d 100644 --- a/apps/gitea/README.md +++ b/apps/gitea/README.md @@ -33,7 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 1.27, latest. +Supported versions: 28.1, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/gitea/variables.json b/apps/gitea/variables.json index 00dd93a0b..2e7cdd43e 100644 --- a/apps/gitea/variables.json +++ b/apps/gitea/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "1.27", + "28.1", "latest" ] } diff --git a/apps/gitlab/.env b/apps/gitlab/.env index ea6c87407..935fc7487 100644 --- a/apps/gitlab/.env +++ b/apps/gitlab/.env @@ -1,7 +1,7 @@ # Gitlab edition: ce, ee, jihu W9_REPO=gitlab/gitlab-ce W9_DIST=community -W9_VERSION=19.3.2-ce.0 +W9_VERSION=19.4.2-ce.0 # Optional password seed: enable only when the package actually controls a DB or built-in login. # See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. diff --git a/apps/gitlab/CHANGELOG.md b/apps/gitlab/CHANGELOG.md index a07740be6..d723c3515 100644 --- a/apps/gitlab/CHANGELOG.md +++ b/apps/gitlab/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2026-10-13 + +- Updated GitLab Community Edition from `19.3.2-ce.0` to `19.4.2-ce.0`. +- The `19.3.2` to `19.4.2` path crosses no required upgrade stop; the next GitLab required stop is `19.5`. +- Kept the Omnibus config, published ports, and optional `runner` profile unchanged. + ## 2026-09-10 - Updated GitLab Community Edition from `18.1.3-ce.0` to `19.3.2-ce.0` by owner request. diff --git a/apps/gitlab/README.md b/apps/gitlab/README.md index 415752650..4ec5368ff 100644 --- a/apps/gitlab/README.md +++ b/apps/gitlab/README.md @@ -29,7 +29,7 @@ Websoft9 packages this app from the official [Gitlab Docker image](https://hub.d This package uses the official single-container GitLab Docker deployment and keeps PostgreSQL inside the GitLab Omnibus container. -GitLab official upgrade guidance requires stepped upgrade stops across `18.2`, `18.5`, `18.8`, `18.11`, and `19.2` before later `19.x` versions. This package update to `19.3.2-ce.0` was applied by explicit owner direction and should be treated as a high-risk data upgrade for existing installations. +GitLab official upgrade guidance requires stepped upgrade stops across `18.2`, `18.5`, `18.8`, `18.11`, and `19.2` before later `19.x` versions. This package update to `19.4.2-ce.0` was applied by explicit owner direction and should be treated as a high-risk data upgrade for existing installations. For browser access and generated clone URLs to stay correct, set `W9_URL` to the real externally used host or host:port before the first container startup. @@ -40,7 +40,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 19.3.2-ce.0, latest. +Supported versions: 19.4.2-ce.0, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/gitlab/tests/cases.yml b/apps/gitlab/tests/cases.yml new file mode 100644 index 000000000..64453977e --- /dev/null +++ b/apps/gitlab/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: login-page + type: web-access + path: /users/sign_in + expect_status: 200 diff --git a/apps/gitlab/variables.json b/apps/gitlab/variables.json index d68545937..8bfa31ba3 100644 --- a/apps/gitlab/variables.json +++ b/apps/gitlab/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "19.3.2-ce.0", + "19.4.2-ce.0", "latest" ] } diff --git a/apps/gocd/.env b/apps/gocd/.env index b991934e9..07aa6f5de 100644 --- a/apps/gocd/.env +++ b/apps/gocd/.env @@ -1,5 +1,5 @@ W9_DIST='community' -W9_VERSION='v25.3.0' +W9_VERSION='v26.1.0' W9_REPO=gocd/gocd-server #### -- Not allowed to edit below environments when recreate app based on existing data -- #### diff --git a/apps/gocd/CHANGELOG.md b/apps/gocd/CHANGELOG.md index 582cf46c5..3190bffb2 100644 --- a/apps/gocd/CHANGELOG.md +++ b/apps/gocd/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-13 + +- Updated GoCD server and agent from `v25.3.0` to `v26.1.0`. +- GoCD publishes only `vX.Y.0` tags, so `v26.1.0` is the correct stable target. +- Server and agent images stay aligned through the shared `W9_VERSION` variable. + ## Release ### Fixes and Enhancements diff --git a/apps/gocd/README.md b/apps/gocd/README.md index 1dec3a82e..087bd2814 100644 --- a/apps/gocd/README.md +++ b/apps/gocd/README.md @@ -1,26 +1,80 @@ -# GoCD on Docker +# GoCD on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for GoCD: +## Quick Start +### Deploy Verification - - community: v25.2.0 +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **GoCD**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the GoCD admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.gocd.org): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this GoCD by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [GoCD Docker image](https://hub.docker.com/r/gocd/gocd-server) and makes some improvements below. -If you want use GoCD with **Websoft9 Business Support** free, you can [subscribe GoCD](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[GoCD Administrator Guide](https://support.websoft9.com/docs/gocd) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v26.1.0. + + +### Ports + +| Purpose | Port | +| --- | --- | +| W9_HTTP_PORT_SET | 8153 | + + +### Data Directory + + +- `gocd-server-data` → `/godata` +- `gocd-agent-data` → `/godata` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [GoCD Administrator Guide](https://support.websoft9.com/docs/gocd) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/gocd/gocd-server) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/gocd/tests/cases.yml b/apps/gocd/tests/cases.yml new file mode 100644 index 000000000..3c88a39b0 --- /dev/null +++ b/apps/gocd/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: server-health + type: web-access + path: /go/api/v1/health + expect_status: 200 diff --git a/apps/gocd/variables.json b/apps/gocd/variables.json index 8dbd2707a..357ef7b22 100644 --- a/apps/gocd/variables.json +++ b/apps/gocd/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "v25.3.0" + "v26.1.0" ] } ], diff --git a/apps/grafana/.env b/apps/grafana/.env index 9239d8cc1..df5531377 100644 --- a/apps/grafana/.env +++ b/apps/grafana/.env @@ -1,5 +1,6 @@ # latest is not stable, sometime is 9.x,sometime is 8.x -W9_VERSION='12.1.1' +W9_REPO=grafana/grafana +W9_VERSION='13.2' W9_POWER_PASSWORD='5PidNEsE5!D314t0' #### -- Not allowed to edit below environments when recreate app based on existing data -- #### @@ -7,7 +8,7 @@ W9_ID='grafana' W9_HTTP_PORT_SET='9001' W9_HTTP_PORT=3000 W9_LOGIN_USER=admin -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} W9_URL='appname.example.com' W9_NETWORK=websoft9 #### --------------------------------------------------------------------------------------- #### @@ -15,7 +16,9 @@ W9_NETWORK=websoft9 # You can use any environment from grafana.ini. format: GF__ # refer to: https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#variable-expansion -GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource +# Grafana 13.x deprecated GF_INSTALL_PLUGINS (silently ignored unless GF_INSTALL_PLUGINS_FORCE=true). +# Use GF_PLUGINS_PREINSTALL instead. +GF_PLUGINS_PREINSTALL=grafana-clock-panel,grafana-simple-json-datasource GF_LOG_MODE=console file GF_SECURITY_ADMIN_USER=${W9_LOGIN_USER} GF_SECURITY_ADMIN_PASSWORD=${W9_POWER_PASSWORD} diff --git a/apps/grafana/CHANGELOG.md b/apps/grafana/CHANGELOG.md index ec3a0bc7c..4bfca062b 100644 --- a/apps/grafana/CHANGELOG.md +++ b/apps/grafana/CHANGELOG.md @@ -1,4 +1,11 @@ # CHANGELOG +## 2026-10-13 + +- Upgraded Grafana to `13.2`. +- Migrated the deprecated `GF_INSTALL_PLUGINS` to `GF_PLUGINS_PREINSTALL`; Grafana 13.x silently ignores `GF_INSTALL_PLUGINS` unless `GF_INSTALL_PLUGINS_FORCE=true`. +- Standardized the main image reference to `${W9_REPO}:${W9_VERSION}` and removed the leading docs/dockerfile/dockerhub source comments. +- Note: upstream removed the `grafana-server` and `grafana-cli` binaries, and the unified-storage migration caveat applies when upgrading an existing instance. + ## Release ### Fixes and Enhancements diff --git a/apps/grafana/README.md b/apps/grafana/README.md index 567308212..3cfa4b856 100644 --- a/apps/grafana/README.md +++ b/apps/grafana/README.md @@ -1,26 +1,86 @@ -# Grafana on Docker +# Grafana on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Grafana: +## Quick Start +### Deploy Verification - - community: 12.0.2, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Grafana**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Grafana admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://grafana.com/docs/grafana/latest/installation/requirements/#grafana-requirements): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 2 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Grafana by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Grafana Docker image](https://hub.docker.com/r/grafana/grafana) and makes some improvements below. -If you want use Grafana with **Websoft9 Business Support** free, you can [subscribe Grafana](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Grafana Administrator Guide](https://support.websoft9.com/docs/grafana) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 13.2, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web console | 3000 | + + +### Data Directory + + +- `data` → `/var/lib/grafana` +- `config` → `/etc/grafana` +- `logs` → `/var/log/grafana` +- `plugins` → `/var/lib/grafana/plugins` +- `loki_data` → `/loki` +- `promtail_log` → `/var/log` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Grafana Administrator Guide](https://support.websoft9.com/docs/grafana) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/grafana/grafana) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/grafana/docker-compose.yml b/apps/grafana/docker-compose.yml index 11febfedd..ea51c1ae8 100644 --- a/apps/grafana/docker-compose.yml +++ b/apps/grafana/docker-compose.yml @@ -1,18 +1,11 @@ -# docs: https://grafana.com/docs/grafana/latest/installation/docker/ -# dockerfile: https://github.com/grafana/grafana/blob/main/Dockerfile -# dockerhub: https://hub.docker.com/r/grafana/grafana -# mysql db for grafana meta storage - -version: '3.8' - services: grafana: - image: grafana/grafana-oss:${W9_VERSION} + image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID} restart: unless-stopped ports: - - ${W9_HTTP_PORT_SET}:3000 + - ${W9_HTTP_PORT_SET}:3000 # Web console volumes: - data:/var/lib/grafana - config:/etc/grafana diff --git a/apps/grafana/src/get_version.sh b/apps/grafana/src/get_version.sh index 3a730a8d7..bbd49f073 100644 --- a/apps/grafana/src/get_version.sh +++ b/apps/grafana/src/get_version.sh @@ -1 +1 @@ -sudo echo $(docker exec -i grafana grafana-cli -v) 1 >> /data/logs/install_version.txt +sudo echo $(docker exec -i grafana grafana --version) 1 >> /data/logs/install_version.txt diff --git a/apps/grafana/tests/cases.yml b/apps/grafana/tests/cases.yml new file mode 100644 index 000000000..49c6f9d57 --- /dev/null +++ b/apps/grafana/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: grafana-health + type: web-access + path: /api/health + expect_status: 200 diff --git a/apps/grafana/variables.json b/apps/grafana/variables.json index 7a4f5c46f..ec4e90b3c 100644 --- a/apps/grafana/variables.json +++ b/apps/grafana/variables.json @@ -9,7 +9,7 @@ { "dist": "community", "version": [ - "12.1.1", + "13.2", "latest" ] } diff --git a/apps/graylog/.env b/apps/graylog/.env index f767f7a12..3676e1f37 100644 --- a/apps/graylog/.env +++ b/apps/graylog/.env @@ -3,7 +3,7 @@ # 2. echo -n "Enter Password: " && head -1 &2 - exit 1 - ;; -esac - -if ! grep -Eqi 'graylog|initial configuration|sign in|login' "$body"; then - echo "response does not look like a Graylog setup or login page" >&2 - exit 1 -fi - -echo "Graylog web UI responded with HTTP ${code}" +echo "unexpected HTTP ${last} from Graylog web UI" >&2 +exit 1 diff --git a/apps/graylog/variables.json b/apps/graylog/variables.json index cdcebddde..8e32f3232 100644 --- a/apps/graylog/variables.json +++ b/apps/graylog/variables.json @@ -13,7 +13,7 @@ { "dist": "community", "version": [ - "7.1" + "7.2" ] } ], diff --git a/apps/haproxy/.env b/apps/haproxy/.env index c375d465c..93c7b5cca 100644 --- a/apps/haproxy/.env +++ b/apps/haproxy/.env @@ -1,4 +1,4 @@ -W9_VERSION='3.2' +W9_VERSION='3.4' W9_REPO=haproxy W9_DIST='community' diff --git a/apps/haproxy/CHANGELOG.md b/apps/haproxy/CHANGELOG.md index 582cf46c5..4c02b780b 100644 --- a/apps/haproxy/CHANGELOG.md +++ b/apps/haproxy/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-13 +- Updated HAProxy community to 3.4; kept the older versions in the supported list. +- Regenerated the README. + ## Release ### Fixes and Enhancements diff --git a/apps/haproxy/README.md b/apps/haproxy/README.md index f4471bd45..6bc1586fb 100644 --- a/apps/haproxy/README.md +++ b/apps/haproxy/README.md @@ -1,26 +1,78 @@ -# HAProxy on Docker +# HAProxy on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for HAProxy: +## Quick Start +### Deploy Verification - - community: 3.2, 3.1, 3.0, 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3, 2.0 +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **HAProxy**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the HAProxy admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://hub.docker.com/_/haproxy): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this HAProxy by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [HAProxy Docker image](https://hub.docker.com/_/haproxy) and makes some improvements below. -If you want use HAProxy with **Websoft9 Business Support** free, you can [subscribe HAProxy](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[HAProxy Administrator Guide](https://support.websoft9.com/docs/haproxy) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 3.4, 3.2, 3.1, 3.0, 2.9, 2.8, 2.7, 2.6, 2.5, 2.4, 2.3, 2.0. + + +### Ports + +| Purpose | Port | +| --- | --- | +| W9_HTTP_PORT_SET | 80 | + + +### Data Directory + + +Data is kept inside the container; a named volume is recommended for persistence. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/haproxy.cfg` to `/usr/local/etc/haproxy/haproxy.cfg`. + + +## References + +- [HAProxy Administrator Guide](https://support.websoft9.com/docs/haproxy) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/haproxy) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/haproxy/tests/cases.yml b/apps/haproxy/tests/cases.yml new file mode 100644 index 000000000..ced33d173 --- /dev/null +++ b/apps/haproxy/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: stats-page + type: web-access + path: /stats + expect_status: 200 diff --git a/apps/haproxy/variables.json b/apps/haproxy/variables.json index 6af17ebc6..b7e18873d 100644 --- a/apps/haproxy/variables.json +++ b/apps/haproxy/variables.json @@ -9,6 +9,7 @@ { "dist": "community", "version": [ + "3.4", "3.2", "3.1", "3.0", diff --git a/apps/hermes/.env b/apps/hermes/.env index 3cf5a12ba..4c90d7d98 100644 --- a/apps/hermes/.env +++ b/apps/hermes/.env @@ -1,6 +1,6 @@ W9_REPO=nousresearch/hermes-agent W9_DIST=community -W9_VERSION=v2026.9.14 +W9_VERSION=v2026.9.24 # Optional password seed: enable only when the package actually controls a DB or built-in login. # See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. diff --git a/apps/hermes/CHANGELOG.md b/apps/hermes/CHANGELOG.md index 3680e66d8..3902ebebf 100644 --- a/apps/hermes/CHANGELOG.md +++ b/apps/hermes/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-13 +- Updated Hermes Agent to v2026.9.24 (image `nousresearch/hermes-agent`). +- Regenerated the README. + ## 2026-09-17 - Initial package for Hermes Agent v2026.9.14 (image `nousresearch/hermes-agent`). diff --git a/apps/hermes/README.md b/apps/hermes/README.md index 545f2d9c3..17f75ff77 100644 --- a/apps/hermes/README.md +++ b/apps/hermes/README.md @@ -40,7 +40,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: v2026.9.14, latest. +Supported versions: v2026.9.24, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/hermes/variables.json b/apps/hermes/variables.json index be69dfc15..ac19d8314 100644 --- a/apps/hermes/variables.json +++ b/apps/hermes/variables.json @@ -18,7 +18,7 @@ { "dist": "community", "version": [ - "v2026.9.14", + "v2026.9.24", "latest" ] } diff --git a/apps/homeassistant/.env b/apps/homeassistant/.env index cb137f7d9..f30f32d2b 100644 --- a/apps/homeassistant/.env +++ b/apps/homeassistant/.env @@ -1,5 +1,5 @@ W9_REPO=homeassistant/home-assistant -W9_VERSION='2025.7' +W9_VERSION='2026.10' W9_DIST='community' #### -- Not allowed to edit below environments when recreate app based on existing data -- #### diff --git a/apps/homeassistant/CHANGELOG.md b/apps/homeassistant/CHANGELOG.md index 582cf46c5..15ca704ae 100644 --- a/apps/homeassistant/CHANGELOG.md +++ b/apps/homeassistant/CHANGELOG.md @@ -1,5 +1,15 @@ # CHANGELOG +## 2026-10-13 + +- Updated Home Assistant from `2025.7` to `2026.10`. +- The container now requires Docker 23 or newer and supports only 64-bit hosts. +- No environment variable or port changes are required. +- Regenerated `README.md` from the updated version metadata. +- Added `src/nginx-proxy.conf` so the Websoft9 Gateway clears the forwarded + headers that make Home Assistant return HTTP 400 on a bound domain, and keeps + the frontend WebSocket connection alive; direct port access was already fine. + ## Release ### Fixes and Enhancements diff --git a/apps/homeassistant/Notes.md b/apps/homeassistant/Notes.md index 575e88f05..085322c54 100644 --- a/apps/homeassistant/Notes.md +++ b/apps/homeassistant/Notes.md @@ -1,6 +1,20 @@ -# Home Assitant +# Home Assistant -Need add **mosquitto MQTT** and **nginx-proxy.conf** for this application +Need add **mosquitto MQTT** for this application. +`src/nginx-proxy.conf` is shipped: the gateway clears `X-Forwarded-For` / +`X-Real-IP` so Home Assistant does not reject domain requests, and forwards the +WebSocket upgrade. ## FAQ + +### Port works but a bound domain returns HTTP 400 + +Home Assistant blocks requests that carry forwarded headers unless the proxy is +a trusted proxy. Because `http:` in `configuration.yaml` is ignored since HA +2026.8, the settings live under **Settings > System > Network** (Trust +X-Forwarded-For + Trusted proxies). The shipped `src/nginx-proxy.conf` avoids the +problem by dropping those headers at the gateway. If you prefer real client IPs +and IP banning, remove the two `proxy_set_header` lines that clear +`X-Forwarded-For` / `X-Real-IP` and instead enable the trusted-proxy settings in +the UI. diff --git a/apps/homeassistant/README.md b/apps/homeassistant/README.md index 0e0fbaec3..42e2d0667 100644 --- a/apps/homeassistant/README.md +++ b/apps/homeassistant/README.md @@ -1,26 +1,82 @@ -# Home Assistant on Docker +# Home Assistant on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Home Assistant: +## Quick Start +### Deploy Verification - - community: 2025.6, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Home Assistant**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Home Assistant admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.home-assistant.io/installation/linux): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Home Assistant by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Home Assistant Docker image](https://hub.docker.com/r/homeassistant/home-assistant) and makes some improvements below. -If you want use Home Assistant with **Websoft9 Business Support** free, you can [subscribe Home Assistant](https://www.websoft9.com/apps) on Cloud platform + +The package ships `src/nginx-proxy.conf`, which the Websoft9 Gateway injects into the Proxy Host `server{}` block. It clears the forwarded headers that make Home Assistant return HTTP 400 on a bound domain (direct port access was already fine) and keeps the frontend WebSocket alive. It is not mounted into the container and is unrelated to `docker-compose.yml`. + -## Documentation +Apps run as containers; rebuild after any configuration change. -[Home Assistant Administrator Guide](https://support.websoft9.com/docs/homeassistant) powered by Websoft9 \ No newline at end of file +### Version Support + +Supported versions: 2026.10, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| W9_HTTP_PORT_SET | 8123 | + + +### Data Directory + + +- `hs_config` → `/config` +- `/etc/localtime` → `/etc/localtime` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Home Assistant Administrator Guide](https://support.websoft9.com/docs/homeassistant) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/homeassistant/home-assistant) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/homeassistant/src/nginx-proxy.conf b/apps/homeassistant/src/nginx-proxy.conf new file mode 100644 index 000000000..589dfb8ed --- /dev/null +++ b/apps/homeassistant/src/nginx-proxy.conf @@ -0,0 +1,24 @@ +# Websoft9 Gateway (Nginx Proxy Manager) advanced config. +# The platform reads this file from src/nginx-proxy.conf and injects it into the +# Proxy Host server{} block. It is NOT mounted into any container, so +# docker-compose.yml does not reference it. +# +# Home Assistant rejects every request that carries X-Forwarded-For / X-Real-IP +# unless the proxy IP is listed under trusted proxies (Settings > System > +# Network; the YAML `http:` block is ignored since 2026.8). The Websoft9 Gateway +# adds those headers, so direct port access works while a bound domain fails with +# HTTP 400. Clearing the forwarded headers here keeps Home Assistant reachable +# behind the gateway without any per-user setup; the Upgrade/Connection +# directives keep the frontend WebSocket connection alive. + +location / { + proxy_pass $forward_scheme://$server:$port$request_uri; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For ""; + proxy_set_header X-Real-IP ""; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + proxy_read_timeout 3600s; + proxy_send_timeout 3600s; +} diff --git a/apps/homeassistant/tests/cases.yml b/apps/homeassistant/tests/cases.yml new file mode 100644 index 000000000..b1c0dc4de --- /dev/null +++ b/apps/homeassistant/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: web-manifest + type: web-access + path: /manifest.json + expect_status: 200 diff --git a/apps/homeassistant/variables.json b/apps/homeassistant/variables.json index 639e32a22..d60dbf4d7 100644 --- a/apps/homeassistant/variables.json +++ b/apps/homeassistant/variables.json @@ -9,7 +9,7 @@ { "dist": "community", "version": [ - "2025.7", + "2026.10", "latest" ] } diff --git a/apps/jellyfin/.env b/apps/jellyfin/.env index 076aa2fee..d6f5d8d2b 100644 --- a/apps/jellyfin/.env +++ b/apps/jellyfin/.env @@ -1,6 +1,6 @@ W9_REPO=jellyfin/jellyfin W9_DIST='community' -W9_VERSION='10.10.7' +W9_VERSION='12.2' W9_HTTP_PORT_SET='9001' #### -- Not allowed to edit below environments when recreate app based on existing data -- #### @@ -15,4 +15,4 @@ W9_NETWORK=websoft9 # environment from this url: https://jellyfin.org/docs/general/administration/configuration # Below environment is created by Jellyfin -JELLYFIN_PublishedServerUrl=http://$W9_URL +JELLYFIN_PublishedServerUrl=http://${W9_URL} diff --git a/apps/jellyfin/CHANGELOG.md b/apps/jellyfin/CHANGELOG.md index 582cf46c5..f273f212e 100644 --- a/apps/jellyfin/CHANGELOG.md +++ b/apps/jellyfin/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## 2026-10-13 + +- Updated Jellyfin from `10.10.7` to `12.2`. +- Upstream renumbered Jellyfin releases from the `10.11.x` line to `12.x`; the first start on `12.x` runs a database/schema migration automatically. +- A full library scan is required after the upgrade to rebuild metadata and refresh library contents. +- Normalized `.env` variable references to the braced `${VAR}` form. + ## Release ### Fixes and Enhancements diff --git a/apps/jellyfin/README.md b/apps/jellyfin/README.md index ac2cfa8af..50930747d 100644 --- a/apps/jellyfin/README.md +++ b/apps/jellyfin/README.md @@ -1,26 +1,83 @@ -# Jellyfin on Docker +# Jellyfin on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Jellyfin: +## Quick Start +### Deploy Verification - - community: 10.10.7, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Jellyfin**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Jellyfin admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://jellyfin.org/docs/general/administration/hardware-selection): +### Change Password -* **RAM**: 8 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 5 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Jellyfin by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Jellyfin Docker image](https://hub.docker.com/r/jellyfin/jellyfin) and makes some improvements below. -If you want use Jellyfin with **Websoft9 Business Support** free, you can [subscribe Jellyfin](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Jellyfin Administrator Guide](https://support.websoft9.com/docs/jellyfin) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 12.2, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| W9_HTTP_PORT_SET | 8096 | + + +### Data Directory + + +- `config` → `/config` +- `cache` → `/cache` +- `media` → `/media` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Jellyfin Administrator Guide](https://support.websoft9.com/docs/jellyfin) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/jellyfin/jellyfin) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/jellyfin/tests/cases.yml b/apps/jellyfin/tests/cases.yml new file mode 100644 index 000000000..3c263165f --- /dev/null +++ b/apps/jellyfin/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: health + type: web-access + path: /health + expect_status: 200 diff --git a/apps/jellyfin/variables.json b/apps/jellyfin/variables.json index 46cdb9d68..7fbaf2907 100644 --- a/apps/jellyfin/variables.json +++ b/apps/jellyfin/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "10.10.7", + "12.2", "latest" ] } diff --git a/apps/jenkins/.env b/apps/jenkins/.env index 3c38d7cc7..827051c34 100644 --- a/apps/jenkins/.env +++ b/apps/jenkins/.env @@ -2,7 +2,7 @@ # /var/jenkins_home/secrets/initialAdminPassword inside the container. W9_REPO=jenkins/jenkins W9_DIST=community -W9_VERSION=2.581 +W9_VERSION=2.586 # Canonical semantics live in docs/w9-env-spec.md. # This template controls layout; the spec controls meaning and decision rules. diff --git a/apps/jenkins/CHANGELOG.md b/apps/jenkins/CHANGELOG.md index 32bc1b5dd..2774d5135 100644 --- a/apps/jenkins/CHANGELOG.md +++ b/apps/jenkins/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-13 +- Updated Jenkins from `2.581` to `2.586`. +- Regenerated the README. + ## 2026-09-12 - Updated Jenkins from `2.540` to `2.581`. - Normalized `.env` and `docker-compose.yml` to current repository policy rules (braced `${VAR}` references, port purpose comment, removal of the obsolete `version` and source comments). diff --git a/apps/jenkins/README.md b/apps/jenkins/README.md index a104bb2dd..19f2d6234 100644 --- a/apps/jenkins/README.md +++ b/apps/jenkins/README.md @@ -35,7 +35,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 2.581, latest. +Supported versions: 2.586, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/jenkins/tests/cases.yml b/apps/jenkins/tests/cases.yml new file mode 100644 index 000000000..98e7e5fb0 --- /dev/null +++ b/apps/jenkins/tests/cases.yml @@ -0,0 +1,5 @@ +# The adaptive checks cover Jenkins' functional path: compose-config, container-up, +# and web-access on "/" (which accepts the 403 returned before the initial admin +# password is set). The initial admin password is resolved from the container file +# declared in variables.json.credentials, not from an HTTP check. +# Add cases here only if a future package exposes a stable unauthenticated endpoint. diff --git a/apps/jenkins/variables.json b/apps/jenkins/variables.json index 8c95143cd..03d0f3db1 100644 --- a/apps/jenkins/variables.json +++ b/apps/jenkins/variables.json @@ -15,7 +15,7 @@ { "dist": "community", "version": [ - "2.581", + "2.586", "latest" ] } diff --git a/apps/jfrog/.env b/apps/jfrog/.env new file mode 100644 index 000000000..d19c0d5ca --- /dev/null +++ b/apps/jfrog/.env @@ -0,0 +1,47 @@ +W9_REPO=releases-docker.jfrog.io/jfrog/artifactory-pro +W9_DIST=community +W9_VERSION=7.161.26 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=jfrog + +# Web/internal ports: uncomment the ones the package actually uses. +W9_HTTP_PORT=8082 +W9_HTTP_PORT_SET=9001 + +# Built-in login and URL helpers: keep these in the protected block because the appstore parser +# reads them from the app package metadata surface. +# Use a domain-style placeholder for W9_URL, e.g. appname.example.com or example.youdomain.com. +# Do NOT use internet_ip:${W9_HTTP_PORT_SET}; host substitution is the consumer's concern. +W9_URL=jfrog.example.com + +W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +#W9_NAME="" +#W9_RCODE="" + +# ============================================================ +# JFrog Artifactory image environment variables +# Docs: https://www.jfrogchina.com/docs/docker-install-artifactory-1 +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +# Artifactory ships without PostgreSQL; run the bundled (embedded) Derby database. +JF_SHARED_DATABASE_TYPE=derby +JF_SHARED_DATABASE_ALLOWNONPOSTGRESQL=true + +# Not used by default; enable only when needed: +# JF_SHARED_JFROGURL=http://${W9_URL} +# JF_SHARED_NODE_ID=jfrog-node1 +# JF_SHARED_NODE_IP=127.0.0.1 +# ARTIFACTORY_EXTRA_JAVA_OPTS=-Xms1g -Xmx2g +# JF_ROUTER_ENTRYPOINTS_EXTERNALPORT=8082 diff --git a/apps/jfrog/CHANGELOG.md b/apps/jfrog/CHANGELOG.md new file mode 100644 index 000000000..e53b2d8f4 --- /dev/null +++ b/apps/jfrog/CHANGELOG.md @@ -0,0 +1,8 @@ +# CHANGELOG + +## 2026-10-13 +- Initial JFrog Artifactory community package based on the official `releases-docker.jfrog.io/jfrog/artifactory-pro` image. +- Add `docker-compose.yml` publishing the JFrog Platform console on `${W9_HTTP_PORT_SET}:8082`, with the `jfrog_data` volume at `/var/opt/jfrog/artifactory` and a `/router/api/v1/system/health` healthcheck. +- Enable the embedded Derby database via `JF_SHARED_DATABASE_TYPE=derby` and `JF_SHARED_DATABASE_ALLOWNONPOSTGRESQL=true` so no external database is required. +- Declare the built-in `admin` / `password` credentials with a first-sign-in password-change note in `help.login`. +- Fill `.env`, `variables.json`, `README.md`, and add `tests/cases.yml` with an Artifactory ping check. diff --git a/apps/jfrog/README.md b/apps/jfrog/README.md new file mode 100644 index 000000000..41219e314 --- /dev/null +++ b/apps/jfrog/README.md @@ -0,0 +1,93 @@ +# JFrog Artifactory on Docker + +## Quick Start + +### Deploy Verification + +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **JFrog Artifactory**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + + +### Usage + +1. Open the JFrog Platform URL from the **Access** tab. The first sign-in uses `admin` / `password`. +2. When prompted, set a new administrator password, then install a valid Artifactory license under **Administration → Licenses**. +3. Create repositories and users from the Platform administration UI. + +### Change Password + +1. Sign in to the JFrog Platform with the administrator account. +2. Open the account menu → **Edit Profile → Change Password**, or reset it from **Administration → User Management**. + + +## Configuration Reference + +Websoft9 packages this app from the official [JFrog Artifactory Docker image](releases-docker.jfrog.io/jfrog/artifactory-pro) and makes some improvements below. + + +- This package runs the official JFrog Artifactory Pro image and uses the bundled embedded Derby database, so no external database service is required. For production workloads JFrog recommends PostgreSQL. +- The Platform web console listens on port `8082` inside the container and is published through `W9_HTTP_PORT_SET`. +- The first sign-in uses the built-in `admin` / `password`; Artifactory forces a new administrator password on first sign-in, so changing that default here does not change the running instance. +- An Artifactory license is required after first login; without it the product runs in a limited state. +- Set the external base URL inside the UI (**Administration → General → JFrog URL / Base URL**) because the package does not configure it through environment variables. +- Artifactory can take several minutes to start on the first boot. + + +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 7.161.26. + + +### Ports + +| Purpose | Port | +| --- | --- | +| JFrog Platform web console | 8082 | + + +### Data Directory + + +Data is persisted in the `jfrog_data` volume, mounted at `/var/opt/jfrog/artifactory`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [JFrog Artifactory Administrator Guide](https://support.websoft9.com/docs/jfrog) by Websoft9 + +- [Docker Hub image](releases-docker.jfrog.io/jfrog/artifactory-pro) + +- [Official docs](https://www.jfrogchina.com/docs/docker-install-artifactory-1) + +- [GitHub docs](https://github.com/jfrog/artifactory-docker-examples) + + + +## Troubleshooting + +**App takes long to start?** +- Artifactory bootstraps its database and keys on first start; allow a few minutes and check `docker compose logs`. + +**Login rejected?** +- Use the initial `admin` / `password`, or the password you set on first sign-in. + +**License prompt blocks usage?** +- Install a valid Artifactory license under **Administration → Licenses**. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/jfrog/docker-compose.yml b/apps/jfrog/docker-compose.yml new file mode 100644 index 000000000..89766f6fd --- /dev/null +++ b/apps/jfrog/docker-compose.yml @@ -0,0 +1,25 @@ +services: + + jfrog: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + restart: unless-stopped + env_file: .env + ports: + - "${W9_HTTP_PORT_SET}:8082" # JFrog Platform web console + volumes: + - jfrog_data:/var/opt/jfrog/artifactory + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8082/router/api/v1/system/health || exit 1"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 300s + +volumes: + jfrog_data: + +networks: + default: + name: ${W9_NETWORK} + external: true diff --git a/apps/bigbluebutton/src/conf/dialplan_public/.gitkeep b/apps/jfrog/src/.gitkeep similarity index 100% rename from apps/bigbluebutton/src/conf/dialplan_public/.gitkeep rename to apps/jfrog/src/.gitkeep diff --git a/apps/jfrog/tests/cases.yml b/apps/jfrog/tests/cases.yml new file mode 100644 index 000000000..7db01f42f --- /dev/null +++ b/apps/jfrog/tests/cases.yml @@ -0,0 +1,8 @@ +# The default adaptive checks already cover compose-config, container-up, +# container-healthy (the packaged router healthcheck), and the web root path. +# Add an app-specific check for the public Artifactory ping endpoint. +optional: + - id: artifactory-ping + type: web-access + path: /artifactory/api/system/ping + expect_status: 200 diff --git a/apps/jfrog/variables.json b/apps/jfrog/variables.json new file mode 100644 index 000000000..649c2163f --- /dev/null +++ b/apps/jfrog/variables.json @@ -0,0 +1,46 @@ +{ + "name": "jfrog", + "trademark": "JFrog Artifactory", + "release": false, + "upstream": { + "image": "releases-docker.jfrog.io/jfrog/artifactory-pro", + "docs": [ + "https://www.jfrogchina.com/docs/docker-install-artifactory-1", + "https://github.com/jfrog/artifactory-docker-examples" + ] + }, + "edition": [ + { + "dist": "community", + "version": ["7.161.26"] + } + ], + "access": { + "defaultScheme": "http", + "web": { + "port": 8082, + "path": "/" + } + }, + "requirements": { + "cpu": "2", + "memory": "4", + "disk": "20" + }, + "credentials": { + "username": { + "source": "inline", + "value": "admin" + }, + "password": { + "source": "inline", + "value": "password" + } + }, + "env": { + "first_startup_only": [] + }, + "help": { + "login": "First login uses the built-in admin / password. JFrog Artifactory forces a new administrator password on first sign-in, after which the initial password no longer works. A valid Artifactory license is required to use the product." + } +} diff --git a/apps/jihu/.env b/apps/jihu/.env index 8f73200c1..ddd3f22e0 100644 --- a/apps/jihu/.env +++ b/apps/jihu/.env @@ -1,6 +1,6 @@ W9_REPO=registry.gitlab.cn/omnibus/gitlab-jh W9_DIST=community -W9_VERSION=19.3.2 +W9_VERSION=19.4.1 W9_POWER_PASSWORD="uQ8E1wVTzG8SOk3!" # Canonical semantics live in docs/w9-env-spec.md. diff --git a/apps/jihu/CHANGELOG.md b/apps/jihu/CHANGELOG.md index b510e6449..cbaab47b8 100644 --- a/apps/jihu/CHANGELOG.md +++ b/apps/jihu/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-13 + +- Updated JiHu GitLab to `19.4.1`. +- Minor in-place upgrades are supported; no packaging changes were required. + ## 2026-09-15 - Pinned JiHu GitLab from the floating `latest` tag to `19.3.2`. diff --git a/apps/jihu/README.md b/apps/jihu/README.md index c3d827b4f..2a49d44ce 100644 --- a/apps/jihu/README.md +++ b/apps/jihu/README.md @@ -36,7 +36,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 19.3.2, latest. +Supported versions: 19.4.1, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/jihu/variables.json b/apps/jihu/variables.json index 80d05bf11..956398b0b 100644 --- a/apps/jihu/variables.json +++ b/apps/jihu/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "19.3.2", + "19.4.1", "latest" ] } diff --git a/apps/keycloak/.env b/apps/keycloak/.env index a51b0838b..cd1b70aec 100644 --- a/apps/keycloak/.env +++ b/apps/keycloak/.env @@ -1,17 +1,38 @@ W9_REPO=keycloak/keycloak -W9_DIST='community' -W9_VERSION='26.4' -W9_HTTP_PORT_SET='9001' -W9_POWER_PASSWORD='O06ddT1DY!PXTHHQ' +W9_DIST=community +W9_VERSION=26.8 + +# Optional password seed: enable only when the package actually controls a DB or built-in login. +# See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. +W9_POWER_PASSWORD=O06ddT1DY!PXTHHQ + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='keycloak' + +W9_ID=keycloak W9_HTTP_PORT=8080 +W9_HTTP_PORT_SET=9001 W9_LOGIN_USER=admin -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_URL='example.youdomain.com' +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +W9_URL=example.youdomain.com W9_NETWORK=websoft9 -####Below environment is created by : https://www.keycloak.org/getting-started/getting-started-docker #### -KC_BOOTSTRAP_ADMIN_USERNAME=$W9_LOGIN_USER -KC_BOOTSTRAP_ADMIN_PASSWORD=$W9_LOGIN_PASSWORD +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Keycloak image environment variables +# Docs: https://www.keycloak.org/getting-started/getting-started-docker +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +KC_BOOTSTRAP_ADMIN_USERNAME=${W9_LOGIN_USER} +KC_BOOTSTRAP_ADMIN_PASSWORD=${W9_LOGIN_PASSWORD} + +# Not used by default; enable only when needed: +# KC_HOSTNAME=${W9_URL} +# KC_PROXY_HEADERS=xforwarded diff --git a/apps/keycloak/CHANGELOG.md b/apps/keycloak/CHANGELOG.md new file mode 100644 index 000000000..cc5aeed11 --- /dev/null +++ b/apps/keycloak/CHANGELOG.md @@ -0,0 +1,7 @@ +# CHANGELOG + +## 2026-10-12 + +- Updated Keycloak from `26.4` to `26.8`. +- Normalized `.env` and `docker-compose.yml` to current repository conventions, including braced variable references and inline port purpose comments. +- Added `tests/cases.yml` to cover the admin console path for automated validation. diff --git a/apps/keycloak/README.md b/apps/keycloak/README.md index cfc4bfce1..e05c2ac10 100644 --- a/apps/keycloak/README.md +++ b/apps/keycloak/README.md @@ -1,26 +1,80 @@ -# Keycloak on Docker +# Keycloak on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Keycloak: +## Quick Start +### Deploy Verification - - community: 26.2, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Keycloak**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Keycloak admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.keycloak.org): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Keycloak by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Keycloak Docker image](https://hub.docker.com/r/keycloak/keycloak) and makes some improvements below. -If you want use Keycloak with **Websoft9 Business Support** free, you can [subscribe Keycloak](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Keycloak Administrator Guide](https://support.websoft9.com/docs/keycloak) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 26.8, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 8080 | + + +### Data Directory + + +Data is persisted in the `keycloak_data` volume, mounted at `/opt/keycloak/data`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Keycloak Administrator Guide](https://support.websoft9.com/docs/keycloak) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/keycloak/keycloak) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/keycloak/docker-compose.yml b/apps/keycloak/docker-compose.yml index db31e9907..95db081bf 100644 --- a/apps/keycloak/docker-compose.yml +++ b/apps/keycloak/docker-compose.yml @@ -1,13 +1,10 @@ -# image: https://hub.docker.com/r/keycloak/keycloak -# docs: https://www.keycloak.org/getting-started/getting-started-docker - services: - keycloak: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + restart: unless-stopped ports: - - $W9_HTTP_PORT_SET:8080 + - "${W9_HTTP_PORT_SET}:8080" # Web Console env_file: .env command: start-dev volumes: @@ -18,5 +15,5 @@ volumes: networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/keycloak/tests/cases.yml b/apps/keycloak/tests/cases.yml new file mode 100644 index 000000000..a0f236440 --- /dev/null +++ b/apps/keycloak/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: admin-console + type: web-access + path: /admin/ + expect_status: 200 diff --git a/apps/keycloak/variables.json b/apps/keycloak/variables.json index 789ebb737..253b68f13 100644 --- a/apps/keycloak/variables.json +++ b/apps/keycloak/variables.json @@ -9,7 +9,7 @@ { "dist": "community", "version": [ - "26.4", + "26.8", "latest" ] } diff --git a/apps/kibana/.env b/apps/kibana/.env index f64be3eac..022f5522b 100644 --- a/apps/kibana/.env +++ b/apps/kibana/.env @@ -1,20 +1,31 @@ -# version must the same with Elasticsearch -W9_VERSION=8.12.2 -W9_DIST=community W9_REPO=docker.elastic.co/kibana/kibana +W9_DIST=community +W9_VERSION=9.5.5 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### +W9_ID=kibana W9_HTTP_PORT=5601 W9_HTTP_PORT_SET=9001 W9_URL=appname.example.com W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### -## Kibaba configurations can change to environment, e.g: SERVER_NAME <-> server.name -## refer to: https://www.elastic.co/guide/en/kibana/current/docker.html#environment-variable-config -## configures: https://www.elastic.co/guide/en/kibana/current/settings.html +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Kibana image environment variables +# Docs: https://www.elastic.co/docs/deploy-manage/deploy/self-managed/install-kibana-with-docker +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +SERVER_HOST=0.0.0.0 -SERVER_HOST="0.0.0.0" -#ELASTICSEARCH_HOSTS='["http://{elastcisearch-host}:{port}"]' -#ELASTICSEARCH_SERVICEACCOUNTTOKEN={elastcisearch-serviceaccounttoken} \ No newline at end of file +# Not used by default; enable only when needed: +# ELASTICSEARCH_HOSTS=["http://elasticsearch:9200"] +# ELASTICSEARCH_SERVICEACCOUNTTOKEN=replace-with-service-account-token diff --git a/apps/kibana/CHANGELOG.md b/apps/kibana/CHANGELOG.md index 582cf46c5..92c50c276 100644 --- a/apps/kibana/CHANGELOG.md +++ b/apps/kibana/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 +- Updated Kibana from `8.12.2` to `9.5.5` because the Elastic registry does not publish a usable `9.5` tag for this image. +- Normalized `.env` and `docker-compose.yml` to current repository conventions, including braced variable references and inline port purpose comments. +- Added upstream docs metadata and an app-specific admin UI test case. diff --git a/apps/kibana/README.md b/apps/kibana/README.md index fe144ef4b..d1da85cd8 100644 --- a/apps/kibana/README.md +++ b/apps/kibana/README.md @@ -1,26 +1,82 @@ -# Kibana on Docker +# Kibana on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Kibana: +## Quick Start +### Deploy Verification - - community: 8.12.2 +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Kibana**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Kibana admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://hub.docker.com/_/kibana): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 5 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Kibana by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Kibana Docker image](https://hub.docker.com/_/kibana) and makes some improvements below. -If you want use Kibana with **Websoft9 Business Support** free, you can [subscribe Kibana](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Kibana Administrator Guide](https://support.websoft9.com/docs/kibana) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 9.5.5. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 5601 | + + +### Data Directory + + +Data is kept inside the container; a named volume is recommended for persistence. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Kibana Administrator Guide](https://support.websoft9.com/docs/kibana) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/kibana) + +- [Official docs](https://www.elastic.co/docs/deploy-manage/deploy/self-managed/install-kibana-with-docker) + +- [Official docs](https://www.elastic.co/docs/release-notes/kibana) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/kibana/docker-compose.yml b/apps/kibana/docker-compose.yml index 944197a84..261807e9a 100644 --- a/apps/kibana/docker-compose.yml +++ b/apps/kibana/docker-compose.yml @@ -1,19 +1,13 @@ -# image https://www.docker.elastic.co/r/kibana -# docs: https://www.elastic.co/guide/en/kibana/current/docker.html - -version: '3.8' - services: - kibana: image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID} restart: unless-stopped ports: - - ${W9_HTTP_PORT_SET}:5601 + - "${W9_HTTP_PORT_SET}:5601" # Web Console env_file: .env networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/kibana/tests/cases.yml b/apps/kibana/tests/cases.yml new file mode 100644 index 000000000..809f7c014 --- /dev/null +++ b/apps/kibana/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: login-page + type: web-access + path: /login + expect_status: 200 diff --git a/apps/kibana/variables.json b/apps/kibana/variables.json index e03cdfba3..77aafa171 100644 --- a/apps/kibana/variables.json +++ b/apps/kibana/variables.json @@ -3,13 +3,17 @@ "trademark": "Kibana", "release": true, "upstream": { - "image": "https://www.docker.elastic.co/r/kibana" + "image": "https://hub.docker.com/_/kibana", + "docs": [ + "https://www.elastic.co/docs/deploy-manage/deploy/self-managed/install-kibana-with-docker", + "https://www.elastic.co/docs/release-notes/kibana" + ] }, "edition": [ { "dist": "community", "version": [ - "8.12.2" + "9.5.5" ] } ], diff --git a/apps/kong/.env b/apps/kong/.env index bed03e3f9..94fee9bb4 100644 --- a/apps/kong/.env +++ b/apps/kong/.env @@ -1,47 +1,58 @@ -W9_POWER_PASSWORD='Xk3kABV7Z!3snr5r' -W9_VERSION='3.9' -W9_DIST='community' W9_REPO=kong +W9_DIST=community +W9_VERSION=3.9 -#### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='kong' -W9_DB_EXPOSE="postgresql" -W9_DB_VERSION="13" +W9_POWER_PASSWORD='Xk3kABV7Z!3snr5r' -W9_HTTP_PORT=8000 -W9_HTTP_PORT_SET='8010' +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. -# both IP or domain access, this port need enable at security group -W9_ADMIN_API_PORT_SET='8011' -W9_ADMIN_GUI_PORT_SET='8012' +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### -# admin gui access by: http://IP:W9_ADMIN_GUI_PORT_SET/admin or http://domain/admin -W9_ADMIN_PATH="/admin" -W9_URL='kong.test.websoft9.cn' +W9_ID=kong +W9_HTTP_PORT=8000 +W9_HTTP_PORT_SET=8010 +W9_DB_EXPOSE=postgresql +W9_DB_VERSION=13 +W9_URL=kong.example.com W9_URL_REPLACE=true - +W9_ADMIN_PATH=/admin W9_NETWORK=websoft9 -#### --Kong official environments-- #### +# Additional Kong entrypoints exposed by this package. +W9_ADMIN_API_PORT_SET=8011 +W9_ADMIN_GUI_PORT_SET=8012 + +#### ----------------------------------------------------------------------------------------- #### -## Environment can changed from configs, e.g: log_level <-> KONG_LOG_LEVEL -## refer to: https://docs.konghq.com/gateway/latest/production/environment-variables/ +# ============================================================ +# Kong Gateway (OSS) image environment variables +# Docs: https://docs.konghq.com/gateway/latest/production/environment-variables/ +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ +# Used by docker-compose.yml: +KONG_DATABASE=postgres KONG_PG_DATABASE=kong KONG_PG_HOST=${W9_ID}-postgresql KONG_PG_USER=kong KONG_PG_PASSWORD=${W9_POWER_PASSWORD} - KONG_PROXY_LISTEN=0.0.0.0:8000 -# It must use 8001 +# Expose the Admin API because this package also publishes it on W9_ADMIN_API_PORT_SET. KONG_ADMIN_LISTEN=0.0.0.0:8001 KONG_ADMIN_GUI_LISTEN=0.0.0.0:8002 -KONG_ADMIN_GUI_PATH=/admin +KONG_ADMIN_GUI_PATH=${W9_ADMIN_PATH} KONG_ADMIN_GUI_API_URL=http://${W9_URL}:${W9_ADMIN_API_PORT_SET} - KONG_PROXY_ACCESS_LOG=/dev/stdout KONG_ADMIN_ACCESS_LOG=/dev/stdout KONG_PROXY_ERROR_LOG=/dev/stderr KONG_ADMIN_ERROR_LOG=/dev/stderr KONG_PREFIX=/tmp/ -KONG_DECLARATIVE_CONFIG="/opt/kong/kong.yaml" +KONG_DECLARATIVE_CONFIG=/opt/kong/kong.yaml + +# Not used by default; enable only when needed: +# KONG_LOG_LEVEL=notice +# KONG_STATUS_LISTEN=0.0.0.0:8100 +# KONG_PLUGINS=bundled diff --git a/apps/kong/CHANGELOG.md b/apps/kong/CHANGELOG.md index 596aa9daf..5a32cf1ac 100644 --- a/apps/kong/CHANGELOG.md +++ b/apps/kong/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-12 + +- Moved Kong upstream references from `docker-compose.yml` comments into `variables.json > upstream` and refreshed `.env` to the current template layout. +- Corrected `variables.json.access` so the primary browser entry is Kong Manager on port 8002 at `/admin`, while the proxy and Admin API remain documented as separate surfaces. +- Made `kong-migrations-up` use an explicit shell command so `kong migrations finish` is not dropped by YAML/Compose parsing. + ## 2026-09-14 - Declared `variables.json.access` for the proxy (`web`, port 8000), admin API (`api`, port 8001), and admin GUI (`admin`, port 8002). diff --git a/apps/kong/Notes.md b/apps/kong/Notes.md index d9d1e94c1..fcb117486 100644 --- a/apps/kong/Notes.md +++ b/apps/kong/Notes.md @@ -1,4 +1,6 @@ ## Kong -- kong migrations cli: https://docs.konghq.com/gateway/3.6.x/reference/cli/#kong-migrations -- add KONG_ADMIN_GUI_PATH=/admin, then can use Nginx Proxy +- Upstream docs now live in `variables.json > upstream` instead of compose-file comments. +- `web` access points to Kong Manager at `http://${W9_URL}${W9_ADMIN_PATH}`; the proxy listener on port 8000 is modeled as an additional `admin` surface for operators who want a direct browser/API entry. +- This package uses PostgreSQL-backed mode, so `.env` declares `KONG_DATABASE=postgres` explicitly rather than relying on image defaults. +- Removed the unused `kong_prefix_vol`; only the tmpfs mount at `/tmp` is active in the current package layout. diff --git a/apps/kong/docker-compose.yml b/apps/kong/docker-compose.yml index a93874c69..6c792b7e9 100644 --- a/apps/kong/docker-compose.yml +++ b/apps/kong/docker-compose.yml @@ -1,12 +1,6 @@ -# docs: https://docs.konghq.com/gateway/latest/install/docker/#main -# image: https://hub.docker.com/_/kong -# compose: https://github.com/Kong/docker-kong/blob/master/compose/docker-compose.yml - -version: '3.8' - services: kong-migrations: - image: $W9_REPO:${W9_VERSION} + image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID}-migrations command: kong migrations bootstrap depends_on: @@ -15,26 +9,29 @@ services: restart: on-failure kong-migrations-up: - image: $W9_REPO:${W9_VERSION} + image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID}-migrations-up - command: kong migrations up && kong migrations finish + command: + - /bin/sh + - -ec + - kong migrations up && kong migrations finish depends_on: - db env_file: .env restart: on-failure kong: - image: $W9_REPO:${W9_VERSION} + image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID} depends_on: - kong-migrations-up: + kong-migrations-up: condition: service_completed_successfully user: "${KONG_USER:-kong}" env_file: .env ports: - - ${W9_HTTP_PORT_SET}:8000 # apis - - ${W9_ADMIN_API_PORT_SET}:8001 # admin api - - ${W9_ADMIN_GUI_PORT_SET}:8002 # admin gui + - "${W9_HTTP_PORT_SET}:8000" # Proxy + - "${W9_ADMIN_API_PORT_SET}:8001" # Admin API + - "${W9_ADMIN_GUI_PORT_SET}:8002" # Kong Manager healthcheck: test: [ "CMD", "kong", "health" ] interval: 10s @@ -43,14 +40,13 @@ services: restart: on-failure:5 read_only: true volumes: - - kong_prefix_vol:${KONG_PREFIX} - kong_tmp_vol:/tmp - ./src/config:/opt/kong security_opt: - no-new-privileges db: - image: postgres:$W9_DB_VERSION + image: postgres:${W9_DB_VERSION} container_name: ${W9_ID}-postgresql environment: POSTGRES_DB: ${KONG_PG_DATABASE} @@ -68,11 +64,7 @@ services: - "postgres:/var/lib/postgresql/data" volumes: - postgres: - kong_prefix_vol: - driver_opts: - type: tmpfs - device: tmpfs + postgres: kong_tmp_vol: driver_opts: type: tmpfs @@ -81,4 +73,4 @@ volumes: networks: default: name: ${W9_NETWORK} - external: true \ No newline at end of file + external: true diff --git a/apps/kong/src/get_version.sh b/apps/kong/src/get_version.sh deleted file mode 100644 index faedc3063..000000000 --- a/apps/kong/src/get_version.sh +++ /dev/null @@ -1 +0,0 @@ -sudo echo kong version: $(docker exec -i $1 kong version) |sudo tee -a /data/logs/install_version.txt diff --git a/apps/kong/variables.json b/apps/kong/variables.json index fe86a9dfe..a62c66bb5 100644 --- a/apps/kong/variables.json +++ b/apps/kong/variables.json @@ -2,6 +2,15 @@ "name": "kong", "trademark": "Kong Gateway (OSS)", "release": true, + "upstream": { + "image": "https://hub.docker.com/_/kong", + "releases": "https://github.com/Kong/kong/releases", + "docs": [ + "https://docs.konghq.com/gateway/latest/install/docker/", + "https://docs.konghq.com/gateway/latest/production/environment-variables/", + "https://github.com/Kong/docker-kong/tree/master/compose" + ] + }, "edition": [ { "dist": "community", @@ -12,22 +21,23 @@ } ], "access": { + "defaultScheme": "http", "web": { - "port": 8000 + "port": 8002, + "path": "/admin" }, "admin": { - "port": 8002 + "port": 8000, + "path": "/" }, "api": { - "port": 8001 + "port": 8001, + "path": "/" } }, "requirements": { "cpu": "1", "memory": "2", "disk": "1" - }, - "upstream": { - "image": "https://hub.docker.com/_/kong" } } diff --git a/apps/laravel/.env b/apps/laravel/.env index 6bf039f6d..7d8370300 100644 --- a/apps/laravel/.env +++ b/apps/laravel/.env @@ -1,6 +1,6 @@ W9_REPO=serversideup/php W9_DIST=community -W9_VERSION=13.31.0 +W9_VERSION=13.35.0 # Canonical semantics live in docs/w9-env-spec.md. # This template controls layout; the spec controls meaning and decision rules. diff --git a/apps/laravel/CHANGELOG.md b/apps/laravel/CHANGELOG.md index 13bd01244..5651b146f 100644 --- a/apps/laravel/CHANGELOG.md +++ b/apps/laravel/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-12 + +- Updated the Laravel framework package version from `13.31.0` to `13.35.0`. +- Refreshed the generated package README so the supported version matches the updated scaffold target. + ## 2026-09-17 - Added a thin runtime orchestrator in front of the base image entrypoint so the unified `DATABASE_URL` is mapped to Laravel's `DB_CONNECTION`/`DB_URL` (the base `/etc/entrypoint.d/` scripts run in subshells and cannot export to the main process). diff --git a/apps/laravel/README.md b/apps/laravel/README.md index 10e3915c8..74267a4ab 100644 --- a/apps/laravel/README.md +++ b/apps/laravel/README.md @@ -44,7 +44,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 13.31.0, latest. +Supported versions: 13.35.0, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -59,9 +59,7 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p ### Data Directory -- `laravel_app` → `/var/www/html` -- `mysql_data` → `/var/lib/mysql` - +Data is persisted in the `laravel_app` volume, mounted at `/var/www/html`. ### Environment Variables @@ -72,8 +70,8 @@ Environment variables are defined in the app's `.env` file; see the reference se ### Configuration Files -- `./src/entrypoint.d/10-scaffold.sh` → `/etc/entrypoint.d/10-scaffold.sh` -- `./src/entrypoint.d/20-composer-install.sh` → `/etc/entrypoint.d/20-composer-install.sh` +- `./src/entrypoint.sh` → `/opt/websoft9/entrypoint.sh` +- `./src/entrypoint.d` → `/opt/websoft9/entrypoint.d` diff --git a/apps/laravel/variables.json b/apps/laravel/variables.json index a6a5e4d62..f51dae4fa 100644 --- a/apps/laravel/variables.json +++ b/apps/laravel/variables.json @@ -15,7 +15,7 @@ { "dist": "community", "version": [ - "13.31.0", + "13.35.0", "latest" ] } diff --git a/apps/librechat/.env b/apps/librechat/.env index 090eebac3..bd737e547 100644 --- a/apps/librechat/.env +++ b/apps/librechat/.env @@ -32,12 +32,13 @@ NODE_ENV=production MONGO_URI=mongodb://${W9_ID}-mongodb:27017/LibreChat MEILI_HOST=http://${W9_ID}-meilisearch:7700 MEILI_NO_ANALYTICS=true -MEILI_MASTER_KEY=DrhYf7zENyR6AlUCKmnz0eYASOQdl6zxH7s7MKFSfFCt +MEILI_MASTER_KEY=2f54759e2a05479ba914275c7e88c9f416f2e1b37b20490aa3b78f0f1ab6d5d4 RAG_PORT=8000 RAG_API_URL=http://${W9_ID}-rag:8000 DOMAIN_CLIENT=http://${W9_URL} DOMAIN_SERVER=http://${W9_URL} -ADMIN_PANEL_SESSION_SECRET='o7rzFWa7gei1kbMfwGBhfl0E-WyhoTvy1wkrKLrs87w' +LIBRECHAT_TEMP_CREDENTIALS_PATH=/app/data/.env.temp +ADMIN_PANEL_SESSION_SECRET=6ddae6544d2546d0bfd7f21bdc3d43c7673db7b35a154efe8632f0fe3ec0bbba ADMIN_PANEL_SESSION_COOKIE_SECURE=false CONFIG_PATH=/app/librechat.yaml OPENAI_API_KEY=user_provided @@ -54,10 +55,10 @@ ALLOW_PASSWORD_RESET=false ALLOW_UNVERIFIED_EMAIL_LOGIN=true SESSION_EXPIRY=1000 * 60 * 15 REFRESH_TOKEN_EXPIRY=(1000 * 60 * 60 * 24) * 7 -JWT_SECRET=16f8c0ef4a5d391b26034086c628469d3f9f497f08163ab9b40137092f2909ef -JWT_REFRESH_SECRET=eaa5191f2914e30b9387fd84e254e4ba6fc51b4654968a9b0803b456a54b8418 -CREDS_KEY=f34be427ebb29de8d88c107a71546019685ed8b241d8f2ed00c3df97ad2566f0 -CREDS_IV=e2341419ec3dd3d19b13a1a87fafcbfb +JWT_SECRET=72999d2dc59d49f8bc781a3bf3ef4eb7ee830386fb004f0aa410e7f1bcbe611f +JWT_REFRESH_SECRET=86e02895f44147c383d437e09907804a441c2c63fdd14b6e8956e56289f901ff +CREDS_KEY=5b1ddb5f61914b82b27c3df455f8a663fdf304e50f32405aa7e4be7397f624cb +CREDS_IV=d4d1d0e9c86e4cb9b0f8b1c6c5c7abde # Not used by default; enable only when needed: # DEBUG_LOGGING=false diff --git a/apps/librechat/CHANGELOG.md b/apps/librechat/CHANGELOG.md index 2cff63a1d..a38bae65d 100644 --- a/apps/librechat/CHANGELOG.md +++ b/apps/librechat/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-12 + +- Hardened the packaged `v0.8.7` deployment with explicit generated secrets for the admin panel, Meilisearch, JWT, and credential storage. +- Mounted the package `.env` into the API container and set `LIBRECHAT_TEMP_CREDENTIALS_PATH` so generated temp credentials persist under `/app/data`. +- Aligned `src/librechat.yaml` back to the upstream `v0.8.7` config schema version and refreshed upstream metadata links. + ## 2026-09-13 - Pinned the main image from the floating `latest` to `librechat/librechat:v0.8.7`. diff --git a/apps/librechat/README.md b/apps/librechat/README.md index 9f8b1c055..6001b1af4 100644 --- a/apps/librechat/README.md +++ b/apps/librechat/README.md @@ -33,9 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: v0.8.7, latest. - -The `latest` tag is not guaranteed to remain valid; pin a specific version for production. +Supported versions: v0.8.7. ### Ports @@ -49,6 +47,7 @@ The `latest` tag is not guaranteed to remain valid; pin a specific version for p ### Data Directory +- `./.env` → `/app/.env` - `app-images` → `/app/client/public/images` - `app-uploads` → `/app/uploads` - `app-logs` → `/app/logs` @@ -76,17 +75,17 @@ Configuration is overridden by mounting `./src/librechat.yaml` to `/app/librecha - [Docker Hub image](https://hub.docker.com/r/librechat/librechat) -- [Releases](https://github.com/danny-avila/LibreChat/releases) +- [Releases](https://github.com/LibreChat-AI/LibreChat/releases) -- [Official compose](https://raw.githubusercontent.com/danny-avila/LibreChat/main/docker-compose.yml) +- [Official compose](https://raw.githubusercontent.com/LibreChat-AI/LibreChat/main/docker-compose.yml) -- [Official env example](https://raw.githubusercontent.com/danny-avila/LibreChat/main/.env.example) +- [Official env example](https://raw.githubusercontent.com/LibreChat-AI/LibreChat/main/.env.example) - [Official docs](https://www.librechat.ai/docs/local/docker) - [Official docs](https://www.librechat.ai/docs/configuration/dotenv) -- [GitHub docs](https://github.com/danny-avila/LibreChat) +- [GitHub docs](https://github.com/LibreChat-AI/LibreChat) diff --git a/apps/librechat/docker-compose.yml b/apps/librechat/docker-compose.yml index 7d2a184fe..a98ba4ec3 100644 --- a/apps/librechat/docker-compose.yml +++ b/apps/librechat/docker-compose.yml @@ -13,6 +13,7 @@ services: - MEILI_HOST=http://${W9_ID}-meilisearch:7700 - RAG_PORT=8000 - RAG_API_URL=http://${W9_ID}-rag:8000 + - LIBRECHAT_TEMP_CREDENTIALS_PATH=/app/data/.env.temp depends_on: mongodb: condition: service_started @@ -21,6 +22,7 @@ services: extra_hosts: - "host.docker.internal:host-gateway" volumes: + - ./.env:/app/.env:ro - ./src/librechat.yaml:/app/librechat.yaml:ro - app-images:/app/client/public/images - app-uploads:/app/uploads @@ -46,7 +48,7 @@ services: - PORT=3000 - SESSION_SECRET=${ADMIN_PANEL_SESSION_SECRET} - API_SERVER_URL=http://${W9_ID}:3080 - - VITE_API_BASE_URL=http://${W9_URL} + - VITE_API_BASE_URL=${DOMAIN_CLIENT} - SESSION_COOKIE_SECURE=${ADMIN_PANEL_SESSION_COOKIE_SECURE} mongodb: diff --git a/apps/librechat/src/librechat.yaml b/apps/librechat/src/librechat.yaml index f2adb968d..1c48c47d5 100644 --- a/apps/librechat/src/librechat.yaml +++ b/apps/librechat/src/librechat.yaml @@ -2,7 +2,7 @@ # https://www.librechat.ai/docs/configuration/librechat_yaml # Configuration version (required) -version: 1.3.16 +version: 1.3.13 # Cache settings: Set to true to enable caching -cache: true \ No newline at end of file +cache: true diff --git a/apps/librechat/variables.json b/apps/librechat/variables.json index c76c9e10e..56b89b47f 100644 --- a/apps/librechat/variables.json +++ b/apps/librechat/variables.json @@ -4,23 +4,22 @@ "release": true, "upstream": { "image": "https://hub.docker.com/r/librechat/librechat", - "releases": "https://github.com/danny-avila/LibreChat/releases", + "releases": "https://github.com/LibreChat-AI/LibreChat/releases", "compose": { - "compose": "https://raw.githubusercontent.com/danny-avila/LibreChat/main/docker-compose.yml", - "env": "https://raw.githubusercontent.com/danny-avila/LibreChat/main/.env.example" + "compose": "https://raw.githubusercontent.com/LibreChat-AI/LibreChat/main/docker-compose.yml", + "env": "https://raw.githubusercontent.com/LibreChat-AI/LibreChat/main/.env.example" }, "docs": [ "https://www.librechat.ai/docs/local/docker", "https://www.librechat.ai/docs/configuration/dotenv", - "https://github.com/danny-avila/LibreChat" + "https://github.com/LibreChat-AI/LibreChat" ] }, "edition": [ { "dist": "community", "version": [ - "v0.8.7", - "latest" + "v0.8.7" ] } ], @@ -36,5 +35,15 @@ "cpu": "2", "memory": "4", "disk": "10" + }, + "env": { + "secrets": [ + "ADMIN_PANEL_SESSION_SECRET", + "MEILI_MASTER_KEY", + "JWT_SECRET", + "JWT_REFRESH_SECRET", + "CREDS_KEY", + "CREDS_IV" + ] } } diff --git a/apps/litellm/.env b/apps/litellm/.env index 39059c734..5f77a68c3 100644 --- a/apps/litellm/.env +++ b/apps/litellm/.env @@ -1,53 +1,40 @@ -W9_REPO="wordpress" +W9_REPO=ghcr.io/berriai/litellm W9_DIST=community -W9_VERSION="latest" +W9_VERSION=v1.105.0 W9_POWER_PASSWORD="1PrMxExC45LsCT" -# Environments which for user settings when create application -# Named expression: W9_xxx_xxx_SET, xxx refer to file fields -W9_HTTP_PORT_SET=9001 -# W9_HTTPS_PORT_SET=9002 -# W9_DB_PORT_SET=3306 -# W9_SSH_PORT_SET=23 -W9_KEY_SET="dfsjdkjf77xjxcjcj" +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### W9_ID=litellm - -# W9_HTTP_PORT or W9_HTTPS_PORT is need at leaset and used for proxy for web application -# Some container (e.g teleport) need HTTPS access, then need to set this pra -W9_HTTP_PORT=80 -W9_HTTPS_PORT=81 - -W9_LOGIN_USER=admin -# use https://1password.com/zh-cn/password-generator/ to genarate 14 bit password -# this password can also use password file -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_ADMIN_PATH="/wp-login" - -# Container name's suffix must use one of the value -W9_DB_EXPOSE="mysql,postgresql,mariadb,mongodb,redis" - -# It is used when the application APP needs to set an external URL, which can be IP(or domain), IP:PORT -# If have protocols, should be set it in the APP's ENV +W9_HTTP_PORT=4000 +W9_HTTP_PORT_SET=9001 +W9_DB_VERSION=16 +W9_DB_EXPOSE=postgresql W9_URL=example.youdomain.com -# modifies W9_URL on init when it is true -W9_URL_REPLACE=true - W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### - -# Below environment is created by this app - -WORDPRESS_DB_HOST=$W9_ID-mariadb -WORDPRESS_DB_USER=wordpress #if use postgresql, it need set to postgres -WORDPRESS_DB_PASSWORD=$W9_POWER_PASSWORD -WORDPRESS_DB_NAME=wordpress - - -#W9_NAME="" -#W9_RCODE="" \ No newline at end of file +# ============================================================ +# LiteLLM image environment variables +# Docs: https://docs.litellm.ai/docs/proxy/docker_quick_start +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +LITELLM_MASTER_KEY=sk-f9938940a2a1475b96ce4f8b4fd1a0cf0d84047cd6d34d239f3f4bc20d2fa1cf +LITELLM_SALT_KEY=sk-c698f2cdb784441dbdbd0c958b8abcb8da65f215fc6f492a8d58d94d2f5c283b +DATABASE_URL=postgresql://litellm:${W9_POWER_PASSWORD}@${W9_ID}-postgresql:5432/litellm +STORE_MODEL_IN_DB=True +UI_USERNAME=admin +UI_PASSWORD=${W9_POWER_PASSWORD} + +# Not used by default; enable only when needed: +# OPENAI_API_KEY= +# LITELLM_BIND=127.0.0.1: diff --git a/apps/litellm/CHANGELOG.md b/apps/litellm/CHANGELOG.md index 582cf46c5..0e670e238 100644 --- a/apps/litellm/CHANGELOG.md +++ b/apps/litellm/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 +- Replaced the incorrect WordPress/MariaDB package with the official LiteLLM proxy self-hosting topology. +- Pinned the main image to `ghcr.io/berriai/litellm:v1.105.0` and added bundled PostgreSQL for DB-backed model and key management. +- Added persistent proxy configuration and package metadata for the `/ui` admin console. +- Configured explicit `UI_USERNAME` and `UI_PASSWORD` so the Admin UI does not require using the master key for environment-credential login. diff --git a/apps/litellm/README.md b/apps/litellm/README.md index 28ecf32f7..ca014595f 100644 --- a/apps/litellm/README.md +++ b/apps/litellm/README.md @@ -1,26 +1,87 @@ -# LiteLLM on Docker +# LiteLLM on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for LiteLLM: +## Quick Start +### Deploy Verification - - community: latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **LiteLLM**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Open `/ui` to manage the proxy and inspect configured models. +2. Set at least one provider key such as `OPENAI_API_KEY` in `.env`, then rebuild. +3. Send an OpenAI-compatible request to `/v1/chat/completions`. -The following are the minimal [recommended requirements](https://www.litellm.ai): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. The Admin UI uses `UI_USERNAME` and `UI_PASSWORD` from `.env`. +2. The API and proxy admin key use `LITELLM_MASTER_KEY`. +3. Do not rotate `LITELLM_SALT_KEY` after first deployment unless you also reset encrypted credentials in the database. + -## Install +## Configuration Reference -You can install this LiteLLM by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [LiteLLM Docker image](https://ghcr.io/berriai/litellm) and makes some improvements below. -If you want use LiteLLM with **Websoft9 Business Support** free, you can [subscribe LiteLLM](https://www.websoft9.com/apps) on Cloud platform + +This package follows LiteLLM's official DB-backed quickstart topology so the `/ui` admin console, model catalog, and key management are available. The package also sets `UI_USERNAME` and `UI_PASSWORD`, so the Admin UI no longer falls back to using `LITELLM_MASTER_KEY` as the login password. + -## Documentation +Apps run as containers; rebuild after any configuration change. -[LiteLLM Administrator Guide](https://support.websoft9.com/docs/litellm) powered by Websoft9 \ No newline at end of file +### Version Support + +Supported versions: v1.105.0. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 4000 | + + +### Data Directory + + +Data is persisted in the `postgres_data` volume, mounted at `/var/lib/postgresql/data`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/proxy_server_config.yaml` to `/app/proxy_server_config.yaml`. + + +## References + +- [LiteLLM Administrator Guide](https://support.websoft9.com/docs/litellm) by Websoft9 + +- [GHCR image](https://ghcr.io/berriai/litellm) + +- [Releases](https://github.com/BerriAI/litellm/releases) + +- [Official docs](https://docs.litellm.ai/docs/proxy/docker_quick_start) + +- [Official docs](https://docs.litellm.ai/docs/proxy/quick_start) + +- [GitHub docs](https://github.com/BerriAI/litellm) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/litellm/docker-compose.yml b/apps/litellm/docker-compose.yml index 1c1948688..080b6be83 100644 --- a/apps/litellm/docker-compose.yml +++ b/apps/litellm/docker-compose.yml @@ -1,50 +1,44 @@ -# image,docs: https://hub.docker.com/_/wordpress/ - services: - - wordpress: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + litellm: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} restart: unless-stopped - #This is for access host from container - # extra_hosts: ["host.docker.internal:host-gateway"] - # command: | - # /bin/bash -c "ping -c 3 host.docker.internal" - logging: - driver: "json-file" - options: - max-file: "5" - max-size: 10m - deploy: - resources: - limits: - memory: 5g - cpus: '0.7' ports: - - $W9_HTTP_PORT_SET:80 + - "${W9_HTTP_PORT_SET}:4000" # Web Console env_file: .env + command: ["--config", "/tmp/proxy_server_config.yaml"] volumes: - - wordpress:/var/www/html - - ./src/php_exra.ini:/usr/local/etc/php/conf.d/php_exra.ini + - ./src/proxy_server_config.yaml:/tmp/proxy_server_config.yaml:ro + depends_on: + postgresql: + condition: service_healthy + healthcheck: + test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:4000/health/readiness', timeout=10)"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s - mariadb: - image: mariadb:10.4 - container_name: $W9_ID-mariadb + postgresql: + image: postgres:${W9_DB_VERSION} + container_name: ${W9_ID}-postgresql restart: unless-stopped - command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_log_buffer_size=30M - volumes: - - mysql_data:/var/lib/mysql environment: - MYSQL_DATABASE: $WORDPRESS_DB_NAME - MYSQL_USER: $WORDPRESS_DB_USER - MYSQL_PASSWORD: $W9_POWER_PASSWORD - MYSQL_ROOT_PASSWORD: $W9_POWER_PASSWORD + POSTGRES_USER: litellm + POSTGRES_PASSWORD: ${W9_POWER_PASSWORD} + POSTGRES_DB: litellm + healthcheck: + test: ["CMD-SHELL", "pg_isready -U litellm -d litellm"] + interval: 5s + timeout: 5s + retries: 10 + volumes: + - postgres_data:/var/lib/postgresql/data volumes: - wordpress: - mysql_data: - + postgres_data: + networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/litellm/src/proxy_server_config.yaml b/apps/litellm/src/proxy_server_config.yaml new file mode 100644 index 000000000..ce59e7487 --- /dev/null +++ b/apps/litellm/src/proxy_server_config.yaml @@ -0,0 +1,8 @@ +model_list: + - model_name: gpt-4o-mini + litellm_params: + model: openai/gpt-4o-mini + api_key: os.environ/OPENAI_API_KEY + +general_settings: + master_key: os.environ/LITELLM_MASTER_KEY diff --git a/apps/litellm/tests/cases.yml b/apps/litellm/tests/cases.yml new file mode 100644 index 000000000..322c5fdfa --- /dev/null +++ b/apps/litellm/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: ui-redirect + type: web-access + path: /ui + expect_status: 200 diff --git a/apps/litellm/variables.json b/apps/litellm/variables.json index 83fb02fcd..26d0bdea3 100644 --- a/apps/litellm/variables.json +++ b/apps/litellm/variables.json @@ -1,21 +1,60 @@ { "name": "litellm", "trademark": "LiteLLM", - "release": false, + "release": true, + "upstream": { + "image": "ghcr.io/berriai/litellm", + "releases": "https://github.com/BerriAI/litellm/releases", + "docs": [ + "https://docs.litellm.ai/docs/proxy/docker_quick_start", + "https://docs.litellm.ai/docs/proxy/quick_start", + "https://github.com/BerriAI/litellm" + ] + }, "edition": [ { "dist": "community", "version": [ - "latest" + "v1.105.0" ] } ], + "access": { + "defaultScheme": "http", + "web": { + "port": 4000, + "path": "/ui" + }, + "admin": { + "port": 4000, + "path": "/ui" + } + }, "requirements": { "cpu": "2", "memory": "4", "disk": "10" }, - "upstream": { - "image": "ghcr.io/berriai/litellm" + "env": { + "secrets": [ + "W9_POWER_PASSWORD", + "LITELLM_MASTER_KEY", + "LITELLM_SALT_KEY", + "UI_PASSWORD" + ] + }, + "database": { + "type": "postgresql", + "supported_modes": [ + "bundled" + ], + "default_mode": "bundled", + "bundled": { + "service": "postgresql", + "internal_host": "${W9_ID}-postgresql", + "database_env": "POSTGRES_DB", + "username_env": "POSTGRES_USER", + "password_env": "POSTGRES_PASSWORD" + } } } diff --git a/apps/lobehub/.env b/apps/lobehub/.env index 68686c9e5..419d22aff 100644 --- a/apps/lobehub/.env +++ b/apps/lobehub/.env @@ -1,6 +1,6 @@ W9_REPO=lobehub/lobehub W9_DIST=community -W9_VERSION=2.2.17 +W9_VERSION=2.2.19 W9_POWER_PASSWORD='l5QTjtAKGj16d!9t' diff --git a/apps/lobehub/CHANGELOG.md b/apps/lobehub/CHANGELOG.md index 5e7982f80..162530e36 100644 --- a/apps/lobehub/CHANGELOG.md +++ b/apps/lobehub/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## 2026-10-12 + +- Updated the main image from `lobehub/lobehub:2.2.17` to `lobehub/lobehub:2.2.19`. +- Restored the RustFS init helper to the pullable upstream `rustfs/rc:latest` image after `quay.io/minio/mc:latest` stopped resolving anonymously. +- Refreshed the generated package README so the supported version matches the validated image tag. + ## 2026-09-12 - Renamed the app from `lobechat` to `lobehub` to follow the upstream rebrand, including the directory, trademark, `W9_ID`, and container names. diff --git a/apps/lobehub/README.md b/apps/lobehub/README.md index dcd7238c1..b48604f5e 100644 --- a/apps/lobehub/README.md +++ b/apps/lobehub/README.md @@ -33,7 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 2.2.17, latest. +Supported versions: 2.2.19, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/lobehub/docker-compose.yml b/apps/lobehub/docker-compose.yml index b929737d0..9cf662845 100644 --- a/apps/lobehub/docker-compose.yml +++ b/apps/lobehub/docker-compose.yml @@ -70,7 +70,7 @@ services: - rustfs_data:/data rustfs-init: - image: quay.io/minio/mc:latest + image: rustfs/rc:latest container_name: ${W9_ID}-rustfs-init restart: "no" depends_on: @@ -81,7 +81,7 @@ services: entrypoint: /bin/sh command: - -c - - 'set -eux; mc alias set rustfs "http://${W9_ID}-rustfs:9000" "${RUSTFS_ACCESS_KEY}" "${RUSTFS_SECRET_KEY}"; mc mb "rustfs/lobe" --ignore-existing; mc anonymous set-json "/bucket.config.json" "rustfs/lobe";' + - 'set -eux; rc alias set rustfs "http://${W9_ID}-rustfs:9000" "${RUSTFS_ACCESS_KEY}" "${RUSTFS_SECRET_KEY}"; rc mb "rustfs/lobe" --ignore-existing; rc anonymous set-json "/bucket.config.json" "rustfs/lobe";' volumes: postgresql_data: diff --git a/apps/lobehub/variables.json b/apps/lobehub/variables.json index f9b6702d2..91c388405 100644 --- a/apps/lobehub/variables.json +++ b/apps/lobehub/variables.json @@ -18,7 +18,7 @@ { "dist": "community", "version": [ - "2.2.17", + "2.2.19", "latest" ] } diff --git a/apps/localai/.env b/apps/localai/.env index 47b387b95..6492579cd 100644 --- a/apps/localai/.env +++ b/apps/localai/.env @@ -1,11 +1,34 @@ W9_REPO=localai/localai W9_DIST=community -W9_VERSION=latest +W9_VERSION=v4.6.2 + +W9_POWER_PASSWORD="H8m3lLs7J2c4aP1q" + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_HTTP_PORT_SET=9001 W9_ID=localai W9_HTTP_PORT=8080 +W9_HTTP_PORT_SET=9001 W9_URL=example.youdomain.com W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# LocalAI image environment variables +# Docs: https://localai.io/docs/getting-started/containers/ +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +LOCALAI_API_KEY=${W9_POWER_PASSWORD} + +# Not used by default; enable only when needed: +# DEBUG=true +# THREADS=4 +# MODELS_PATH=/models diff --git a/apps/localai/CHANGELOG.md b/apps/localai/CHANGELOG.md index 4591f22ad..619892934 100644 --- a/apps/localai/CHANGELOG.md +++ b/apps/localai/CHANGELOG.md @@ -1,2 +1,7 @@ # CHANGELOG +## 2026-10-12 + +- Updated the main image from `localai/localai:latest` to `localai/localai:v4.6.2`. +- Added persistent volumes for models, backends, configuration, and runtime data to match the official container guidance. +- Added an API key variable and a `/v1/models` healthcheck for automated validation. diff --git a/apps/localai/README.md b/apps/localai/README.md index 84e895b44..0cc9aa42a 100644 --- a/apps/localai/README.md +++ b/apps/localai/README.md @@ -1,26 +1,91 @@ -# LocalAI on Docker +# LocalAI on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for LocalAI: +## Quick Start +### Deploy Verification - - community: latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **LocalAI**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Deploy the package and open the API/UI endpoint. +2. Add or download at least one model before trying inference. +3. Verify `GET /v1/models` returns your loaded models. -The following are the minimal [recommended requirements](https://localai.io): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this LocalAI by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [LocalAI Docker image](https://hub.docker.com/r/localai/localai) and makes some improvements below. -If you want use LocalAI with **Websoft9 Business Support** free, you can [subscribe LocalAI](https://www.websoft9.com/apps) on Cloud platform + +LocalAI does not ship with a ready-to-chat model. Add a model after deployment and keep the mounted data volumes if you want models and runtime state to survive upgrades. + -## Documentation +Apps run as containers; rebuild after any configuration change. -[LocalAI Administrator Guide](https://support.websoft9.com/docs/localai) powered by Websoft9 \ No newline at end of file +### Version Support + +Supported versions: v4.6.2. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 8080 | + + +### Data Directory + + +- `models` → `/models` +- `backends` → `/backends` +- `configuration` → `/configuration` +- `data` → `/data` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [LocalAI Administrator Guide](https://support.websoft9.com/docs/localai) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/localai/localai) + +- [Releases](https://github.com/mudler/LocalAI/releases) + +- [Official docs](https://localai.io/docs/getting-started/containers/) + +- [Official docs](https://localai.io/docs/getting-started/models/) + +- [GitHub docs](https://github.com/mudler/LocalAI) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/localai/docker-compose.yml b/apps/localai/docker-compose.yml index c4c7fe1ed..aa2bbd30e 100644 --- a/apps/localai/docker-compose.yml +++ b/apps/localai/docker-compose.yml @@ -1,17 +1,30 @@ -# docs: https://localai.io/basics/getting_started/ -# image: https://hub.docker.com/r/localai/localai/tags - services: - localai: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} restart: unless-stopped ports: - - $W9_HTTP_PORT_SET:8080 + - "${W9_HTTP_PORT_SET}:8080" # Web Console env_file: .env + volumes: + - models:/models + - backends:/backends + - configuration:/configuration + - data:/data + healthcheck: + test: ["CMD", "sh", "-c", "wget --header='Authorization: Bearer ${LOCALAI_API_KEY}' -qO- http://127.0.0.1:8080/v1/models >/dev/null 2>&1 || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + +volumes: + models: + backends: + configuration: + data: networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/localai/tests/cases.yml b/apps/localai/tests/cases.yml new file mode 100644 index 000000000..cfcb5c1a1 --- /dev/null +++ b/apps/localai/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: auth-required + type: web-access + path: /v1/models + expect_status: 401 diff --git a/apps/localai/variables.json b/apps/localai/variables.json index 8337daff9..9e09e8332 100644 --- a/apps/localai/variables.json +++ b/apps/localai/variables.json @@ -6,8 +6,7 @@ { "dist": "community", "version": [ - "v3.9.0", - "latest" + "v4.6.2" ] } ], @@ -24,6 +23,17 @@ "disk": "8" }, "upstream": { - "image": "https://hub.docker.com/r/localai/localai" + "image": "https://hub.docker.com/r/localai/localai", + "releases": "https://github.com/mudler/LocalAI/releases", + "docs": [ + "https://localai.io/docs/getting-started/containers/", + "https://localai.io/docs/getting-started/models/", + "https://github.com/mudler/LocalAI" + ] + }, + "env": { + "secrets": [ + "LOCALAI_API_KEY" + ] } } diff --git a/apps/logstash/.env b/apps/logstash/.env index 288e48f5e..162753fd7 100644 --- a/apps/logstash/.env +++ b/apps/logstash/.env @@ -1,4 +1,4 @@ -W9_VERSION='9.1.0' +W9_VERSION='9.5.5' W9_DIST='community' W9_REPO=docker.elastic.co/logstash/logstash diff --git a/apps/logstash/CHANGELOG.md b/apps/logstash/CHANGELOG.md index 582cf46c5..7470f1cee 100644 --- a/apps/logstash/CHANGELOG.md +++ b/apps/logstash/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 + +- Updated the main image from `docker.elastic.co/logstash/logstash:9.1.0` to `docker.elastic.co/logstash/logstash:9.5.5`. +- Added an app-specific API reachability test for the Logstash monitoring endpoint. +- Refreshed the generated package README so the supported version matches the updated image tag. diff --git a/apps/logstash/Notes.md b/apps/logstash/Notes.md deleted file mode 100644 index bb3c39a54..000000000 --- a/apps/logstash/Notes.md +++ /dev/null @@ -1,4 +0,0 @@ -# Logstash - -- Multiply pipelines -- Beat to Logstash \ No newline at end of file diff --git a/apps/logstash/README.md b/apps/logstash/README.md index 0a104dd90..8f5aef829 100644 --- a/apps/logstash/README.md +++ b/apps/logstash/README.md @@ -1,26 +1,78 @@ -# logstash on Docker +# logstash on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for logstash: +## Quick Start +### Deploy Verification - - community: 9.0.2 +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **logstash**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the logstash admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://www.elastic.co/guide/en/logstash/current/docker-config.html): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this logstash by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [logstash Docker image](https://hub.docker.com/_/logstash) and makes some improvements below. -If you want use logstash with **Websoft9 Business Support** free, you can [subscribe logstash](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[logstash Administrator Guide](https://support.websoft9.com/docs/logstash) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 9.5.5. + + +### Ports + +| Purpose | Port | +| --- | --- | +| for API | 9600 | + + +### Data Directory + + +Data is kept inside the container; a named volume is recommended for persistence. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/pipeline` to `/usr/share/logstash/pipeline`. + + +## References + +- [logstash Administrator Guide](https://support.websoft9.com/docs/logstash) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/logstash) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/logstash/docker-compose.yml b/apps/logstash/docker-compose.yml index 820790907..8f1a8b275 100644 --- a/apps/logstash/docker-compose.yml +++ b/apps/logstash/docker-compose.yml @@ -3,8 +3,6 @@ # docs: https://www.elastic.co/guide/en/logstash/current/docker.html#docker # docs: https://www.elastic.co/guide/en/logstash/current/docker-config.html -version: '3.8' - services: logstash: diff --git a/apps/logstash/tests/cases.yml b/apps/logstash/tests/cases.yml new file mode 100644 index 000000000..0df06e211 --- /dev/null +++ b/apps/logstash/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: api-root + type: web-access + path: / + expect_status: 200 diff --git a/apps/logstash/variables.json b/apps/logstash/variables.json index e0b078e00..008b3732d 100644 --- a/apps/logstash/variables.json +++ b/apps/logstash/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "9.1.0" + "9.5.5" ] } ], diff --git a/apps/mattermost/CHANGELOG.md b/apps/mattermost/CHANGELOG.md index e1de8fdc5..cd2743d30 100644 --- a/apps/mattermost/CHANGELOG.md +++ b/apps/mattermost/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-12 + +- Pin Mattermost Team Edition from the floating `11.11` line to the current stable patch `11.11.1` for deterministic deployments. +- Add upstream Docker and release-note references to the package metadata. + ## 2026-09-30 - Update Mattermost team edition from `11.1` to `11.11` (latest stable upstream release; no major-version jump). diff --git a/apps/mattermost/README.md b/apps/mattermost/README.md index 35637a9c2..09d904de4 100644 --- a/apps/mattermost/README.md +++ b/apps/mattermost/README.md @@ -33,7 +33,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 11.11. +Supported versions: 11.11.1. ### Ports @@ -73,6 +73,12 @@ Configuration files live inside the image; mount a single file read-only to over - [Docker Hub image](https://hub.docker.com/r/mattermost/mattermost-team-edition) +- [Official docs](https://docs.mattermost.com/install/install-docker.html) + +- [Official docs](https://docs.mattermost.com/deployment-guide/server/docker-troubleshooting.html) + +- [Official docs](https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html) + ## Troubleshooting diff --git a/apps/mattermost/variables.json b/apps/mattermost/variables.json index f69a02fe2..0790fbe61 100644 --- a/apps/mattermost/variables.json +++ b/apps/mattermost/variables.json @@ -3,7 +3,12 @@ "trademark": "Mattermost", "release": true, "upstream": { - "image": "https://hub.docker.com/r/mattermost/mattermost-team-edition" + "image": "https://hub.docker.com/r/mattermost/mattermost-team-edition", + "docs": [ + "https://docs.mattermost.com/install/install-docker.html", + "https://docs.mattermost.com/deployment-guide/server/docker-troubleshooting.html", + "https://docs.mattermost.com/product-overview/mattermost-v11-changelog.html" + ] }, "edition": [ { diff --git a/apps/milvus/.env b/apps/milvus/.env index 96e14ea67..11493c88b 100644 --- a/apps/milvus/.env +++ b/apps/milvus/.env @@ -1,20 +1,40 @@ W9_REPO=milvusdb/milvus -W9_VERSION='v2.6.3' -W9_DIST='community' +W9_DIST=community +W9_VERSION=v3.0.3 W9_POWER_PASSWORD='0CgnfPkRxVxz!Qpa' -W9_ID='milvus' -W9_RCODE='V3G8Jqzk15kHy' -W9_ADMIN_PATH="/webui" +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. -W9_HTTP_PORT=9091 +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=milvus +W9_RCODE='V3G8Jqzk15kHy' +W9_ADMIN_PATH="/webui" +W9_HTTP_PORT=9091 W9_HTTP_PORT_SET='19530' W9_DB_PORT_SET='9530' -W9_URL='example.youdomain.com' +W9_URL=example.youdomain.com W9_NETWORK=websoft9 -# Below environment is created by this app: https://github.com/milvus-io/milvus/blob/master/.env +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Milvus image environment variables +# Docs: https://github.com/milvus-io/milvus/blob/master/configs/milvus.yaml +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ +# Used by docker-compose.yml: MINIO_REGION=us-east-1 ETCD_ENDPOINTS=${W9_RCODE}etcd:2379 MINIO_ADDRESS=${W9_RCODE}minio:9000 + +# Not used by default; enable only when needed: +# COMMON_STORAGETYPE=minio +# MINIO_BUCKET_NAME=a-bucket +# MINIO_ROOT_PATH=milvus +# MINIO_USE_SSL=false +# ETCD_USE_EMBED=false diff --git a/apps/milvus/CHANGELOG.md b/apps/milvus/CHANGELOG.md index 09c4e7bd0..c5fdd6dd8 100644 --- a/apps/milvus/CHANGELOG.md +++ b/apps/milvus/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG -## Release +## 2026-10-14 -### Fixes and Enhancements +- Updated Milvus from `v2.6.3` to `v3.0.3`, the latest stable upstream release. +- Followed the upstream `v3.0` standalone compose changes: added the `milvus-volume-init` one-shot volume ownership step, bumped etcd to `v3.5.25`, switched MinIO to the upstream `milvusdb/minio` image, and used the `mc ready local` MinIO healthcheck. +- Aligned `.env` with the current repository layout and documented the Milvus image environment section. +- Added inline purpose comments to the published ports and braced `${VAR}` references in `docker-compose.yml`. +- Added `tests/cases.yml` with `/healthz` and `/webui/` reachability checks. +- Added upstream releases, compose, and docs references to `variables.json`. +- Regenerated `README.md` from `variables.json`. diff --git a/apps/milvus/README.md b/apps/milvus/README.md index f2c09e990..20dfdcb01 100644 --- a/apps/milvus/README.md +++ b/apps/milvus/README.md @@ -1,26 +1,92 @@ -# Milvus on Docker +# Milvus on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Milvus: +## Quick Start +### Deploy Verification - - community: v2.5.5, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Milvus**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Milvus admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://milvus.io/docs/prerequisite-docker.md): +### Change Password -* **RAM**: 32 GB or more -* **CPU**: 8 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Milvus by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Milvus Docker image](https://hub.docker.com/r/milvusdb/milvus) and makes some improvements below. -If you want use Milvus with **Websoft9 Business Support** free, you can [subscribe Milvus](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Milvus Administrator Guide](https://support.websoft9.com/docs/milvus) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v3.0.3, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Milvus WebUI | 9091 | +| Milvus SDK/gRPC endpoint | 19530 | + + +### Data Directory + + +- `milvus_data` → `/var/lib/milvus` +- `etcd_data` → `/etcd` +- `minio_data` → `/minio_data` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Milvus Administrator Guide](https://support.websoft9.com/docs/milvus) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/milvusdb/milvus) + +- [Releases](https://github.com/milvus-io/milvus/releases) + +- [Official compose](https://raw.githubusercontent.com/milvus-io/milvus/v3.0.3/deployments/docker/standalone/docker-compose.yml) + +- [Official docs](https://milvus.io/docs/install_standalone-docker-compose.md) + +- [Official docs](https://milvus.io/docs/milvus-webui.md) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/milvus/docker-compose.yml b/apps/milvus/docker-compose.yml index 16682c019..3219f3e84 100644 --- a/apps/milvus/docker-compose.yml +++ b/apps/milvus/docker-compose.yml @@ -1,17 +1,11 @@ -# image: https://hub.docker.com/r/milvusdb/milvus -# compose: https://github.com/milvus-io/milvus/blob/master/deployments/docker/standalone/docker-compose.yml -# docs: https://milvus.io/docs/zh/install_standalone-docker-compose.md - -version: '3.8' - services: standalone: - container_name: $W9_ID - image: $W9_REPO:$W9_VERSION + container_name: ${W9_ID} + image: ${W9_REPO}:${W9_VERSION} command: ["milvus", "run", "standalone"] security_opt: - - seccomp:unconfined - env_file: .env + - seccomp:unconfined + env_file: .env volumes: - milvus_data:/var/lib/milvus healthcheck: @@ -21,15 +15,42 @@ services: timeout: 20s retries: 3 ports: - - "${W9_HTTP_PORT_SET}:9091" # webui port - - "${W9_DB_PORT_SET}:19530" # server port + - "${W9_HTTP_PORT_SET}:9091" # Milvus WebUI + - "${W9_DB_PORT_SET}:19530" # Milvus SDK/gRPC endpoint depends_on: - - etcd - - minio + milvus-volume-init: + condition: service_completed_successfully + etcd: + condition: service_started + minio: + condition: service_started + + milvus-volume-init: + container_name: ${W9_ID}-volume-init + image: ${W9_REPO}:${W9_VERSION} + user: "0:0" + network_mode: none + read_only: true + restart: "no" + entrypoint: ["/bin/sh", "-c"] + command: + - | + set -eu + uid="$$(id -u milvus)" + gid="$$(id -g milvus)" + marker="/var/lib/milvus/.milvus-volume-owner-$${uid}-$${gid}" + if [ ! -e "$${marker}" ]; then + echo "Preparing /var/lib/milvus for $${uid}:$${gid}" + chown -R "$${uid}:$${gid}" /var/lib/milvus + touch "$${marker}" + chown "$${uid}:$${gid}" "$${marker}" + fi + volumes: + - milvus_data:/var/lib/milvus etcd: - container_name: $W9_ID-etcd - image: quay.io/coreos/etcd:v3.5.18 + container_name: ${W9_ID}-etcd + image: quay.io/coreos/etcd:v3.5.25 hostname: ${W9_RCODE}etcd environment: - ETCD_AUTO_COMPACTION_MODE=revision @@ -46,20 +67,17 @@ services: retries: 3 minio: - container_name: $W9_ID-minio + container_name: ${W9_ID}-minio hostname: ${W9_RCODE}minio - image: minio/minio:RELEASE.2023-03-20T20-16-18Z + image: milvusdb/minio:RELEASE.2024-12-18T13-15-44Z volumes: - minio_data:/minio_data command: minio server /minio_data --console-address ":9001" - # ports: - # - "9001:9001" - # - "9000:9000" environment: MINIO_ACCESS_KEY: minioadmin MINIO_SECRET_KEY: minioadmin healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + test: ["CMD", "mc", "ready", "local"] interval: 30s timeout: 20s retries: 3 @@ -73,8 +91,3 @@ volumes: etcd_data: minio_data: milvus_data: - - - - - diff --git a/apps/milvus/tests/cases.yml b/apps/milvus/tests/cases.yml new file mode 100644 index 000000000..9da701ba9 --- /dev/null +++ b/apps/milvus/tests/cases.yml @@ -0,0 +1,14 @@ +# Milvus serves the WebUI under /webui and returns 404 on the bare root path, +# so the adaptive root web-access check does not apply. +skip: + - id: web-access + +optional: + - id: healthz + type: web-access + path: /healthz + expect_status: 200 + - id: webui + type: web-access + path: /webui/ + expect_status: 200 diff --git a/apps/milvus/variables.json b/apps/milvus/variables.json index b92c8058f..0843c0754 100644 --- a/apps/milvus/variables.json +++ b/apps/milvus/variables.json @@ -3,13 +3,21 @@ "trademark": "Milvus", "release": true, "upstream": { - "image": "https://hub.docker.com/r/milvusdb/milvus" + "image": "https://hub.docker.com/r/milvusdb/milvus", + "releases": "https://github.com/milvus-io/milvus/releases", + "compose": { + "compose": "https://raw.githubusercontent.com/milvus-io/milvus/v3.0.3/deployments/docker/standalone/docker-compose.yml" + }, + "docs": [ + "https://milvus.io/docs/install_standalone-docker-compose.md", + "https://milvus.io/docs/milvus-webui.md" + ] }, "edition": [ { "dist": "community", "version": [ - "v2.6.3", + "v3.0.3", "latest" ] } @@ -18,7 +26,7 @@ "defaultScheme": "http", "web": { "port": 9091, - "path": "/" + "path": "/webui" } }, "requirements": { diff --git a/apps/mlflow/.env b/apps/mlflow/.env index f9da0a69f..2a6b96ac4 100644 --- a/apps/mlflow/.env +++ b/apps/mlflow/.env @@ -1,16 +1,37 @@ -W9_ID='mlflow' -W9_REPO=ghcr.io/mlflow/mlflow -W9_DIST='community' -W9_VERSION='v3.1.4' +W9_REPO=ghcr.io/mlflow/mlflow +W9_DIST=community +W9_VERSION=v3.17.1 -#### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_HTTP_PORT=5000 -W9_HTTP_PORT_SET='9001' -W9_URL='example.youdomain.com' +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=mlflow +W9_HTTP_PORT=5000 +W9_HTTP_PORT_SET=9001 +W9_URL=example.youdomain.com W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### -# ENV for Mlflow: https://mlflow.org/docs/latest/cli.html#mlflow-server +#### ----------------------------------------------------------------------------------------- #### +# ============================================================ +# MLflow image environment variables +# Docs: https://mlflow.org/docs/latest/cli.html#mlflow-server +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: MLFLOW_HOME=/workspaces/mlflow MLFLOW_TRACKING_URI=sqlite:////workspaces/mlflow/mlruns.db +# MLflow 3.x rejects Host headers it does not allow; the public host is unknown +# at package time, so allow all hosts (see docs/w9-env-spec.md). +MLFLOW_SERVER_ALLOWED_HOSTS=* + +# Not used by default; enable only when needed: +# MLFLOW_SERVER_CORS_ALLOWED_ORIGINS= +# MLFLOW_SERVER_WORKERS=4 +# MLFLOW_SERVER_WORKER_CONNECTIONS=1000 +# MLFLOW_SERVER_TIMEOUT=60 diff --git a/apps/mlflow/CHANGELOG.md b/apps/mlflow/CHANGELOG.md index 11da4a100..385ea5287 100644 --- a/apps/mlflow/CHANGELOG.md +++ b/apps/mlflow/CHANGELOG.md @@ -1,7 +1,15 @@ # CHANGELOG -## Release +## 2026-10-14 -### Fixes and Enhancements +- Updated MLflow from `v3.1.4` to `v3.17.1`, the latest stable upstream release. +- Aligned `.env` with the current repository layout, normalized variable references, and documented the MLflow server environment section. +- Set `MLFLOW_SERVER_ALLOWED_HOSTS=*` so the MLflow 3.x DNS-rebinding protection does not reject access through the public host or IP. +- Removed the dead `build` named volume that over-mounted the image's bundled frontend assets, and dropped the obsolete compose `version` key. +- Added `tests/cases.yml` with a `/health` reachability check. +- Added upstream releases, compose, and docs references to `variables.json`. +- Regenerated `README.md` from `variables.json`. -2024-12-27 first Release +## 2024-12-27 + +- First release. diff --git a/apps/mlflow/README.md b/apps/mlflow/README.md index 695e1826f..2c2eaca9b 100644 --- a/apps/mlflow/README.md +++ b/apps/mlflow/README.md @@ -1,26 +1,90 @@ -# MLflow on Docker +# MLflow on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for MLflow: +## Quick Start +### Deploy Verification - - community: v2.19.0, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **MLflow**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the MLflow admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://mlflow.org/docs/latest/index.html): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 2 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this MLflow by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [MLflow Docker image](https://github.com/mlflow/mlflow/pkgs/container/mlflow) and makes some improvements below. -If you want use MLflow with **Websoft9 Business Support** free, you can [subscribe MLflow](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[MLflow Administrator Guide](https://support.websoft9.com/docs/mlflow) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v3.17.1, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| MLflow Web UI and REST API | 5000 | + + +### Data Directory + + +Data is persisted in the `mlflow_data` volume, mounted at `/workspaces/mlflow`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [MLflow Administrator Guide](https://support.websoft9.com/docs/mlflow) by Websoft9 + +- [Docker Hub image](https://github.com/mlflow/mlflow/pkgs/container/mlflow) + +- [Releases](https://github.com/mlflow/mlflow/releases) + +- [Official compose](https://raw.githubusercontent.com/mlflow/mlflow/v3.17.1/docker-compose/docker-compose.yml) + +- [Official env example](https://raw.githubusercontent.com/mlflow/mlflow/v3.17.1/docker-compose/.env.dev.example) + +- [Official docs](https://mlflow.org/docs/latest/self-hosting/index.html) + +- [Official docs](https://mlflow.org/docs/latest/cli.html#mlflow-server) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/mlflow/docker-compose.yml b/apps/mlflow/docker-compose.yml index d9959556b..b7b289232 100644 --- a/apps/mlflow/docker-compose.yml +++ b/apps/mlflow/docker-compose.yml @@ -1,27 +1,19 @@ -# image: https://github.com/mlflow/mlflow/pkgs/container/mlflow -# compose: https://github.com/mlflow/mlflow/blob/master/.devcontainer/docker-compose.yml - -version: '3.8' - services: mlflow: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} working_dir: /workspaces/mlflow command: ["sh", "-c", "mlflow server --host 0.0.0.0 --port 5000"] env_file: .env ports: - - $W9_HTTP_PORT_SET:5000 + - "${W9_HTTP_PORT_SET}:5000" # MLflow Web UI and REST API volumes: - mlflow_data:/workspaces/mlflow - - build:/workspaces/mlflow/mlflow/server/js/build volumes: - build: mlflow_data: networks: default: name: ${W9_NETWORK} external: true - diff --git a/apps/mlflow/tests/cases.yml b/apps/mlflow/tests/cases.yml new file mode 100644 index 000000000..8d56ab5aa --- /dev/null +++ b/apps/mlflow/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: health-endpoint + type: web-access + path: /health + expect_status: 200 diff --git a/apps/mlflow/variables.json b/apps/mlflow/variables.json index 16827dd65..ab0bb726d 100644 --- a/apps/mlflow/variables.json +++ b/apps/mlflow/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "v3.1.4", + "v3.17.1", "latest" ] } @@ -24,6 +24,15 @@ "disk": "2" }, "upstream": { - "image": "https://github.com/mlflow/mlflow/pkgs/container/mlflow" + "image": "https://github.com/mlflow/mlflow/pkgs/container/mlflow", + "releases": "https://github.com/mlflow/mlflow/releases", + "compose": { + "compose": "https://raw.githubusercontent.com/mlflow/mlflow/v3.17.1/docker-compose/docker-compose.yml", + "env": "https://raw.githubusercontent.com/mlflow/mlflow/v3.17.1/docker-compose/.env.dev.example" + }, + "docs": [ + "https://mlflow.org/docs/latest/self-hosting/index.html", + "https://mlflow.org/docs/latest/cli.html#mlflow-server" + ] } } diff --git a/apps/modsecurity/Notes.md b/apps/modsecurity/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/apps/modsecurity/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/apps/n8n/.env b/apps/n8n/.env index 81c430e05..05da45854 100644 --- a/apps/n8n/.env +++ b/apps/n8n/.env @@ -1,6 +1,6 @@ W9_REPO=n8nio/n8n W9_DIST=community -W9_VERSION=2.38.4 +W9_VERSION=2.43.4 W9_POWER_PASSWORD="bk!ctOA2xJ2ur0AB" # Canonical semantics live in docs/w9-env-spec.md. diff --git a/apps/n8n/CHANGELOG.md b/apps/n8n/CHANGELOG.md index 0652dcc8a..9a46dd120 100644 --- a/apps/n8n/CHANGELOG.md +++ b/apps/n8n/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 2026-10-12 +- Updated n8n to `2.43.4`. +- Added app-local functional test metadata for deploy validation. + ## 2026-09-08 - Updated n8n to `2.38.4`. - Replaced deprecated `WEBHOOK_URL` with `N8N_WEBHOOK_URL` and added `N8N_PROXY_HOPS=1` for reverse-proxy deployments. diff --git a/apps/n8n/README.md b/apps/n8n/README.md index 236dfcac6..9f0ddca9d 100644 --- a/apps/n8n/README.md +++ b/apps/n8n/README.md @@ -37,7 +37,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 2.38.4, latest. +Supported versions: 2.43.4, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. @@ -72,7 +72,7 @@ Configuration files live inside the image; mount a single file read-only to over - [Docker Hub image](https://hub.docker.com/r/n8nio/n8n) -- [Releases](https://github.com/n8n-io/n8n/releases/tag/n8n%402.38.4) +- [Releases](https://github.com/n8n-io/n8n) - [Official docs](https://docs.n8n.io/deploy/host-n8n/install-options/install-with-docker.md) diff --git a/apps/n8n/tests/cases.yml b/apps/n8n/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/n8n/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/n8n/variables.json b/apps/n8n/variables.json index 4d6b57ed4..62d603444 100644 --- a/apps/n8n/variables.json +++ b/apps/n8n/variables.json @@ -15,7 +15,7 @@ { "dist": "community", "version": [ - "2.38.4", + "2.43.4", "latest" ] } diff --git a/apps/neo4j/.env b/apps/neo4j/.env index 62ef3c2fa..d467c8dfc 100644 --- a/apps/neo4j/.env +++ b/apps/neo4j/.env @@ -1,6 +1,6 @@ W9_REPO=neo4j W9_DIST=community -W9_VERSION=2026.07 +W9_VERSION=2026.09 # Optional password seed: enable only when the package actually controls a DB or built-in login. # See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. diff --git a/apps/neo4j/CHANGELOG.md b/apps/neo4j/CHANGELOG.md index 95800b09a..60fa617c7 100644 --- a/apps/neo4j/CHANGELOG.md +++ b/apps/neo4j/CHANGELOG.md @@ -1,3 +1,8 @@ +## 2026-10-12 + +- Updated Neo4j from the floating `2026.07` line to the floating `2026.09` line. +- Refreshed the published release-note reference and added app-local functional test metadata for deploy validation. + ## 2026-09-08 - Updated Neo4j from `5.26.5` to the floating `2026.07` line and reduced the published version set to `2026.07`, `2026.07-enterprise`, `5.26`, and `5.26-enterprise`. diff --git a/apps/neo4j/README.md b/apps/neo4j/README.md index c86d76dd9..a894e8ec4 100644 --- a/apps/neo4j/README.md +++ b/apps/neo4j/README.md @@ -29,16 +29,16 @@ Note: the Connection URL is resolved from your browser directly to the Bolt port Websoft9 packages this app from the official [Neo4j Docker image](https://hub.docker.com/_/neo4j) and makes some improvements below. -This package tracks the current Neo4j `2026.07` release line with the official Docker image and persists database state in `/data`, which matches the current upstream Docker guidance. +This package tracks the current Neo4j `2026.09` release line with the official Docker image and persists database state in `/data`, which matches the current upstream Docker guidance. -Upstream release notes explicitly warn against using `2026.07.0` because of a data-readability bug in `trim()`. This package therefore publishes the floating `2026.07` tag instead of pinning the bad `2026.07.0` patch. +This package publishes the floating `2026.09` tag so upstream patch updates within the `2026.09` line can be adopted without changing the package shape. Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 2026.07, 2026.07-enterprise, 5.26, 5.26-enterprise. +Supported versions: 2026.09, 2026.09-enterprise, 5.26, 5.26-enterprise. ### Ports @@ -77,7 +77,7 @@ Configuration files live inside the image; mount a single file read-only to over - [Official docs](https://neo4j.com/docs/operations-manual/current/docker/introduction/) -- [Official docs](https://neo4j.com/release-notes/database/neo4j-2026-07-1/) +- [Official docs](https://neo4j.com/release-notes/database/neo4j-2026-09-0/) diff --git a/apps/neo4j/tests/cases.yml b/apps/neo4j/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/neo4j/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/neo4j/variables.json b/apps/neo4j/variables.json index ee65591e8..ee2dba8fb 100644 --- a/apps/neo4j/variables.json +++ b/apps/neo4j/variables.json @@ -6,8 +6,8 @@ { "dist": "community", "version": [ - "2026.07", - "2026.07-enterprise", + "2026.09", + "2026.09-enterprise", "5.26", "5.26-enterprise" ] @@ -30,7 +30,7 @@ "releases": "https://neo4j.com/release-notes/database/", "docs": [ "https://neo4j.com/docs/operations-manual/current/docker/introduction/", - "https://neo4j.com/release-notes/database/neo4j-2026-07-1/" + "https://neo4j.com/release-notes/database/neo4j-2026-09-0/" ] }, "env": { diff --git a/apps/nextcloud/.env b/apps/nextcloud/.env index c6238cc10..58db4ca0f 100644 --- a/apps/nextcloud/.env +++ b/apps/nextcloud/.env @@ -1,6 +1,6 @@ W9_REPO=nextcloud W9_DIST=community -W9_VERSION=34.0 +W9_VERSION=35.0 W9_POWER_PASSWORD="36Q2xMTiRPZ!NlLR" # Canonical semantics live in docs/w9-env-spec.md. diff --git a/apps/nextcloud/CHANGELOG.md b/apps/nextcloud/CHANGELOG.md index 932d2e09f..343f65566 100644 --- a/apps/nextcloud/CHANGELOG.md +++ b/apps/nextcloud/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-12 +- Updated Nextcloud to `35.0`. +- Kept the bundled MySQL image on `8.4`, which remains supported by Nextcloud 35. +- Added app-local functional test metadata for deploy validation. + ## 2026-09-08 - Updated Nextcloud to `34.0`. - Updated the bundled MySQL image from `8.0` to `8.4`. diff --git a/apps/nextcloud/README.md b/apps/nextcloud/README.md index 0ab44aaa9..ca3344eca 100644 --- a/apps/nextcloud/README.md +++ b/apps/nextcloud/README.md @@ -37,7 +37,7 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 34.0, latest. +Supported versions: 35.0, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. diff --git a/apps/nextcloud/tests/cases.yml b/apps/nextcloud/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/nextcloud/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/nextcloud/variables.json b/apps/nextcloud/variables.json index d902eeb93..892efffe1 100644 --- a/apps/nextcloud/variables.json +++ b/apps/nextcloud/variables.json @@ -14,7 +14,7 @@ { "dist": "community", "version": [ - "34.0", + "35.0", "latest" ] } @@ -38,6 +38,6 @@ ] }, "help": { - "db": "Nextcloud 34 supports MySQL 8.4 / 9.7 and MariaDB 10.11+. This package bundles MySQL 8.4 for a single-node deployment." + "db": "Nextcloud 35 supports MySQL 8.4 / 9.7 and MariaDB 10.11+. This package bundles MySQL 8.4 for a single-node deployment." } } diff --git a/apps/nexterm/Notes.md b/apps/nexterm/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/apps/nexterm/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/apps/nextjs/.env b/apps/nextjs/.env index 443e9a9d8..800f4c780 100644 --- a/apps/nextjs/.env +++ b/apps/nextjs/.env @@ -1,6 +1,6 @@ W9_REPO=node W9_DIST=community -W9_VERSION=16.3.5 +W9_VERSION=16.4.0 # Canonical semantics live in docs/w9-env-spec.md. # This template controls layout; the spec controls meaning and decision rules. diff --git a/apps/nextjs/CHANGELOG.md b/apps/nextjs/CHANGELOG.md index dfaa082a5..c9141b93a 100644 --- a/apps/nextjs/CHANGELOG.md +++ b/apps/nextjs/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## 2026-10-12 + +- Updated the default Next.js scaffold version to `16.4.0`. +- Kept the runtime package shape unchanged so existing user projects still build and start the same way. + ## 2026-09-15 - Added the initial Next.js runtime package, based on the official Node image. diff --git a/apps/nextjs/README.md b/apps/nextjs/README.md index f749f2f61..e8b8d6649 100644 --- a/apps/nextjs/README.md +++ b/apps/nextjs/README.md @@ -6,7 +6,7 @@ 1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Next.js**. 2. In the **Access** tab, get the login URL and credentials. -3. Open the login URL in a browser and confirm the app works. +3. Open the login URL in a browser and sign in to confirm the app works. ### Usage @@ -41,40 +41,58 @@ Apps run as containers; rebuild after any configuration change. ### Version Support -Supported versions: 16.3.5, latest. +Supported versions: 16.4.0, latest. The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + ### Ports | Purpose | Port | | --- | --- | | Web Console | 3000 | + ### Data Directory + Data is persisted in the `nextjs_app` volume, mounted at `/usr/src/app`. + ### Environment Variables Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + Note: `NEXTJS_CREATE_FLAGS`, `NEXTJS_PACKAGE_MANAGER` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + ### Configuration Files -Configuration is overridden by mounting `./src/entrypoint.sh` to `/usr/local/bin/entrypoint.sh`. + +- `./src/entrypoint.sh` → `/opt/websoft9/entrypoint.sh` +- `./src/entrypoint.d` → `/opt/websoft9/entrypoint.d` +- `./src/start.sh` → `/opt/websoft9/start.sh` + + ## References - [Next.js Administrator Guide](https://support.websoft9.com/docs/nextjs) by Websoft9 + - [Docker Hub image](https://github.com/vercel/next.js) + - [Releases](https://github.com/vercel/next.js/releases) + - [Official docs](https://nextjs.org/docs/app/getting-started/installation) + - [Official docs](https://nextjs.org/docs/app/getting-started/deploying) + - [Official docs](https://nextjs.org/docs/app/guides/self-hosting) + - [Official docs](https://hub.docker.com/_/node) + ## Troubleshooting diff --git a/apps/nextjs/variables.json b/apps/nextjs/variables.json index 97b4525a9..596ac7d5e 100644 --- a/apps/nextjs/variables.json +++ b/apps/nextjs/variables.json @@ -16,7 +16,7 @@ { "dist": "community", "version": [ - "16.3.5", + "16.4.0", "latest" ] } diff --git a/apps/nginx/.env b/apps/nginx/.env index 619fc116a..a521beb57 100644 --- a/apps/nginx/.env +++ b/apps/nginx/.env @@ -1,10 +1,32 @@ -W9_DIST='community' +W9_DIST=community W9_REPO=nginx -W9_VERSION='1.29' +W9_VERSION=1.31 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='nginx' -W9_HTTP_PORT_SET='9001' +W9_ID=nginx +W9_HTTP_PORT_SET=9001 W9_HTTP_PORT=80 -W9_URL='appname.example.com' +W9_URL=appname.example.com W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# NGINX image environment variables +# Docs: https://hub.docker.com/_/nginx +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# APP_VAR_1= +# APP_VAR_2= +# APP_VAR_3= +# APP_VAR_4= +# APP_VAR_5= diff --git a/apps/nginx/CHANGELOG.md b/apps/nginx/CHANGELOG.md index 582cf46c5..d02fe0ab4 100644 --- a/apps/nginx/CHANGELOG.md +++ b/apps/nginx/CHANGELOG.md @@ -1,5 +1,8 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 + +- Updated NGINX to `1.31`. +- Aligned `.env`, `docker-compose.yml`, and upstream metadata with current repository policy. +- Fixed the startup helper script condition so the default demo page can be created correctly on first boot. diff --git a/apps/nginx/Notes.md b/apps/nginx/Notes.md deleted file mode 100644 index e8d36d705..000000000 --- a/apps/nginx/Notes.md +++ /dev/null @@ -1 +0,0 @@ -# NGINX diff --git a/apps/nginx/README.md b/apps/nginx/README.md index 2b19d3c3a..003fc1839 100644 --- a/apps/nginx/README.md +++ b/apps/nginx/README.md @@ -1,26 +1,86 @@ -# NGINX on Docker +# NGINX on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for NGINX: +## Quick Start +### Deploy Verification - - community: 1.28, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **NGINX**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the NGINX admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://github.com/nginx/docker#recommended-system-requirements): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this NGINX by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [NGINX Docker image](https://hub.docker.com/_/nginx) and makes some improvements below. -If you want use NGINX with **Websoft9 Business Support** free, you can [subscribe NGINX](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[NGINX Administrator Guide](https://support.websoft9.com/docs/nginx) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 1.31, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 80 | + + +### Data Directory + + +Data is kept inside the container; a named volume is recommended for persistence. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +- `./src/default.conf` → `/etc/nginx/conf.d/default.conf` +- `./src/cmd.sh` → `/usr/local/bin/cmd.sh` + + + +## References + +- [NGINX Administrator Guide](https://support.websoft9.com/docs/nginx) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/nginx) + +- [Official docs](https://hub.docker.com/_/nginx) + +- [GitHub docs](https://github.com/nginx/docker-nginx) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/nginx/docker-compose.yml b/apps/nginx/docker-compose.yml index 64ca3e05b..1eaa1e2ed 100644 --- a/apps/nginx/docker-compose.yml +++ b/apps/nginx/docker-compose.yml @@ -1,23 +1,18 @@ -# image: https://hub.docker.com/_/nginx -# docs: https://github.com/nginxinc/docker-nginx - -version: '3.8' - services: nginx: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} env_file: - .env restart: unless-stopped working_dir: /usr/share/nginx/html ports: - - "$W9_HTTP_PORT_SET:80" + - "${W9_HTTP_PORT_SET}:80" # Web Console volumes: - site:/usr/share/nginx/html # Add your html site - ./src/default.conf:/etc/nginx/conf.d/default.conf - ./src/cmd.sh:/usr/local/bin/cmd.sh - command: /bin/bash -c "bash /usr/local/bin/cmd.sh && nginx -g 'daemon off;'" + command: /bin/bash -c "bash /usr/local/bin/cmd.sh && nginx -g 'daemon off;'" networks: default: @@ -25,4 +20,4 @@ networks: external: true volumes: - site: \ No newline at end of file + site: diff --git a/apps/nginx/src/cmd.sh b/apps/nginx/src/cmd.sh index a3f8872e4..67332e612 100644 --- a/apps/nginx/src/cmd.sh +++ b/apps/nginx/src/cmd.sh @@ -1,7 +1,7 @@ ### Default Demo which you can delete it echo "Add your CI code here, below is example" -if [! -e /usr/share/nginx/html/index.html ]; then +if [ ! -e /usr/share/nginx/html/index.html ]; then echo "Hello, Nginx!" > /usr/share/nginx/html/index.html fi diff --git a/apps/nginx/tests/cases.yml b/apps/nginx/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/nginx/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/nginx/variables.json b/apps/nginx/variables.json index bcdcfdee7..e409e48ae 100644 --- a/apps/nginx/variables.json +++ b/apps/nginx/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "1.29", + "1.31", "latest" ] } @@ -24,6 +24,10 @@ "disk": "1" }, "upstream": { - "image": "https://hub.docker.com/_/nginx" + "image": "https://hub.docker.com/_/nginx", + "docs": [ + "https://hub.docker.com/_/nginx", + "https://github.com/nginx/docker-nginx" + ] } } diff --git a/apps/nginxproxymanager/.env b/apps/nginxproxymanager/.env index 5372573af..a015f09dd 100644 --- a/apps/nginxproxymanager/.env +++ b/apps/nginxproxymanager/.env @@ -1,9 +1,31 @@ -W9_POWER_PASSWORD=changeme -W9_NAME=nginxproxymanager -W9_VERSION=latest -W9_HTTP_PORT=9001 -W9_LOGIN_USER=admin@example.com -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD +W9_REPO=jc21/nginx-proxy-manager +W9_DIST=community +W9_VERSION=2.16.0 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=nginxproxymanager +W9_HTTP_PORT=81 +W9_HTTP_PORT_SET=9001 +W9_HTTPS_PORT=443 +W9_HTTPS_PORT_SET=9443 +W9_URL=appname.example.com W9_NETWORK=websoft9 -W9_URL_REPLACE=false -W9_URL=appname.example.com \ No newline at end of file + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Nginx Proxy Manager image environment variables +# Docs: https://nginxproxymanager.com/guide/#quick-setup +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: + +# Not used by default; enable only when needed: +# TZ=UTC diff --git a/apps/nginxproxymanager/CHANGELOG.md b/apps/nginxproxymanager/CHANGELOG.md index 582cf46c5..94589e287 100644 --- a/apps/nginxproxymanager/CHANGELOG.md +++ b/apps/nginxproxymanager/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 +- Updated Nginx Proxy Manager to `2.16.0`. +- Rebuilt the package metadata and env layout to current repository conventions. +- Replaced misleading runtime login envs with declarative default-credential metadata matching the upstream first-login screen. diff --git a/apps/nginxproxymanager/Notes.md b/apps/nginxproxymanager/Notes.md deleted file mode 100644 index c4e4c187b..000000000 --- a/apps/nginxproxymanager/Notes.md +++ /dev/null @@ -1,29 +0,0 @@ -# Appname - - -https://nginxproxymanager.com - -## FAQ - -#### 如何额外给 Location 增加指令? - -直接把指令复制到设置框(通过 location 【齿轮】图标打开) - -![image](https://user-images.githubusercontent.com/16741975/198959861-cf09f148-2b7a-42bc-8a43-35882668e974.png) - -#### 如何给主 proxy 增加指令? - -1. 额外增加一个 / location -2. 填写所需的指令 - -#### IP 地址是否可以增加 HTTPS? - -不可以,Nginxproxymanager 申请证书的时候会报错 - -#### Advanced 设置作用域? - -server 级作用域,非 / location - -#### Nginx proxy Manger 如何支持静态网站? - -可以支持,具体参考:[Host a Static Site on NGINX Proxy Manager (NPM)](https://dimensionquest.net/2021/02/host-static-site-on-npm/) diff --git a/apps/nginxproxymanager/README.md b/apps/nginxproxymanager/README.md index 95e0db1cb..01fceedab 100644 --- a/apps/nginxproxymanager/README.md +++ b/apps/nginxproxymanager/README.md @@ -1,26 +1,89 @@ -# Nginx Proxy Manager on Docker +# Nginx Proxy Manager on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Nginx Proxy Manager: +## Quick Start +### Deploy Verification - - community: 2.10.4, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Nginx Proxy Manager**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Nginx Proxy Manager admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://hub.docker.com/r/jc21/nginx-proxy-manager/): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Nginx Proxy Manager by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Nginx Proxy Manager Docker image](https://hub.docker.com/r/jc21/nginx-proxy-manager) and makes some improvements below. -If you want use Nginx Proxy Manager with **Websoft9 Business Support** free, you can [subscribe Nginx Proxy Manager](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Nginx Proxy Manager Administrator Guide](https://support.websoft9.com/docs/nginxmanager) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 2.16.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 81 | +| HTTPS Proxy | 443 | + + +### Data Directory + + +- `nginx_data` → `/data` +- `nginx_letsencrypt` → `/etc/letsencrypt` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Nginx Proxy Manager Administrator Guide](https://support.websoft9.com/docs/nginxproxymanager) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/jc21/nginx-proxy-manager) + +- [Releases](https://github.com/NginxProxyManager/nginx-proxy-manager/releases) + +- [Official docs](https://nginxproxymanager.com/guide/#quick-setup) + +- [GitHub docs](https://github.com/NginxProxyManager/nginx-proxy-manager/releases/tag/v2.16.0) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/nginxproxymanager/docker-compose.yml b/apps/nginxproxymanager/docker-compose.yml index 4826b770d..fe77ec845 100644 --- a/apps/nginxproxymanager/docker-compose.yml +++ b/apps/nginxproxymanager/docker-compose.yml @@ -1,17 +1,13 @@ -# image: https://hub.docker.com/r/jc21/nginx-proxy-manager -# docs: https://nginxproxymanager.com/guide/#quick-setup - -version: '3.8' - services: app: - image: jc21/nginx-proxy-manager:${W9_VERSION} + image: ${W9_REPO}:${W9_VERSION} restart: unless-stopped - container_name: ${W9_NAME} + container_name: ${W9_ID} + env_file: + - .env ports: - - '80:80' - - '${W9_HTTP_PORT}:81' - - '443:443' + - "${W9_HTTP_PORT_SET}:81" # Web Console + - "${W9_HTTPS_PORT_SET}:443" # HTTPS Proxy volumes: - nginx_data:/data - nginx_letsencrypt:/etc/letsencrypt diff --git a/apps/nginxproxymanager/tests/cases.yml b/apps/nginxproxymanager/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/nginxproxymanager/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/nginxproxymanager/variables.json b/apps/nginxproxymanager/variables.json index d0a99d316..6a8906772 100644 --- a/apps/nginxproxymanager/variables.json +++ b/apps/nginxproxymanager/variables.json @@ -1,12 +1,12 @@ { - "name": "nginxmanager", + "name": "nginxproxymanager", "trademark": "Nginx Proxy Manager", - "release": false, + "release": true, "edition": [ { "dist": "community", "version": [ - "2.10.4", + "2.16.0", "latest" ] } @@ -22,5 +22,23 @@ "cpu": "1", "memory": "1", "disk": "1" + }, + "upstream": { + "image": "https://hub.docker.com/r/jc21/nginx-proxy-manager", + "releases": "https://github.com/NginxProxyManager/nginx-proxy-manager/releases", + "docs": [ + "https://nginxproxymanager.com/guide/#quick-setup", + "https://github.com/NginxProxyManager/nginx-proxy-manager/releases/tag/v2.16.0" + ] + }, + "credentials": { + "username": { + "source": "inline", + "value": "admin@example.com" + }, + "password": { + "source": "inline", + "value": "changeme" + } } } diff --git a/apps/nifi/.env b/apps/nifi/.env index 8fa71fd05..ed80f5d1a 100644 --- a/apps/nifi/.env +++ b/apps/nifi/.env @@ -1,53 +1,50 @@ -W9_REPO="wordpress" +W9_REPO=apache/nifi W9_DIST=community -W9_VERSION="latest" +W9_VERSION=2.12.0 +# Optional password seed: enabled because this package controls the initial NiFi single-user login. W9_POWER_PASSWORD="1PrMxExC45LsCT" -# Environments which for user settings when create application -# Named expression: W9_xxx_xxx_SET, xxx refer to file fields -W9_HTTP_PORT_SET=9001 -# W9_HTTPS_PORT_SET=9002 -# W9_DB_PORT_SET=3306 -# W9_SSH_PORT_SET=23 -W9_KEY_SET="dfsjdkjf77xjxcjcj" +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### W9_ID=nifi - -# W9_HTTP_PORT or W9_HTTPS_PORT is need at leaset and used for proxy for web application -# Some container (e.g teleport) need HTTPS access, then need to set this pra -W9_HTTP_PORT=80 -W9_HTTPS_PORT=81 - +W9_HTTPS_PORT=8443 +W9_HTTPS_PORT_SET=9001 W9_LOGIN_USER=admin -# use https://1password.com/zh-cn/password-generator/ to genarate 14 bit password -# this password can also use password file -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_ADMIN_PATH="/wp-login" - -# Container name's suffix must use one of the value -W9_DB_EXPOSE="mysql,postgresql,mariadb,mongodb,redis" - -# It is used when the application APP needs to set an external URL, which can be IP(or domain), IP:PORT -# If have protocols, should be set it in the APP's ENV -W9_URL=example.youdomain.com -# modifies W9_URL on init when it is true +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +W9_ADMIN_PATH=/nifi +W9_URL=appname.example.com W9_URL_REPLACE=true - W9_NETWORK=websoft9 #### ----------------------------------------------------------------------------------------- #### - -# Below environment is created by this app - -WORDPRESS_DB_HOST=$W9_ID-mariadb -WORDPRESS_DB_USER=wordpress #if use postgresql, it need set to postgres -WORDPRESS_DB_PASSWORD=$W9_POWER_PASSWORD -WORDPRESS_DB_NAME=wordpress - - -#W9_NAME="" -#W9_RCODE="" \ No newline at end of file +# ============================================================ +# Apache NiFi image environment variables +# Docs: https://github.com/apache/nifi/tree/main/nifi-docker/dockerhub +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +# Follow the official Docker default secured mode: NiFi serves the UI over HTTPS here. +# This package is validated for HTTPS access and does not support switching the UI to plain HTTP. +NIFI_WEB_HTTPS_PORT=${W9_HTTPS_PORT} +SINGLE_USER_CREDENTIALS_USERNAME=${W9_LOGIN_USER} +SINGLE_USER_CREDENTIALS_PASSWORD=${W9_LOGIN_PASSWORD} +NIFI_JVM_HEAP_INIT=1g +NIFI_JVM_HEAP_MAX=1g +# NiFi validates Host/X-ProxyHost values in secure mode. +# Do not use 0.0.0.0 here: set the real public hostname, and add hostname:port when direct HTTPS port access is needed. +NIFI_WEB_PROXY_HOST=${W9_URL},${W9_URL}:${W9_HTTPS_PORT_SET} +NIFI_WEB_PROXY_CONTEXT_PATH=/nifi + +# Not used by default; enable only when needed: +# NIFI_WEB_HTTPS_HOST=${W9_URL} +# Keep HTTP disabled in this package. Enabling NIFI_WEB_HTTP_* requires redesigning the package and re-validating proxy behavior. +# NIFI_WEB_HTTP_HOST=0.0.0.0 +# NIFI_WEB_HTTP_PORT=8080 diff --git a/apps/nifi/CHANGELOG.md b/apps/nifi/CHANGELOG.md index 582cf46c5..415f23ca1 100644 --- a/apps/nifi/CHANGELOG.md +++ b/apps/nifi/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 +- Rebuilt the broken NiFi package from the official `apache/nifi` Docker image. +- Switched the package to the current secure single-container HTTPS deployment model with single-user authentication. +- Added app-local HTTPS validation coverage and current upstream metadata. diff --git a/apps/nifi/Notes.md b/apps/nifi/Notes.md index 1fdbbb29d..a4876c11d 100644 --- a/apps/nifi/Notes.md +++ b/apps/nifi/Notes.md @@ -1,2 +1,6 @@ -# Appname -## FAQ +# Apache NiFi + +- This package follows the official Docker image's default HTTPS and single-user authentication flow. +- HTTP is intentionally not enabled in this package; validate and redesign the proxy path before changing NiFi to plain HTTP. +- The browser will report a self-signed certificate on first access unless the deployment is customized with trusted certificates. +- `NIFI_WEB_PROXY_HOST` must use the real external hostname; add `hostname:port` when direct HTTPS port access is expected. diff --git a/apps/nifi/README.md b/apps/nifi/README.md index 985fe8466..8a73b855c 100644 --- a/apps/nifi/README.md +++ b/apps/nifi/README.md @@ -1,26 +1,95 @@ -# Apache NiFi on Docker +# Apache NiFi on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Apache NiFi: +## Quick Start +### Deploy Verification - - community: latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Apache NiFi**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Apache NiFi admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://nifi.apache.org): +### Change Password -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Apache NiFi by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Apache NiFi Docker image](https://hub.docker.com/r/apache/nifi) and makes some improvements below. -If you want use Apache NiFi with **Websoft9 Business Support** free, you can [subscribe Apache NiFi](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Apache NiFi Administrator Guide](https://support.websoft9.com/docs/nifi) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 2.12.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console (HTTPS) | 8443 | + + +### Data Directory + + +- `nifi_conf` → `/opt/nifi/nifi-current/conf` +- `nifi_state` → `/opt/nifi/nifi-current/state` +- `nifi_logs` → `/opt/nifi/nifi-current/logs` +- `nifi_database` → `/opt/nifi/nifi-current/database_repository` +- `nifi_flowfile` → `/opt/nifi/nifi-current/flowfile_repository` +- `nifi_content` → `/opt/nifi/nifi-current/content_repository` +- `nifi_provenance` → `/opt/nifi/nifi-current/provenance_repository` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Apache NiFi Administrator Guide](https://support.websoft9.com/docs/nifi) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/apache/nifi) + +- [Releases](https://github.com/apache/nifi/releases) + +- [GitHub docs](https://github.com/apache/nifi/tree/main/nifi-docker/dockerhub) + +- [Official docs](https://nifi.apache.org/documentation/nifi-latest/html/administration-guide.html) + +- [GitHub docs](https://github.com/apache/nifi/releases/tag/rel/nifi-2.12.0) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/nifi/docker-compose.yml b/apps/nifi/docker-compose.yml index 1c1948688..325edef5a 100644 --- a/apps/nifi/docker-compose.yml +++ b/apps/nifi/docker-compose.yml @@ -1,50 +1,32 @@ -# image,docs: https://hub.docker.com/_/wordpress/ - services: - - wordpress: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID + nifi: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + hostname: ${W9_URL} restart: unless-stopped - #This is for access host from container - # extra_hosts: ["host.docker.internal:host-gateway"] - # command: | - # /bin/bash -c "ping -c 3 host.docker.internal" - logging: - driver: "json-file" - options: - max-file: "5" - max-size: 10m - deploy: - resources: - limits: - memory: 5g - cpus: '0.7' + env_file: + - .env ports: - - $W9_HTTP_PORT_SET:80 - env_file: .env - volumes: - - wordpress:/var/www/html - - ./src/php_exra.ini:/usr/local/etc/php/conf.d/php_exra.ini - - mariadb: - image: mariadb:10.4 - container_name: $W9_ID-mariadb - restart: unless-stopped - command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_log_buffer_size=30M + - "${W9_HTTPS_PORT_SET}:8443" # Web Console (HTTPS) volumes: - - mysql_data:/var/lib/mysql - environment: - MYSQL_DATABASE: $WORDPRESS_DB_NAME - MYSQL_USER: $WORDPRESS_DB_USER - MYSQL_PASSWORD: $W9_POWER_PASSWORD - MYSQL_ROOT_PASSWORD: $W9_POWER_PASSWORD + - nifi_conf:/opt/nifi/nifi-current/conf + - nifi_state:/opt/nifi/nifi-current/state + - nifi_logs:/opt/nifi/nifi-current/logs + - nifi_database:/opt/nifi/nifi-current/database_repository + - nifi_flowfile:/opt/nifi/nifi-current/flowfile_repository + - nifi_content:/opt/nifi/nifi-current/content_repository + - nifi_provenance:/opt/nifi/nifi-current/provenance_repository volumes: - wordpress: - mysql_data: - + nifi_conf: + nifi_state: + nifi_logs: + nifi_database: + nifi_flowfile: + nifi_content: + nifi_provenance: + networks: default: - name: $W9_NETWORK + name: ${W9_NETWORK} external: true diff --git a/apps/nifi/src/nginx-proxy.conf.template b/apps/nifi/src/nginx-proxy.conf.template deleted file mode 100644 index 951364ffe..000000000 --- a/apps/nifi/src/nginx-proxy.conf.template +++ /dev/null @@ -1,57 +0,0 @@ -proxy_busy_buffers_size 512k; -proxy_buffers 4 512k; -proxy_buffer_size 256k; -client_max_body_size 50m; -# override default location / -location / { - add_header X-Served-By $host; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass $forward_scheme://$server:$port$request_uri; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection upgrade; - } - -location /console { - proxy_pass http://$server:8080; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -# for echo some useful information -location / { - default_type text/plain; - return 200 'Hello World'; -} - -location /oida/ { -# this is the address and port of the ORDS installation -proxy_pass http://127.0.0.1:8080/ords/; - -# set Origin to blank to avoid Chrome problems with CORS -proxy_set_header Origin "" ; - -# pass along some header variables with the public host name/port/and so on -proxy_set_header Host $host; -proxy_set_header X-Forwarded-Host $host:$server_port; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $scheme; - -# this reverse proxies any "location" headers being passed in the response -proxy_redirect http://$host/ords/ https://$host/oida/; - -# also tell cookies their public path -proxy_cookie_path /ords/ /oida/; - -# reverse proxy links included in response (ie from ORDS webservice) -sub_filter_types application/json ; -sub_filter http://$host/ords/ https://$host/oida/; -sub_filter_once off; -} diff --git a/apps/nifi/src/php_exra.ini b/apps/nifi/src/php_exra.ini deleted file mode 100644 index b253d5718..000000000 --- a/apps/nifi/src/php_exra.ini +++ /dev/null @@ -1,8 +0,0 @@ -file_uploads = On -max_input_time = 800 -max_execution_time = 300 -memory_limit = 600M -upload_max_filesize = 900M -post_max_size = 900M -max_file_uploads = 200 -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT \ No newline at end of file diff --git a/apps/nifi/tests/cases.yml b/apps/nifi/tests/cases.yml new file mode 100644 index 000000000..ad34e9aad --- /dev/null +++ b/apps/nifi/tests/cases.yml @@ -0,0 +1,7 @@ +skip: + - id: web-access + +custom: + - id: https-login-page + type: script + script: check-https-login.sh diff --git a/apps/nifi/tests/check-https-login.sh b/apps/nifi/tests/check-https-login.sh new file mode 100644 index 000000000..b1103752e --- /dev/null +++ b/apps/nifi/tests/check-https-login.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +tmp_file="$(mktemp)" +trap 'rm -f "${tmp_file}"' EXIT + +base_url="${BASE_URL:-}" +if [ -z "${base_url}" ]; then + base_url="https://localhost:${W9_HTTPS_PORT_SET}" +fi + +curl -ksSL "${base_url}" -o "${tmp_file}" +grep -Eiq 'Apache NiFi|NiFi' "${tmp_file}" diff --git a/apps/nifi/variables.json b/apps/nifi/variables.json index eeb947a73..e93871590 100644 --- a/apps/nifi/variables.json +++ b/apps/nifi/variables.json @@ -1,21 +1,38 @@ { "name": "nifi", "trademark": "Apache NiFi", - "release": false, + "release": true, + "upstream": { + "image": "https://hub.docker.com/r/apache/nifi", + "releases": "https://github.com/apache/nifi/releases", + "docs": [ + "https://github.com/apache/nifi/tree/main/nifi-docker/dockerhub", + "https://nifi.apache.org/documentation/nifi-latest/html/administration-guide.html", + "https://github.com/apache/nifi/releases/tag/rel/nifi-2.12.0" + ] + }, "edition": [ { "dist": "community", "version": [ + "2.12.0", "latest" ] } ], + "access": { + "defaultScheme": "https", + "web": { + "port": 8443, + "path": "/nifi" + } + }, "requirements": { "cpu": "2", "memory": "4", "disk": "10" }, - "upstream": { - "image": "https://hub.docker.com/r/apache/nifi" + "help": { + "login": "Apache NiFi starts with HTTPS and single-user authentication. The browser will show a certificate warning on first access because the container generates a self-signed certificate by default." } } diff --git a/apps/nodejs/.env b/apps/nodejs/.env index c77379659..16066e041 100644 --- a/apps/nodejs/.env +++ b/apps/nodejs/.env @@ -1,14 +1,32 @@ W9_REPO=node -W9_DIST='community' -W9_VERSION='24' +W9_DIST=community +W9_VERSION=26 + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='nodejs' -W9_HTTP_PORT_SET='9001' +W9_ID=nodejs +W9_HTTP_PORT_SET=9001 # replace this with your application's port W9_HTTP_PORT=8080 -W9_URL='sample.domain.com' -W9_URL_REPLACE=true +W9_URL=appname.example.com W9_NETWORK=websoft9 + #### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Node.js image environment variables +# Docs: https://hub.docker.com/_/node +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +NODE_ENV=production + +# Not used by default; enable only when needed: +# APP_VAR_1= +# APP_VAR_2= diff --git a/apps/nodejs/CHANGELOG.md b/apps/nodejs/CHANGELOG.md index 582cf46c5..0e6c96fd4 100644 --- a/apps/nodejs/CHANGELOG.md +++ b/apps/nodejs/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-12 +- Updated the default Node.js runtime image tag to `26` and added the `26-alpine` and `26-slim` variants to the published version list. +- Aligned `.env`, `docker-compose.yml`, and upstream metadata with current repository policy. +- Simplified the startup command so the container exits with the demo process instead of idling on a fallback tail. diff --git a/apps/nodejs/README.md b/apps/nodejs/README.md index e348f9f36..1b4b82dd0 100644 --- a/apps/nodejs/README.md +++ b/apps/nodejs/README.md @@ -1,26 +1,80 @@ -# Node.js on Docker +# Node.js on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Node.js: +## Quick Start +### Deploy Verification - - community: 23, 23-alpine, 23-slim, 22, 22-alpine, 22-slim, 21, 21-alpine, 21-slim, 20, 20-alpine, 20-slim, 19, 19-alpine, 19-slim, 18, 18-alpine, 18-slim, 17, 17-alpine, 17-slim +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Node.js**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Node.js admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://github.com/nodejs/docker-node): +### Change Password -* **RAM**: 1 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Node.js by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Node.js Docker image](https://hub.docker.com/_/node) and makes some improvements below. -If you want use Node.js with **Websoft9 Business Support** free, you can [subscribe Node.js](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Node.js Administrator Guide](https://support.websoft9.com/docs/nodejs) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 26, 26-alpine, 26-slim, 24, 23, 23-alpine, 23-slim, 22, 22-alpine, 22-slim, 21, 21-alpine, 21-slim, 20, 20-alpine, 20-slim, 19, 19-alpine, 19-slim, 18, 18-alpine, 18-slim, 17, 17-alpine, 17-slim. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 8080 | + + +### Data Directory + + +Data is persisted in the `app` volume, mounted at `/usr/src/app`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/cmd.sh` to `/usr/src/app/cmd.sh`. + + +## References + +- [Node.js Administrator Guide](https://support.websoft9.com/docs/nodejs) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/_/node) + +- [Official docs](https://hub.docker.com/_/node) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/nodejs/docker-compose.yml b/apps/nodejs/docker-compose.yml index a3beabebb..ca460aaf7 100644 --- a/apps/nodejs/docker-compose.yml +++ b/apps/nodejs/docker-compose.yml @@ -1,11 +1,3 @@ -# image: https://hub.docker.com/_/node - -# Once you have install application at /home/node/app, you should check the correct application path, maybe /home/node/app or /home/node/app/folder -# make sure set working_dir to your correct application path -# make sure enable and set command to correct value - -version: '3.8' - services: node: image: ${W9_REPO}:${W9_VERSION} @@ -13,14 +5,14 @@ services: restart: unless-stopped env_file: .env working_dir: /usr/src/app - volumes: + volumes: - app:/usr/src/app - ./src/cmd.sh:/usr/src/app/cmd.sh - command: /bin/bash -c "bash /usr/src/app/cmd.sh && tail -f /dev/null" + command: /bin/bash /usr/src/app/cmd.sh environment: - - NODE_ENV=production + NODE_ENV: ${NODE_ENV} ports: - - $W9_HTTP_PORT_SET:$W9_HTTP_PORT # replace this with your application's default port + - "${W9_HTTP_PORT_SET}:8080" # Web Console tty: true volumes: @@ -29,4 +21,4 @@ volumes: networks: default: name: ${W9_NETWORK} - external: true \ No newline at end of file + external: true diff --git a/apps/nodejs/src/cmd.sh b/apps/nodejs/src/cmd.sh index 658d9d220..0882581ec 100644 --- a/apps/nodejs/src/cmd.sh +++ b/apps/nodejs/src/cmd.sh @@ -1,3 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + echo "Add your CI code here, below is example" cat > app.js < { }); EOF -node app.js +exec node app.js ## Sample One: Express @@ -46,4 +49,4 @@ node app.js # cd classic && yarn install # #3 Running for test -# npm run start -- --host 0.0.0.0 --port 8080 \ No newline at end of file +# npm run start -- --host 0.0.0.0 --port 8080 diff --git a/apps/nodejs/tests/cases.yml b/apps/nodejs/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/nodejs/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/nodejs/variables.json b/apps/nodejs/variables.json index 8edcdd001..9675e7b7d 100644 --- a/apps/nodejs/variables.json +++ b/apps/nodejs/variables.json @@ -6,6 +6,9 @@ { "dist": "community", "version": [ + "26", + "26-alpine", + "26-slim", "24", "23", "23-alpine", @@ -37,7 +40,10 @@ "disk": "1" }, "upstream": { - "image": "https://hub.docker.com/_/node" + "image": "https://hub.docker.com/_/node", + "docs": [ + "https://hub.docker.com/_/node" + ] }, "access": { "defaultScheme": "http", diff --git a/apps/nodered/.env b/apps/nodered/.env index 7d29d3d3b..e8de253d2 100644 --- a/apps/nodered/.env +++ b/apps/nodered/.env @@ -1,21 +1,33 @@ -W9_VERSION='4.1' -W9_DIST='community' +W9_VERSION=5.0 +W9_DIST=community W9_REPO=nodered/node-red +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + #### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='nodered' +W9_ID=nodered W9_HTTP_PORT=1880 -W9_HTTP_PORT_SET='9001' -W9_URL='appname.example.com' +W9_HTTP_PORT_SET=9001 +W9_URL=appname.example.com W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### -# Below is environments of Node-Red -# env docs: https://nodered.org/docs/getting-started/docker#startup -# config_file:/data/settings.js +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Node-RED image environment variables +# Docs: https://nodered.org/docs/getting-started/docker +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: TZ=Europe/Amsterdam NODE_OPTIONS=--max_old_space_size=128 NODE_RED_ENABLE_SAFE_MODE=false NODE_RED_ENABLE_PROJECTS=false -#FLOWS=my_flows.json + +# Not used by default; enable only when needed: +# FLOWS=my_flows.json diff --git a/apps/nodered/CHANGELOG.md b/apps/nodered/CHANGELOG.md index 4591f22ad..c91579ba2 100644 --- a/apps/nodered/CHANGELOG.md +++ b/apps/nodered/CHANGELOG.md @@ -1,2 +1,7 @@ # CHANGELOG +## 2026-10-12 + +- Updated Node-RED to `5.0`. +- Aligned `.env`, `docker-compose.yml`, and upstream metadata with current repository policy. +- Added app-local functional test metadata for deploy validation. diff --git a/apps/nodered/README.md b/apps/nodered/README.md index 3bf406f5e..70249e3bf 100644 --- a/apps/nodered/README.md +++ b/apps/nodered/README.md @@ -1,26 +1,86 @@ -# Node-RED on Docker +# Node-RED on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Node-RED: +## Quick Start +### Deploy Verification - - community: 4.0, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Node-RED**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Node-RED admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://nodered.org/docs/getting-started/docker): +### Change Password -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Node-RED by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Node-RED Docker image](https://hub.docker.com/r/nodered/node-red) and makes some improvements below. -If you want use Node-RED with **Websoft9 Business Support** free, you can [subscribe Node-RED](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Node-RED Administrator Guide](https://support.websoft9.com/docs/nodered) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 5.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 1880 | + + +### Data Directory + + +Data is persisted in the `nodered_data` volume, mounted at `/data`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Node-RED Administrator Guide](https://support.websoft9.com/docs/nodered) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/nodered/node-red) + +- [Releases](https://github.com/node-red/node-red/releases) + +- [Official docs](https://nodered.org/docs/getting-started/docker) + +- [GitHub docs](https://github.com/node-red/node-red/releases/tag/5.0.0) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/nodered/docker-compose.yml b/apps/nodered/docker-compose.yml index 0295733b4..7f7c78c31 100644 --- a/apps/nodered/docker-compose.yml +++ b/apps/nodered/docker-compose.yml @@ -1,17 +1,12 @@ -# image: https://hub.docker.com/r/nodered/node-red -# docs: https://nodered.org/docs/getting-started/docker - -version: "3.8" - services: nodered: image: ${W9_REPO}:${W9_VERSION} container_name: ${W9_ID} ports: - - ${W9_HTTP_PORT_SET}:1880 + - "${W9_HTTP_PORT_SET}:1880" # Web Console volumes: - nodered_data:/data - #- ./src/my_flows.json:/data/my_flows.json + # - ./src/my_flows.json:/data/my_flows.json env_file: .env restart: unless-stopped diff --git a/apps/nodered/tests/cases.yml b/apps/nodered/tests/cases.yml new file mode 100644 index 000000000..2d0b1aad2 --- /dev/null +++ b/apps/nodered/tests/cases.yml @@ -0,0 +1 @@ +optional: [] diff --git a/apps/nodered/variables.json b/apps/nodered/variables.json index f157f02da..c979b5d2b 100644 --- a/apps/nodered/variables.json +++ b/apps/nodered/variables.json @@ -6,7 +6,7 @@ { "dist": "community", "version": [ - "4.1", + "5.0", "latest" ] } @@ -24,6 +24,11 @@ "disk": "1" }, "upstream": { - "image": "https://hub.docker.com/r/nodered/node-red" + "image": "https://hub.docker.com/r/nodered/node-red", + "releases": "https://github.com/node-red/node-red/releases", + "docs": [ + "https://nodered.org/docs/getting-started/docker", + "https://github.com/node-red/node-red/releases/tag/5.0.0" + ] } } diff --git a/apps/nomad/Notes.md b/apps/nomad/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/apps/nomad/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/apps/nomad/src/nginx-proxy.conf.template b/apps/nomad/src/nginx-proxy.conf.template deleted file mode 100644 index 951364ffe..000000000 --- a/apps/nomad/src/nginx-proxy.conf.template +++ /dev/null @@ -1,57 +0,0 @@ -proxy_busy_buffers_size 512k; -proxy_buffers 4 512k; -proxy_buffer_size 256k; -client_max_body_size 50m; -# override default location / -location / { - add_header X-Served-By $host; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass $forward_scheme://$server:$port$request_uri; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection upgrade; - } - -location /console { - proxy_pass http://$server:8080; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -# for echo some useful information -location / { - default_type text/plain; - return 200 'Hello World'; -} - -location /oida/ { -# this is the address and port of the ORDS installation -proxy_pass http://127.0.0.1:8080/ords/; - -# set Origin to blank to avoid Chrome problems with CORS -proxy_set_header Origin "" ; - -# pass along some header variables with the public host name/port/and so on -proxy_set_header Host $host; -proxy_set_header X-Forwarded-Host $host:$server_port; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $scheme; - -# this reverse proxies any "location" headers being passed in the response -proxy_redirect http://$host/ords/ https://$host/oida/; - -# also tell cookies their public path -proxy_cookie_path /ords/ /oida/; - -# reverse proxy links included in response (ie from ORDS webservice) -sub_filter_types application/json ; -sub_filter http://$host/ords/ https://$host/oida/; -sub_filter_once off; -} diff --git a/apps/nomad/src/php_exra.ini b/apps/nomad/src/php_exra.ini deleted file mode 100644 index b253d5718..000000000 --- a/apps/nomad/src/php_exra.ini +++ /dev/null @@ -1,8 +0,0 @@ -file_uploads = On -max_input_time = 800 -max_execution_time = 300 -memory_limit = 600M -upload_max_filesize = 900M -post_max_size = 900M -max_file_uploads = 200 -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT \ No newline at end of file diff --git a/apps/openclaw/Notes.md b/apps/openclaw/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/apps/openclaw/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/apps/openhands/Notes.md b/apps/openhands/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/apps/openhands/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/apps/oracle/.env b/apps/oracle/.env index bc4a468be..41c240306 100644 --- a/apps/oracle/.env +++ b/apps/oracle/.env @@ -1,16 +1,17 @@ -# ORACLE_EDITION only for Oracle enterprise image, includes: enterprise/standard -# enterprise image support: #enterprise/standard -# when enterprise edtion, version includes [latest,21.3.0.0,19.3.0.0,12.2.0.1] -# when express edtion, version includes [latest,21.3.0-xe,18.4.0-xe] -W9_POWER_PASSWORD=X14eTpm7LjDGZT -W9_VERSION=latest W9_REPO=container-registry.oracle.com/database/express W9_DIST=community +W9_VERSION=latest + +W9_POWER_PASSWORD=X14eTpm7LjDGZT + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. #### -- Not allowed to edit below environments when recreate app based on existing data -- #### + W9_ID=oracle -# this is Oracle EM port +# Oracle Enterprise Manager (EM) port W9_HTTPS_PORT=5500 W9_HTTPS_PORT_SET=5500 W9_ADMIN_PATH="/em" @@ -19,20 +20,29 @@ W9_DB_PORT=1521 W9_DB_PORT_SET=1521 W9_LOGIN_USER=sys -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} W9_LOGIN_Oracle_SID=XE W9_LOGIN_Oracle_PDB=XEPDB1 W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### - -# envrionments for express and enterprise -ORACLE_CHARACTERSET=AL32UTF8 -ORACLE_PWD=$W9_POWER_PASSWORD - -# Below environments only for express references, can not be used for image -ORACLE_EX_SID=XE -ORACLE_EX_PDB=XEPDB1 +#### ----------------------------------------------------------------------------------------- #### +# ============================================================ +# Oracle Database image environment variables +# Docs: https://container-registry.oracle.com/ords/f?p=113:10:::::: +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ +# Used by docker-compose.yml: +ORACLE_CHARACTERSET=AL32UTF8 +ORACLE_PWD=${W9_POWER_PASSWORD} + +# Not used by default; enable only when needed: +# ORACLE_EDITION=enterprise +# ORACLE_SID=XE +# ORACLE_PDB=XEPDB1 +# ORACLE_BASE=/opt/oracle +# ORACLE_HOME=/opt/oracle/product/21c/dbhomeXE diff --git a/apps/oracle/CHANGELOG.md b/apps/oracle/CHANGELOG.md index 582cf46c5..8a98f05ef 100644 --- a/apps/oracle/CHANGELOG.md +++ b/apps/oracle/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG -## Release -### Fixes and Enhancements +## 2026-10-14 +- No new upstream Oracle XE release is available; `container-registry.oracle.com/database/express` still publishes only `21.3.0-xe`, `18.4.0-xe`, and `latest`. +- Refreshed the package for current repository rules: normalized `.env` variable references to `${VAR}`, aligned the `.env` section layout, and documented the Oracle image environment section. +- Removed the obsolete compose `version` key and the legacy `# image:` / `# docs:` source comments, and added inline purpose comments to the published database and EM ports in `docker-compose.yml`. +- Added `tests/cases.yml` with a database listener check, since Oracle XE exposes no HTTP surface on `W9_HTTP_PORT_SET`. +- Regenerated `README.md` from `variables.json`. diff --git a/apps/oracle/README.md b/apps/oracle/README.md index e26fd6026..2fdc9375d 100644 --- a/apps/oracle/README.md +++ b/apps/oracle/README.md @@ -1,26 +1,81 @@ -# Oracle Database on Docker +# Oracle Database on Docker -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Oracle Database: +## Quick Start +### Deploy Verification - - community: 21.3.0-xe, 18.4.0-xe, latest +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Oracle Database**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + +### Usage -## System Requirements +1. Make sure you are signed in to the Oracle Database admin console. +2. Try a core feature. -The following are the minimal [recommended requirements](https://container-registry.oracle.com/): +### Change Password -* **RAM**: 8 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 1 GB of free space -* **bandwidth**: more fluent experience over 100M +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + -## Install +## Configuration Reference -You can install this Oracle Database by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). +Websoft9 packages this app from the official [Oracle Database Docker image](https://container-registry.oracle.com/ords/ocr/ba/database/express) and makes some improvements below. -If you want use Oracle Database with **Websoft9 Business Support** free, you can [subscribe Oracle Database](https://www.websoft9.com/apps) on Cloud platform + -## Documentation + -[Oracle Database Administrator Guide](https://support.websoft9.com/docs/oracle) powered by Websoft9 \ No newline at end of file +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: 21.3.0-xe, 18.4.0-xe, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Oracle database listener (SQL*Net) | 1521 | +| Oracle Enterprise Manager (EM) console | 5500 | + + +### Data Directory + + +Data is persisted in the `data` volume, mounted at `/opt/oracle/oradata`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Oracle Database Administrator Guide](https://support.websoft9.com/docs/oracle) by Websoft9 + +- [Docker Hub image](https://container-registry.oracle.com/ords/ocr/ba/database/express) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/oracle/docker-compose.yml b/apps/oracle/docker-compose.yml index a6213aa3c..87561706d 100644 --- a/apps/oracle/docker-compose.yml +++ b/apps/oracle/docker-compose.yml @@ -1,18 +1,13 @@ -# image: https://container-registry.oracle.com/ords/f?p=113:10:::::: -# docs: http://docs.oracle.com/en/database/ - -version: '4.9.0' - services: oracleex: - image: $W9_REPO:${W9_VERSION} - container_name: ${W9_ID} + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} env_file: .env volumes: - data:/opt/oracle/oradata ports: - - ${W9_DB_PORT_SET}:1521 - - ${W9_HTTPS_PORT_SET}:5500 + - "${W9_DB_PORT_SET}:1521" # Oracle database listener (SQL*Net) + - "${W9_HTTPS_PORT_SET}:5500" # Oracle Enterprise Manager (EM) console restart: unless-stopped networks: diff --git a/apps/oracle/tests/cases.yml b/apps/oracle/tests/cases.yml new file mode 100644 index 000000000..8188f0ec9 --- /dev/null +++ b/apps/oracle/tests/cases.yml @@ -0,0 +1,7 @@ +# Oracle XE has no HTTP surface on W9_HTTP_PORT_SET, so the adaptive web-access +# check does not apply. Its core path is the database accepting connections, so +# a custom script polls the SQL*Net listener inside the container. +custom: + - id: db-listener + type: script + script: check.sh diff --git a/apps/oracle/tests/check.sh b/apps/oracle/tests/check.sh new file mode 100755 index 000000000..02f0a7397 --- /dev/null +++ b/apps/oracle/tests/check.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Oracle XE first boot initializes the database, which can take several minutes; +# custom cases are not auto-retried by the harness, so poll here. +set -u + +container="${W9_ID:?W9_ID is required}" + +deadline=$((SECONDS + 900)) +while [ "${SECONDS}" -lt "${deadline}" ]; do + if docker exec "${container}" bash -c 'exec 3<>/dev/tcp/127.0.0.1/1521' 2>/dev/null; then + echo "Oracle database listener is accepting connections on 1521" + exit 0 + fi + sleep 10 +done + +echo "Oracle database listener did not accept connections before timeout" >&2 +exit 1 diff --git a/apps/posthog/CHANGELOG.md b/apps/posthog/CHANGELOG.md deleted file mode 100644 index 411672483..000000000 --- a/apps/posthog/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# CHANGELOG - -## 2026-10-09 - -- Replaced the placeholder WordPress/Discuz files with a real PostHog self-hosted Compose package. -- Added PostHog upstream metadata, runtime environment wiring, and access metadata. -- Added compose helper scripts for PostHog startup and migration flow. diff --git a/apps/posthog/README.jinja2 b/apps/posthog/README.jinja2 deleted file mode 100644 index 8949cc4e0..000000000 --- a/apps/posthog/README.jinja2 +++ /dev/null @@ -1,26 +0,0 @@ -# {{trademark}} on Docker - -This is an **Docker Compose solution** powered by [Websoft9](https://www.websoft9.com) based on Docker for {{trademark}}: - -{% for ed in edition %} - - {{ed.dist}}: {{ ed.version | join(', ') }} -{% endfor %} - -## System Requirements - -The following are the minimal [recommended requirements]({{requirements.url}}): - -* **RAM**: {{requirements.memory}} GB or more -* **CPU**: {{requirements.cpu}} cores or higher -* **Disk**: at least {{requirements.disk}} GB of free space -* **bandwidth**: more fluent experience over 100M - -## Install - -You can install this {{trademark}} by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). - -If you want use {{trademark}} with **Websoft9 Business Support** free, you can [subscribe {{trademark}}](https://www.websoft9.com/apps) on Cloud platform - -## Documentation - -[{{trademark}} Administrator Guide](https://support.websoft9.com/docs/{{name}}) powered by Websoft9 diff --git a/apps/qwenpaw/.env b/apps/qwenpaw/.env new file mode 100644 index 000000000..09d14f1ba --- /dev/null +++ b/apps/qwenpaw/.env @@ -0,0 +1,57 @@ +W9_REPO=agentscope/qwenpaw +W9_DIST=community +W9_VERSION=latest + +# Optional password seed: enable only when the package actually controls a DB or built-in login. +# See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. +# The Hub first administrator is seeded from W9_LOGIN_USER / W9_LOGIN_PASSWORD on first startup. +W9_POWER_PASSWORD="1HW5NWMtfiA1A6jRKo9T" + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=qwenpaw + +# Web/internal ports: uncomment the ones the package actually uses. +W9_HTTP_PORT=8000 +W9_HTTP_PORT_SET=9001 + +# Built-in login and URL helpers: keep these in the protected block because the appstore parser +# reads them from the app package metadata surface. +W9_LOGIN_USER=admin +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} +# Use a domain-style placeholder for W9_URL, e.g. appname.example.com or example.youdomain.com. +# Do NOT use internet_ip:${W9_HTTP_PORT_SET}; host substitution is the consumer's concern. +W9_URL=qwenpaw.example.com +W9_URL_REPLACE=true + +W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +#W9_NAME="" +#W9_RCODE="" + +# ============================================================ +# QwenPaw Hub image environment variables +# Docs: https://qwenpaw.agentscope.io/docs/hub +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +QWENPAW_HUB_PUBLIC_BASE_URL=http://${W9_URL} +QWENPAW_HUB_ADMIN_USER=${W9_LOGIN_USER} +QWENPAW_HUB_ADMIN_PASSWORD=${W9_LOGIN_PASSWORD} +QWENPAW_HUB_REGISTRATION_MODE=open +QWENPAW_HUB_MAX_RUNTIMES=20 + +# Not used by default; enable only when needed: +# QWENPAW_HUB_PORT=8000 +# QWENPAW_HUB_LOG_LEVEL=info +# DASHSCOPE_API_KEY= +# QWENPAW_TOOL_GUARD_ENABLED=true +# QWENPAW_SKILL_SCAN_MODE=warn diff --git a/apps/qwenpaw/CHANGELOG.md b/apps/qwenpaw/CHANGELOG.md new file mode 100644 index 000000000..d41bfe1af --- /dev/null +++ b/apps/qwenpaw/CHANGELOG.md @@ -0,0 +1,9 @@ +# CHANGELOG + +## 2026-10-13 +- Initial QwenPaw community package: QwenPaw **Hub**, the multi-user control plane, so one address can host an administrator and multiple user runtimes. +- Use the official `agentscope/qwenpaw` image directly; no custom image is built. +- Add `src/hub-entrypoint.sh` to install the missing Hub control-plane `docker` SDK and `bubblewrap` on start, seed the first administrator from `W9_LOGIN_USER` / `W9_LOGIN_PASSWORD`, render `hub.yaml` with `public_base_url` from `W9_URL` and the Local backend, and run `qwenpaw hub` as a forced-public bind on port `8000`. +- Add `docker-compose.yml` publishing the Hub console on `${W9_HTTP_PORT_SET}:8000`, with `privileged: true`, the `qwenpaw_data` volume at `/app/working`, and an `/api/version` healthcheck. +- Declare `W9_URL` / `W9_URL_REPLACE=true` and add `QWENPAW_HUB_*` variables for base URL, admin seeding, registration mode, and capacity. +- Fill `variables.json` (upstream, access, requirements, first-startup env, help) and `tests/cases.yml`. diff --git a/apps/qwenpaw/README.md b/apps/qwenpaw/README.md new file mode 100644 index 000000000..5d321d80d --- /dev/null +++ b/apps/qwenpaw/README.md @@ -0,0 +1,107 @@ +# QwenPaw on Docker + +## Quick Start + +### Deploy Verification + +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **QwenPaw**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + + +### Usage + +1. Open the Hub URL from the **Access** tab and sign in with the packaged administrator account. +2. Go to **User Management** to create accounts, or let members register themselves (registration is `open` by default). +3. Each member signs in and gets a personal, isolated QwenPaw runtime. +4. In a personal Console, open **Settings → Models** to add a provider and API key or to select a local model. + +### Change Password + +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + + +## Configuration Reference + +Websoft9 packages this app from the official [QwenPaw Docker image](https://hub.docker.com/r/agentscope/qwenpaw) and makes some improvements below. + + +- This package runs **QwenPaw Hub**, the multi-user control plane, directly from the official `agentscope/qwenpaw` image. One web address serves an administrator and many per-user QwenPaw runtimes, each with separate workspaces, credentials, and conversations. +- The Hub console listens on port `8000` inside the container and is published through `W9_HTTP_PORT_SET`. `QWENPAW_HUB_PUBLIC_BASE_URL` is derived from `W9_URL` and must match the address users open in their browsers. +- The official image is the single-user Console image, so the container installs the Hub control-plane `docker` SDK and `bubblewrap` on startup when they are missing. The Local runtime backend therefore requires `privileged: true`. The first start needs network access and takes longer while these packages install. +- The first administrator is seeded from `W9_LOGIN_USER` / `W9_LOGIN_PASSWORD` on first startup only. Set `QWENPAW_HUB_REGISTRATION_MODE` (`open`, `invite`, or `closed`) to control self-registration; use `closed` and create accounts in **User Management** for a locked-down deployment. +- The upstream project marks Hub as an early release intended for trusted teams only, not for mutually untrusted users. + + +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| QwenPaw Hub console | 8000 | + + +### Data Directory + + +Data is persisted in the `qwenpaw_data` volume, mounted at `/app/working`. + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +Note: `QWENPAW_HUB_ADMIN_USER`, `QWENPAW_HUB_ADMIN_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + +### Configuration Files + + +Configuration is overridden by mounting `./src/hub-entrypoint.sh` to `/opt/qwenpaw/hub-entrypoint.sh`. + + +## References + +- [QwenPaw Administrator Guide](https://support.websoft9.com/docs/qwenpaw) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/agentscope/qwenpaw) + +- [Releases](https://github.com/agentscope-ai/QwenPaw/releases) + +- [Official compose](https://raw.githubusercontent.com/agentscope-ai/QwenPaw/main/docker-compose.yml) + +- [Official env example](https://qwenpaw.agentscope.io/docs/config) + +- [GitHub docs](https://github.com/agentscope-ai/QwenPaw) + +- [Official docs](https://qwenpaw.agentscope.io/docs/quickstart) + +- [Official docs](https://qwenpaw.agentscope.io/docs/hub) + + + +## Troubleshooting + +**App takes long on first start?** +- The container installs the Hub `docker` SDK and `bubblewrap` on first start; allow a few minutes and check `docker compose logs`. + +**App fails to start?** +- Check `docker compose logs`. + +**Cannot create or start a user runtime?** +- Confirm the container is running as privileged (needed for bubblewrap) and check the Hub **Runtimes** page for the latest error. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/qwenpaw/docker-compose.yml b/apps/qwenpaw/docker-compose.yml new file mode 100644 index 000000000..2ec1c1613 --- /dev/null +++ b/apps/qwenpaw/docker-compose.yml @@ -0,0 +1,30 @@ +services: + + qwenpaw: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + restart: unless-stopped + # The Hub Local runtime backend isolates each user runtime with bubblewrap, + # which needs user namespaces inside the container. + privileged: true + env_file: .env + command: ["sh", "/opt/qwenpaw/hub-entrypoint.sh"] + ports: + - "${W9_HTTP_PORT_SET}:8000" # QwenPaw Hub console + volumes: + - qwenpaw_data:/app/working + - ./src/hub-entrypoint.sh:/opt/qwenpaw/hub-entrypoint.sh:ro + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8000/api/version || exit 1"] + interval: 30s + timeout: 10s + retries: 10 + start_period: 180s + +volumes: + qwenpaw_data: + +networks: + default: + name: ${W9_NETWORK} + external: true diff --git a/apps/bigbluebutton/src/conf/sip_profiles/.gitkeep b/apps/qwenpaw/src/.gitkeep similarity index 100% rename from apps/bigbluebutton/src/conf/sip_profiles/.gitkeep rename to apps/qwenpaw/src/.gitkeep diff --git a/apps/qwenpaw/src/hub-entrypoint.sh b/apps/qwenpaw/src/hub-entrypoint.sh new file mode 100644 index 000000000..249017364 --- /dev/null +++ b/apps/qwenpaw/src/hub-entrypoint.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# Start QwenPaw Hub (multi-user control plane) from the official image with a +# package-managed first administrator and the Local runtime backend. +set -e + +export QWENPAW_WORKING_DIR="${QWENPAW_WORKING_DIR:-/app/working}" +export QWENPAW_HUB_DIR="${QWENPAW_HUB_DIR:-${QWENPAW_WORKING_DIR%/}/hub}" +HUB_CONFIG="${QWENPAW_WORKING_DIR%/}/hub.yaml" +export QWENPAW_HUB_CONFIG="${HUB_CONFIG}" +HUB_PORT="${QWENPAW_HUB_PORT:-8000}" + +export QWENPAW_HUB_ADMIN_USER="${QWENPAW_HUB_ADMIN_USER:-admin}" +export QWENPAW_HUB_ADMIN_PASSWORD="${QWENPAW_HUB_ADMIN_PASSWORD:-}" + +# The official image is the single-user Console image. It ships neither the +# Docker SDK that the Hub control plane imports at startup nor bubblewrap for +# the Local runtime backend, so install whatever is missing before booting Hub. +if ! python -c "import docker" >/dev/null 2>&1; then + echo "Installing the QwenPaw Hub control-plane dependency (docker SDK)..." + pip install --no-cache-dir "docker>=7.1.0,<8" +fi +if ! command -v bwrap >/dev/null 2>&1; then + echo "Installing bubblewrap for the Local runtime backend..." + apt-get update \ + && apt-get install -y --no-install-recommends bubblewrap \ + && rm -rf /var/lib/apt/lists/* +fi + +mkdir -p "${QWENPAW_HUB_DIR}" + +# Seed the first administrator once (the first registered account becomes the +# Hub administrator) and render the startup config. Both steps are done in +# Python so the same script works across QwenPaw Hub releases whose CLI and +# registration config schema differ. +python - <<'PY' +import json +import os +from pathlib import Path + +from qwenpaw.hub.auth import HubAuthService +from qwenpaw.hub.control_app import get_hub_root +from qwenpaw.hub.credentials import TenantCredentialVault +from qwenpaw.hub import config as hub_config + +root = Path(get_hub_root()) +root.mkdir(parents=True, exist_ok=True) +database_path = root / "control.db" +vault = TenantCredentialVault(database_path, root / "secrets" / ".vault_key") +auth = HubAuthService(database_path, vault) + +if not auth.has_enabled_admin(): + username = os.environ["QWENPAW_HUB_ADMIN_USER"] + password = os.environ["QWENPAW_HUB_ADMIN_PASSWORD"] + if not password: + raise SystemExit("QWENPAW_HUB_ADMIN_PASSWORD is required on first startup") + auth.register(username, password) + print(f"Initialized the first QwenPaw Hub administrator: {username}") + +registration: dict[str, object] = {} +registration_fields = hub_config.RegistrationConfig.model_fields +if "mode" in registration_fields: + registration["mode"] = os.environ.get("QWENPAW_HUB_REGISTRATION_MODE", "open") +elif "enabled" in registration_fields: + registration["enabled"] = ( + os.environ.get("QWENPAW_HUB_REGISTRATION_MODE", "open") != "closed" + ) +if "default_role" in registration_fields: + registration["default_role"] = "user" + +config = { + "version": 1, + "control_plane": { + "public_base_url": os.environ["QWENPAW_HUB_PUBLIC_BASE_URL"], + "registration": registration, + }, + "runtime": {"provisioner": "local"}, + "capacity": { + "max_running_runtimes": int(os.environ.get("QWENPAW_HUB_MAX_RUNTIMES", "20")), + }, +} +# Hub accepts YAML; JSON is a subset of YAML, so no extra dependency is needed. +Path(os.environ["QWENPAW_HUB_CONFIG"]).write_text( + json.dumps(config, indent=2) + "\n", + encoding="utf-8", +) +print("Rendered Hub startup config with public_base_url and Local runtime backend.") +PY + +exec qwenpaw hub \ + --host 0.0.0.0 \ + --port "${HUB_PORT}" \ + --force-public \ + --config "${HUB_CONFIG}" \ + --log-level "${QWENPAW_HUB_LOG_LEVEL:-info}" diff --git a/apps/qwenpaw/tests/cases.yml b/apps/qwenpaw/tests/cases.yml new file mode 100644 index 000000000..0373c75c9 --- /dev/null +++ b/apps/qwenpaw/tests/cases.yml @@ -0,0 +1,13 @@ +# The default adaptive checks already cover compose-config, container-up, +# container-healthy (the packaged /api/version healthcheck), and the Hub root +# path. Add app-specific checks for the public control-plane API so the +# multi-user entry path is exercised explicitly. +optional: + - id: hub-api-version + type: web-access + path: /api/version + expect_status: 200 + - id: hub-auth-status + type: web-access + path: /api/auth/status + expect_status: 200 diff --git a/apps/qwenpaw/variables.json b/apps/qwenpaw/variables.json new file mode 100644 index 000000000..13f1dd719 --- /dev/null +++ b/apps/qwenpaw/variables.json @@ -0,0 +1,46 @@ +{ + "name": "qwenpaw", + "trademark": "QwenPaw", + "release": true, + "upstream": { + "image": "https://hub.docker.com/r/agentscope/qwenpaw", + "releases": "https://github.com/agentscope-ai/QwenPaw/releases", + "compose": { + "compose": "https://raw.githubusercontent.com/agentscope-ai/QwenPaw/main/docker-compose.yml", + "env": "https://qwenpaw.agentscope.io/docs/config" + }, + "docs": [ + "https://github.com/agentscope-ai/QwenPaw", + "https://qwenpaw.agentscope.io/docs/quickstart", + "https://qwenpaw.agentscope.io/docs/hub" + ] + }, + "edition": [ + { + "dist": "community", + "version": ["latest"] + } + ], + "access": { + "defaultScheme": "http", + "web": { + "port": 8000, + "path": "/" + } + }, + "requirements": { + "cpu": "4", + "memory": "8", + "disk": "20" + }, + "credentials": {}, + "env": { + "first_startup_only": [ + "QWENPAW_HUB_ADMIN_USER", + "QWENPAW_HUB_ADMIN_PASSWORD" + ] + }, + "help": { + "db": "No bundled database. QwenPaw Hub runs as one control-plane container from the official agentscope/qwenpaw image and provisions one isolated QwenPaw runtime per user with the Local backend; the control database and every user workspace persist under /app/working in the qwenpaw_data volume. The first administrator is seeded from W9_LOGIN_USER / W9_LOGIN_PASSWORD on first startup. Set QWENPAW_HUB_REGISTRATION_MODE to open, invite, or closed to control self-registration." + } +} diff --git a/apps/semaphore/.env b/apps/semaphore/.env deleted file mode 100644 index 1fc57fece..000000000 --- a/apps/semaphore/.env +++ /dev/null @@ -1,31 +0,0 @@ -W9_DIST='community' -W9_VERSION='v2.16.31' -W9_REPO=semaphoreui/semaphore -W9_POWER_PASSWORD='UNeRv!ASZ!s4d1PX' - -#### -- Not allowed to edit below environments when recreate app based on existing data -- #### -W9_ID='semaphore' -W9_HTTP_PORT=3000 -W9_HTTP_PORT_SET='9001' -W9_DB_EXPOSE="mysql" -W9_DB_VERSION="8.0" -W9_LOGIN_USER=admin -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_URL='appname.example.com' -W9_NETWORK=websoft9 -#### --------------------------------------------------------------------------------------- #### - -## Semaphore official environment below -## more official environment refer to: https://docs.semui.co/administration-guide/installation#docker - -SEMAPHORE_DB_USER=semaphore -SEMAPHORE_DB_PASS=$W9_POWER_PASSWORD -SEMAPHORE_DB_HOST=$W9_ID-mysql -SEMAPHORE_DB_PORT=3306 -SEMAPHORE_DB_DIALECT=mysql -SEMAPHORE_DB=semaphore -SEMAPHORE_PLAYBOOK_PATH=/tmp/semaphore/ -SEMAPHORE_ADMIN_PASSWORD=$W9_POWER_PASSWORD -SEMAPHORE_ADMIN_NAME=admin -SEMAPHORE_ADMIN_EMAIL=admin@localhost.com -SEMAPHORE_ADMIN=admin diff --git a/apps/semaphore/CHANGELOG.md b/apps/semaphore/CHANGELOG.md deleted file mode 100644 index 582cf46c5..000000000 --- a/apps/semaphore/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# CHANGELOG - -## Release -### Fixes and Enhancements - diff --git a/apps/semaphore/Notes.md b/apps/semaphore/Notes.md deleted file mode 100644 index 8f5db8582..000000000 --- a/apps/semaphore/Notes.md +++ /dev/null @@ -1 +0,0 @@ -# Ansible Semaphore diff --git a/apps/semaphore/README.md b/apps/semaphore/README.md deleted file mode 100644 index 27e92f245..000000000 --- a/apps/semaphore/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Ansible Semaphore on Docker - -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Ansible Semaphore: - - - - community: v2.15.0, latest - - -## System Requirements - -The following are the minimal [recommended requirements](https://docs.semui.co/): - -* **RAM**: 2 GB or more -* **CPU**: 1 cores or higher -* **Disk**: at least 4 GB of free space -* **bandwidth**: more fluent experience over 100M - -## Install - -You can install this Ansible Semaphore by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). - -If you want use Ansible Semaphore with **Websoft9 Business Support** free, you can [subscribe Ansible Semaphore](https://www.websoft9.com/apps) on Cloud platform - -## Documentation - -[Ansible Semaphore Administrator Guide](https://support.websoft9.com/docs/semaphore) powered by Websoft9 \ No newline at end of file diff --git a/apps/semaphore/docker-compose.yml b/apps/semaphore/docker-compose.yml deleted file mode 100644 index cea07bb12..000000000 --- a/apps/semaphore/docker-compose.yml +++ /dev/null @@ -1,35 +0,0 @@ -# image: https://hub.docker.com/r/semaphoreui/semaphore -# compose: https://docs.semui.co/administration-guide/installation#docker -# docs: https://docs.semui.co/ - -version: "3.8" - -services: - mysql: - restart: unless-stopped - image: mysql:$W9_DB_VERSION - container_name: $W9_ID-mysql - volumes: - - mysql:/var/lib/mysql - environment: - MYSQL_DATABASE: semaphore - MYSQL_USER: semaphore - MYSQL_PASSWORD: $W9_POWER_PASSWORD - MYSQL_ROOT_PASSWORD: $W9_POWER_PASSWORD - semaphore: - restart: unless-stopped - container_name: $W9_ID - ports: - - $W9_HTTP_PORT_SET:3000 - image: semaphoreui/semaphore:$W9_VERSION - env_file: .env - depends_on: - - mysql - -volumes: - mysql: - -networks: - default: - name: ${W9_NETWORK} - external: true diff --git a/apps/semaphore/variables.json b/apps/semaphore/variables.json deleted file mode 100644 index 1e3b2aa0e..000000000 --- a/apps/semaphore/variables.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "semaphore", - "trademark": "Ansible Semaphore", - "release": true, - "edition": [ - { - "dist": "community", - "version": [ - "v2.16.31", - "latest" - ] - } - ], - "access": { - "defaultScheme": "http", - "web": { - "port": 3000, - "path": "/" - } - }, - "requirements": { - "cpu": "1", - "memory": "2", - "disk": "4" - }, - "upstream": { - "image": "https://hub.docker.com/r/semaphoreui/semaphore" - } -} diff --git a/apps/semaphoreui/.env b/apps/semaphoreui/.env new file mode 100644 index 000000000..ca23f370b --- /dev/null +++ b/apps/semaphoreui/.env @@ -0,0 +1,58 @@ +W9_REPO=semaphoreui/semaphore +W9_DIST=community +W9_VERSION=v2.19.16 + +# Optional password seed: enable only when the package actually controls a DB or built-in login. +# See docs/w9-env-spec.md for when W9_POWER_PASSWORD is appropriate. +W9_POWER_PASSWORD='UNeRv!ASZ!s4d1PX' + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=semaphoreui +W9_HTTP_PORT=3000 +W9_HTTP_PORT_SET=9001 + +W9_DB_EXPOSE=mysql +W9_DB_VERSION=8.0 + +# Built-in login: Semaphore UI creates this admin user on first start. +W9_LOGIN_USER=admin +W9_LOGIN_PASSWORD=${W9_POWER_PASSWORD} + +W9_URL=appname.example.com + +W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +# ============================================================ +# Semaphore UI image environment variables +# Docs: https://docs.semaphoreui.com/admin-guide/installation/docker +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +SEMAPHORE_DB_DIALECT=mysql +SEMAPHORE_DB_HOST=${W9_ID}-mysql +SEMAPHORE_DB_PORT=3306 +SEMAPHORE_DB_USER=semaphore +SEMAPHORE_DB_PASS=${W9_POWER_PASSWORD} +SEMAPHORE_DB=semaphore +SEMAPHORE_TMP_PATH=/tmp/semaphore +SEMAPHORE_ADMIN=${W9_LOGIN_USER} +SEMAPHORE_ADMIN_NAME=admin +SEMAPHORE_ADMIN_EMAIL=admin@localhost.com +SEMAPHORE_ADMIN_PASSWORD=${W9_LOGIN_PASSWORD} +SEMAPHORE_ACCESS_KEY_ENCRYPTION='8NfDK/jj3+j+VRo+2bqbuTpwNiFM77wDhkIgIM7nK+Q=' + +# Not used by default; enable only when needed: +# SEMAPHORE_WEB_ROOT=http://appname.example.com +# SEMAPHORE_LDAP_ACTIVATED=no +# SEMAPHORE_EMAIL_ALERT=no +# SEMAPHORE_TLS_ENABLED=no +# SEMAPHORE_PORT=:3000 diff --git a/apps/semaphoreui/CHANGELOG.md b/apps/semaphoreui/CHANGELOG.md new file mode 100644 index 000000000..f598637b1 --- /dev/null +++ b/apps/semaphoreui/CHANGELOG.md @@ -0,0 +1,9 @@ +# CHANGELOG + +## 2026-10-14 + +- Renamed the app package from `semaphore` to `semaphoreui`; the product name is now "Semaphore UI". +- Updated Semaphore UI from v2.16.31 to v2.19.16. +- Refreshed `.env` and `docker-compose.yml` to the current packaging policy (braced variable references, published-port purpose comment, `.env` layout contract). +- Replaced the removed `SEMAPHORE_PLAYBOOK_PATH` with `SEMAPHORE_TMP_PATH`; added the required `SEMAPHORE_ACCESS_KEY_ENCRYPTION` secret. +- Added an app-specific admin login check under `tests/`. diff --git a/apps/semaphoreui/Notes.md b/apps/semaphoreui/Notes.md new file mode 100644 index 000000000..7854919a4 --- /dev/null +++ b/apps/semaphoreui/Notes.md @@ -0,0 +1 @@ +# Semaphore UI diff --git a/apps/semaphoreui/README.md b/apps/semaphoreui/README.md new file mode 100644 index 000000000..648d79a4f --- /dev/null +++ b/apps/semaphoreui/README.md @@ -0,0 +1,89 @@ +# Semaphore UI on Docker + +## Quick Start + +### Deploy Verification + +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Semaphore UI**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + + +### Usage + +1. Make sure you are signed in to the Semaphore UI admin console. +2. Try a core feature. + +### Change Password + +1. In the [Websoft9](https://www.websoft9.com) console, open the app's **Compose** tab. +2. Update the password in `.env` and save. +3. Rebuild the app. + + +## Configuration Reference + +Websoft9 packages this app from the official [Semaphore UI Docker image](https://hub.docker.com/r/semaphoreui/semaphore) and makes some improvements below. + + + + + +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v2.19.16, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web Console | 3000 | + + +### Data Directory + + +- `semaphore` → `/var/lib/semaphore` +- `mysql` → `/var/lib/mysql` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +Note: `SEMAPHORE_ADMIN`, `SEMAPHORE_ADMIN_NAME`, `SEMAPHORE_ADMIN_EMAIL`, `SEMAPHORE_ADMIN_PASSWORD` take effect on first startup only; changing them after deployment may not take effect until the app is re-initialized. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Semaphore UI Administrator Guide](https://support.websoft9.com/docs/semaphoreui) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/semaphoreui/semaphore) + +- [Releases](https://github.com/semaphoreui/semaphore/releases) + +- [Official docs](https://docs.semaphoreui.com/) + + + +## Troubleshooting + +**App fails to start?** +- Check `docker compose logs`. + +**Port not reachable?** +- Ensure the firewall / security group allows the port. + diff --git a/apps/semaphoreui/docker-compose.yml b/apps/semaphoreui/docker-compose.yml new file mode 100644 index 000000000..41f2e2e08 --- /dev/null +++ b/apps/semaphoreui/docker-compose.yml @@ -0,0 +1,34 @@ +services: + semaphoreui: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + restart: unless-stopped + ports: + - "${W9_HTTP_PORT_SET}:3000" # Web Console + env_file: .env + volumes: + - semaphore:/var/lib/semaphore + depends_on: + - mysql + + mysql: + image: mysql:${W9_DB_VERSION} + container_name: ${W9_ID}-mysql + restart: unless-stopped + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci + volumes: + - mysql:/var/lib/mysql + environment: + MYSQL_DATABASE: semaphore + MYSQL_USER: semaphore + MYSQL_PASSWORD: ${W9_POWER_PASSWORD} + MYSQL_ROOT_PASSWORD: ${W9_POWER_PASSWORD} + +volumes: + semaphore: + mysql: + +networks: + default: + name: ${W9_NETWORK} + external: true diff --git a/apps/apache/src/README.md b/apps/semaphoreui/src/README.md similarity index 100% rename from apps/apache/src/README.md rename to apps/semaphoreui/src/README.md diff --git a/apps/semaphoreui/tests/cases.yml b/apps/semaphoreui/tests/cases.yml new file mode 100644 index 000000000..df8db7e06 --- /dev/null +++ b/apps/semaphoreui/tests/cases.yml @@ -0,0 +1,7 @@ +# The adaptive web-access check covers the Semaphore UI root entry path. +# This exercises the authenticated API with the built-in admin account that +# Semaphore UI creates on first start. +custom: + - id: admin-login + type: script + script: check.sh diff --git a/apps/semaphoreui/tests/check.sh b/apps/semaphoreui/tests/check.sh new file mode 100755 index 000000000..5322e4296 --- /dev/null +++ b/apps/semaphoreui/tests/check.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -euo pipefail + +base="${BASE_URL:-http://localhost:3000}" +user="${W9_LOGIN_USER:-admin}" +password="${W9_LOGIN_PASSWORD:-changeme}" + +deadline=$((SECONDS + 300)) +status="" +while [ "${SECONDS}" -lt "${deadline}" ]; do + status="$(curl -s -o /dev/null -w '%{http_code}' --max-time 15 \ + -H 'Content-Type: application/json' \ + --data "{\"auth\":\"${user}\",\"password\":\"${password}\"}" \ + "${base}/api/auth/login" || true)" + if [ "${status}" = "204" ]; then + echo "Semaphore UI admin login succeeded" + exit 0 + fi + sleep 5 +done + +echo "Semaphore UI admin login did not succeed before timeout (last status ${status:-none})" >&2 +exit 1 diff --git a/apps/semaphoreui/variables.json b/apps/semaphoreui/variables.json new file mode 100644 index 000000000..4a94b0c37 --- /dev/null +++ b/apps/semaphoreui/variables.json @@ -0,0 +1,44 @@ +{ + "name": "semaphoreui", + "trademark": "Semaphore UI", + "release": true, + "upstream": { + "image": "https://hub.docker.com/r/semaphoreui/semaphore", + "releases": "https://github.com/semaphoreui/semaphore/releases", + "docs": [ + "https://docs.semaphoreui.com/" + ] + }, + "edition": [ + { + "dist": "community", + "version": [ + "v2.19.16", + "latest" + ] + } + ], + "access": { + "defaultScheme": "http", + "web": { + "port": 3000, + "path": "/" + } + }, + "requirements": { + "cpu": "1", + "memory": "2", + "disk": "4" + }, + "env": { + "first_startup_only": [ + "SEMAPHORE_ADMIN", + "SEMAPHORE_ADMIN_NAME", + "SEMAPHORE_ADMIN_EMAIL", + "SEMAPHORE_ADMIN_PASSWORD" + ], + "secrets": [ + "SEMAPHORE_ACCESS_KEY_ENCRYPTION" + ] + } +} diff --git a/apps/xinference/.env b/apps/xinference/.env new file mode 100644 index 000000000..2ac5e7194 --- /dev/null +++ b/apps/xinference/.env @@ -0,0 +1,49 @@ +W9_REPO=xprobe/xinference +W9_DIST=community +W9_VERSION=v4.0.0 +# CPU-only hosts: use the CPU image tag (e.g. v4.0.0-cpu) and drop the GPU +# reservation in docker-compose.yml. + +# Canonical semantics live in docs/w9-env-spec.md. +# This template controls layout; the spec controls meaning and decision rules. + +#### -- Not allowed to edit below environments when recreate app based on existing data -- #### + +W9_ID=xinference + +# Web/internal ports: uncomment the ones the package actually uses. +W9_HTTP_PORT=9997 +W9_HTTP_PORT_SET=9001 + +# Built-in login and URL helpers: keep these in the protected block because the appstore parser +# reads them from the app package metadata surface. +# Use a domain-style placeholder for W9_URL, e.g. appname.example.com or example.youdomain.com. +W9_URL=xinference.example.com + +W9_NETWORK=websoft9 + +#### ----------------------------------------------------------------------------------------- #### + +#W9_NAME="" +#W9_RCODE="" + +# ============================================================ +# Xinference image environment variables +# Docs: https://inference.readthedocs.io/en/latest/getting_started/environments.html +# Follow docs/w9-env-spec.md when deciding which vars belong here. +# Enable the vars actually used in docker-compose.yml below; list up +# to 5 unused vars commented out. Full reference lives in the Docs URL. +# ============================================================ + +# Used by docker-compose.yml: +XINFERENCE_MODEL_SRC=auto +# Give the supervisor/worker handshake enough time on slow or busy hosts. +XINFERENCE_HEALTH_CHECK_TIMEOUT=60 +XINFERENCE_HEALTH_CHECK_INTERVAL=5 +XINFERENCE_HEALTH_CHECK_FAILURE_THRESHOLD=12 + +# Not used by default; enable only when needed: +# XINFERENCE_HOME=/root/.xinference +# XINFERENCE_LOG_LEVEL=info +# XINFERENCE_AUTH_ADVANCED=true +# XINFERENCE_ACCESS_TOKEN_EXPIRE_MINUTES=30 diff --git a/apps/xinference/CHANGELOG.md b/apps/xinference/CHANGELOG.md new file mode 100644 index 000000000..6048b5757 --- /dev/null +++ b/apps/xinference/CHANGELOG.md @@ -0,0 +1,10 @@ +# CHANGELOG + +## 2026-10-13 + +- Restore the `xinference` app from archive and rebuild the package from the official `xprobe/xinference` image instead of the mis-scaffolded WordPress copy. +- Add the upstream Docker Compose topology: Web UI/API on port `9997`, `/status` healthcheck, and named volumes for `.xinference`, Hugging Face, and ModelScope caches. +- Default to the CPU image variant `v4.0.0-cpu` for initial deployment validation; the GPU variant `v4.0.0` requires an NVIDIA host with CUDA 13.0 and driver 580+. +- After the CPU deployment passed, switch the package to the GPU image variant `v4.0.0` and add the NVIDIA GPU reservation to the compose service. +- Document that authentication is enabled by default since v3.0, so the first Web UI visit creates the initial administrator account. +- Add `tests/cases.yml` with an app-specific `/status` reachability check. diff --git a/apps/xinference/README.md b/apps/xinference/README.md new file mode 100644 index 000000000..7071c2cf8 --- /dev/null +++ b/apps/xinference/README.md @@ -0,0 +1,106 @@ +# Xinference on Docker + +## Quick Start + +### Deploy Verification + +1. In the [Websoft9](https://www.websoft9.com) console, open **My Apps** and select **Xinference**. +2. In the **Access** tab, get the login URL and credentials. +3. Open the login URL in a browser and sign in to confirm the app works. + + +### Usage + +Xinference exposes an OpenAI-compatible RESTful API and a Web UI. Authentication is enabled by default since v3.0, so the first visit to the Web UI opens a setup page where you create the initial administrator account. + +1. Open the app URL and complete the first-run setup to create the administrator account. +2. Sign in and use **Launch Model** to download and start a model; the first launch of a model installs its engine dependencies and takes longer. + +### Change Password + +Use the Web UI **User Management** page, or reset it from a shell with: + +```bash +docker exec -it xinference xinference-reset-auth-password --username admin +``` + + +## Configuration Reference + +Websoft9 packages this app from the official [Xinference Docker image](https://hub.docker.com/r/xprobe/xinference) and makes some improvements below. + + +The package does not preset credentials: the first visit to the Web UI creates the initial administrator account. + +The package ships the GPU image variant (`xprobe/xinference:v4.0.0`) and reserves all NVIDIA GPUs, so the host must have an NVIDIA GPU with CUDA 13.0 and driver 580+. On a CPU-only host, set `W9_VERSION=v4.0.0-cpu` in `.env` and remove the `deploy.resources.reservations.devices` block from `docker-compose.yml`. + + +Apps run as containers; rebuild after any configuration change. + +### Version Support + +Supported versions: v4.0.0, latest. + +The `latest` tag is not guaranteed to remain valid; pin a specific version for production. + + +### Ports + +| Purpose | Port | +| --- | --- | +| Web UI / API | 9997 | + + +### Data Directory + + +- `xinference_home` → `/root/.xinference` +- `huggingface_cache` → `/root/.cache/huggingface` +- `modelscope_cache` → `/root/.cache/modelscope` + + + +### Environment Variables + +Environment variables are defined in the app's `.env` file; see the reference section at the end of `.env` for supported variables. + + +### Configuration Files + + +Configuration files live inside the image; mount a single file read-only to override, and never replace the whole directory. + + +## References + +- [Xinference Administrator Guide](https://support.websoft9.com/docs/xinference) by Websoft9 + +- [Docker Hub image](https://hub.docker.com/r/xprobe/xinference) + +- [Releases](https://github.com/xorbitsai/inference) + +- [Official compose](https://raw.githubusercontent.com/xorbitsai/inference/main/xinference/deploy/docker/docker-compose.yml) + +- [Official env example](https://raw.githubusercontent.com/xorbitsai/inference/main/xinference/deploy/docker/.env.example) + +- [Official docs](https://inference.readthedocs.io/en/latest/getting_started/installation.html) + +- [Official docs](https://inference.readthedocs.io/en/latest/getting_started/using_docker_image.html) + +- [Official docs](https://inference.readthedocs.io/en/latest/getting_started/using_docker_compose.html) + +- [Official docs](https://inference.readthedocs.io/en/latest/user_guide/auth_system.html) + + + +## Troubleshooting + +**Web UI asks for account setup on first visit?** +- This is expected: create the initial administrator account in the browser. + +**Model launch is slow the first time?** +- Xinference installs the engine dependencies into a per-model virtual environment on first launch; later launches reuse it. + +**Not enough memory to load a model?** +- Raise the container memory limit and choose a smaller model or quantization. + diff --git a/apps/xinference/docker-compose.yml b/apps/xinference/docker-compose.yml new file mode 100644 index 000000000..89b6805f7 --- /dev/null +++ b/apps/xinference/docker-compose.yml @@ -0,0 +1,38 @@ +services: + + xinference: + image: ${W9_REPO}:${W9_VERSION} + container_name: ${W9_ID} + restart: unless-stopped + env_file: .env + command: xinference-local -H 0.0.0.0 --port 9997 + shm_size: 8gb + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + ports: + - "${W9_HTTP_PORT_SET}:9997" # Web UI / API + volumes: + - xinference_home:/root/.xinference + - huggingface_cache:/root/.cache/huggingface + - modelscope_cache:/root/.cache/modelscope + healthcheck: + test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:9997/status')"] + interval: 30s + timeout: 5s + retries: 5 + start_period: 60s + +volumes: + xinference_home: + huggingface_cache: + modelscope_cache: + +networks: + default: + name: ${W9_NETWORK} + external: true diff --git a/apps/bitwarden/src/README.md b/apps/xinference/src/README.md similarity index 100% rename from apps/bitwarden/src/README.md rename to apps/xinference/src/README.md diff --git a/apps/xinference/tests/cases.yml b/apps/xinference/tests/cases.yml new file mode 100644 index 000000000..fe6388e32 --- /dev/null +++ b/apps/xinference/tests/cases.yml @@ -0,0 +1,5 @@ +optional: + - id: status-endpoint + type: web-access + path: /status + expect_status: 200 diff --git a/apps/xinference/variables.json b/apps/xinference/variables.json new file mode 100644 index 000000000..6d65c22aa --- /dev/null +++ b/apps/xinference/variables.json @@ -0,0 +1,44 @@ +{ + "name": "xinference", + "trademark": "Xinference", + "release": false, + "upstream": { + "image": "https://hub.docker.com/r/xprobe/xinference", + "releases": "https://github.com/xorbitsai/inference", + "compose": { + "compose": "https://raw.githubusercontent.com/xorbitsai/inference/main/xinference/deploy/docker/docker-compose.yml", + "env": "https://raw.githubusercontent.com/xorbitsai/inference/main/xinference/deploy/docker/.env.example" + }, + "docs": [ + "https://inference.readthedocs.io/en/latest/getting_started/installation.html", + "https://inference.readthedocs.io/en/latest/getting_started/using_docker_image.html", + "https://inference.readthedocs.io/en/latest/getting_started/using_docker_compose.html", + "https://inference.readthedocs.io/en/latest/user_guide/auth_system.html" + ] + }, + "edition": [ + { + "dist": "community", + "version": ["v4.0.0", "latest"] + } + ], + "access": { + "defaultScheme": "http", + "web": { + "port": 9997, + "path": "/" + } + }, + "requirements": { + "cpu": "4", + "memory": "8", + "disk": "20" + }, + "credentials": {}, + "env": { + "first_startup_only": [] + }, + "help": { + "db": "" + } +} diff --git a/apps/apache/.env b/archive/apps/apache/.env similarity index 100% rename from apps/apache/.env rename to archive/apps/apache/.env diff --git a/apps/apache/CHANGELOG.md b/archive/apps/apache/CHANGELOG.md similarity index 100% rename from apps/apache/CHANGELOG.md rename to archive/apps/apache/CHANGELOG.md diff --git a/apps/apache/Notes.md b/archive/apps/apache/Notes.md similarity index 100% rename from apps/apache/Notes.md rename to archive/apps/apache/Notes.md diff --git a/apps/apache/README.md b/archive/apps/apache/README.md similarity index 100% rename from apps/apache/README.md rename to archive/apps/apache/README.md diff --git a/apps/apache/docker-compose.yml b/archive/apps/apache/docker-compose.yml similarity index 100% rename from apps/apache/docker-compose.yml rename to archive/apps/apache/docker-compose.yml diff --git a/apps/bookstack/src/README.md b/archive/apps/apache/src/README.md similarity index 100% rename from apps/bookstack/src/README.md rename to archive/apps/apache/src/README.md diff --git a/apps/apache/src/cmd.sh b/archive/apps/apache/src/cmd.sh similarity index 100% rename from apps/apache/src/cmd.sh rename to archive/apps/apache/src/cmd.sh diff --git a/apps/apache/src/http.conf b/archive/apps/apache/src/http.conf similarity index 100% rename from apps/apache/src/http.conf rename to archive/apps/apache/src/http.conf diff --git a/apps/apache/variables.json b/archive/apps/apache/variables.json similarity index 100% rename from apps/apache/variables.json rename to archive/apps/apache/variables.json diff --git a/apps/apisix/.env b/archive/apps/apisix/.env similarity index 100% rename from apps/apisix/.env rename to archive/apps/apisix/.env diff --git a/apps/apisix/CHANGELOG.md b/archive/apps/apisix/CHANGELOG.md similarity index 100% rename from apps/apisix/CHANGELOG.md rename to archive/apps/apisix/CHANGELOG.md diff --git a/apps/apisix/Notes.md b/archive/apps/apisix/Notes.md similarity index 100% rename from apps/apisix/Notes.md rename to archive/apps/apisix/Notes.md diff --git a/apps/apisix/README.md b/archive/apps/apisix/README.md similarity index 100% rename from apps/apisix/README.md rename to archive/apps/apisix/README.md diff --git a/apps/apisix/docker-compose.yml b/archive/apps/apisix/docker-compose.yml similarity index 100% rename from apps/apisix/docker-compose.yml rename to archive/apps/apisix/docker-compose.yml diff --git a/apps/apisix/src/config/.gitignore b/archive/apps/apisix/src/config/.gitignore similarity index 100% rename from apps/apisix/src/config/.gitignore rename to archive/apps/apisix/src/config/.gitignore diff --git a/apps/apisix/src/config/apisix_conf/config.yaml b/archive/apps/apisix/src/config/apisix_conf/config.yaml similarity index 100% rename from apps/apisix/src/config/apisix_conf/config.yaml rename to archive/apps/apisix/src/config/apisix_conf/config.yaml diff --git a/apps/apisix/src/config/apisix_log/.keep b/archive/apps/apisix/src/config/apisix_log/.keep similarity index 100% rename from apps/apisix/src/config/apisix_log/.keep rename to archive/apps/apisix/src/config/apisix_log/.keep diff --git a/apps/apisix/src/config/dashboard_conf/conf.yaml b/archive/apps/apisix/src/config/dashboard_conf/conf.yaml similarity index 100% rename from apps/apisix/src/config/dashboard_conf/conf.yaml rename to archive/apps/apisix/src/config/dashboard_conf/conf.yaml diff --git a/apps/apisix/src/config/docker-compose-alpine.yml b/archive/apps/apisix/src/config/docker-compose-alpine.yml similarity index 100% rename from apps/apisix/src/config/docker-compose-alpine.yml rename to archive/apps/apisix/src/config/docker-compose-alpine.yml diff --git a/apps/apisix/src/config/docker-compose.yml b/archive/apps/apisix/src/config/docker-compose.yml similarity index 100% rename from apps/apisix/src/config/docker-compose.yml rename to archive/apps/apisix/src/config/docker-compose.yml diff --git a/apps/apisix/src/config/etcd_conf/etcd.conf.yml b/archive/apps/apisix/src/config/etcd_conf/etcd.conf.yml similarity index 100% rename from apps/apisix/src/config/etcd_conf/etcd.conf.yml rename to archive/apps/apisix/src/config/etcd_conf/etcd.conf.yml diff --git a/apps/apisix/src/config/etcd_data/.keep b/archive/apps/apisix/src/config/etcd_data/.keep similarity index 100% rename from apps/apisix/src/config/etcd_data/.keep rename to archive/apps/apisix/src/config/etcd_data/.keep diff --git a/apps/apisix/src/config/mkcert/README.md b/archive/apps/apisix/src/config/mkcert/README.md similarity index 100% rename from apps/apisix/src/config/mkcert/README.md rename to archive/apps/apisix/src/config/mkcert/README.md diff --git a/apps/apisix/src/config/upstream/web1.conf b/archive/apps/apisix/src/config/upstream/web1.conf similarity index 100% rename from apps/apisix/src/config/upstream/web1.conf rename to archive/apps/apisix/src/config/upstream/web1.conf diff --git a/apps/apisix/src/config/upstream/web2.conf b/archive/apps/apisix/src/config/upstream/web2.conf similarity index 100% rename from apps/apisix/src/config/upstream/web2.conf rename to archive/apps/apisix/src/config/upstream/web2.conf diff --git a/apps/apisix/src/filelist b/archive/apps/apisix/src/filelist similarity index 100% rename from apps/apisix/src/filelist rename to archive/apps/apisix/src/filelist diff --git a/apps/apisix/variables.json b/archive/apps/apisix/variables.json similarity index 100% rename from apps/apisix/variables.json rename to archive/apps/apisix/variables.json diff --git a/apps/appsmith/.env b/archive/apps/appsmith/.env similarity index 100% rename from apps/appsmith/.env rename to archive/apps/appsmith/.env diff --git a/apps/appsmith/CHANGELOG.md b/archive/apps/appsmith/CHANGELOG.md similarity index 100% rename from apps/appsmith/CHANGELOG.md rename to archive/apps/appsmith/CHANGELOG.md diff --git a/apps/appsmith/README.md b/archive/apps/appsmith/README.md similarity index 100% rename from apps/appsmith/README.md rename to archive/apps/appsmith/README.md diff --git a/apps/appsmith/docker-compose.yml b/archive/apps/appsmith/docker-compose.yml similarity index 100% rename from apps/appsmith/docker-compose.yml rename to archive/apps/appsmith/docker-compose.yml diff --git a/apps/appsmith/src/after_up.sh b/archive/apps/appsmith/src/after_up.sh similarity index 100% rename from apps/appsmith/src/after_up.sh rename to archive/apps/appsmith/src/after_up.sh diff --git a/apps/appsmith/src/encrypt.sh b/archive/apps/appsmith/src/encrypt.sh similarity index 100% rename from apps/appsmith/src/encrypt.sh rename to archive/apps/appsmith/src/encrypt.sh diff --git a/apps/appsmith/src/filelist b/archive/apps/appsmith/src/filelist similarity index 100% rename from apps/appsmith/src/filelist rename to archive/apps/appsmith/src/filelist diff --git a/apps/appsmith/src/get_version.sh b/archive/apps/appsmith/src/get_version.sh similarity index 100% rename from apps/appsmith/src/get_version.sh rename to archive/apps/appsmith/src/get_version.sh diff --git a/apps/appsmith/src/nginx_proxy.conf b/archive/apps/appsmith/src/nginx_proxy.conf similarity index 100% rename from apps/appsmith/src/nginx_proxy.conf rename to archive/apps/appsmith/src/nginx_proxy.conf diff --git a/apps/appsmith/variables.json b/archive/apps/appsmith/variables.json similarity index 100% rename from apps/appsmith/variables.json rename to archive/apps/appsmith/variables.json diff --git a/apps/bigbluebutton/.env b/archive/apps/bigbluebutton/.env similarity index 100% rename from apps/bigbluebutton/.env rename to archive/apps/bigbluebutton/.env diff --git a/apps/bigbluebutton/CHANGELOG.md b/archive/apps/bigbluebutton/CHANGELOG.md similarity index 100% rename from apps/bigbluebutton/CHANGELOG.md rename to archive/apps/bigbluebutton/CHANGELOG.md diff --git a/apps/bigbluebutton/Notes.md b/archive/apps/bigbluebutton/Notes.md similarity index 100% rename from apps/bigbluebutton/Notes.md rename to archive/apps/bigbluebutton/Notes.md diff --git a/apps/bigbluebutton/README.md b/archive/apps/bigbluebutton/README.md similarity index 100% rename from apps/bigbluebutton/README.md rename to archive/apps/bigbluebutton/README.md diff --git a/apps/bigbluebutton/docker-compose.yml b/archive/apps/bigbluebutton/docker-compose.yml similarity index 100% rename from apps/bigbluebutton/docker-compose.yml rename to archive/apps/bigbluebutton/docker-compose.yml diff --git a/apps/bigbluebutton/src/conf/.gitignore b/archive/apps/bigbluebutton/src/conf/.gitignore similarity index 100% rename from apps/bigbluebutton/src/conf/.gitignore rename to archive/apps/bigbluebutton/src/conf/.gitignore diff --git a/apps/coze/src/nginx/ssl/.gitkeep b/archive/apps/bigbluebutton/src/conf/dialplan_public/.gitkeep similarity index 100% rename from apps/coze/src/nginx/ssl/.gitkeep rename to archive/apps/bigbluebutton/src/conf/dialplan_public/.gitkeep diff --git a/apps/bigbluebutton/src/conf/dialplan_public/example.xml b/archive/apps/bigbluebutton/src/conf/dialplan_public/example.xml similarity index 100% rename from apps/bigbluebutton/src/conf/dialplan_public/example.xml rename to archive/apps/bigbluebutton/src/conf/dialplan_public/example.xml diff --git a/apps/cloudreve/src/cloudreve.db b/archive/apps/bigbluebutton/src/conf/sip_profiles/.gitkeep similarity index 100% rename from apps/cloudreve/src/cloudreve.db rename to archive/apps/bigbluebutton/src/conf/sip_profiles/.gitkeep diff --git a/apps/bigbluebutton/src/conf/sip_profiles/example.xml b/archive/apps/bigbluebutton/src/conf/sip_profiles/example.xml similarity index 100% rename from apps/bigbluebutton/src/conf/sip_profiles/example.xml rename to archive/apps/bigbluebutton/src/conf/sip_profiles/example.xml diff --git a/apps/bigbluebutton/src/docker-compose.tmpl.yml b/archive/apps/bigbluebutton/src/docker-compose.tmpl.yml similarity index 100% rename from apps/bigbluebutton/src/docker-compose.tmpl.yml rename to archive/apps/bigbluebutton/src/docker-compose.tmpl.yml diff --git a/apps/bigbluebutton/src/filelist b/archive/apps/bigbluebutton/src/filelist similarity index 100% rename from apps/bigbluebutton/src/filelist rename to archive/apps/bigbluebutton/src/filelist diff --git a/apps/bigbluebutton/upstream.sh b/archive/apps/bigbluebutton/upstream.sh similarity index 100% rename from apps/bigbluebutton/upstream.sh rename to archive/apps/bigbluebutton/upstream.sh diff --git a/apps/bigbluebutton/variables.json b/archive/apps/bigbluebutton/variables.json similarity index 100% rename from apps/bigbluebutton/variables.json rename to archive/apps/bigbluebutton/variables.json diff --git a/apps/bitwarden/.env b/archive/apps/bitwarden/.env similarity index 100% rename from apps/bitwarden/.env rename to archive/apps/bitwarden/.env diff --git a/apps/bitwarden/CHANGELOG.md b/archive/apps/bitwarden/CHANGELOG.md similarity index 100% rename from apps/bitwarden/CHANGELOG.md rename to archive/apps/bitwarden/CHANGELOG.md diff --git a/apps/bitwarden/Notes.md b/archive/apps/bitwarden/Notes.md similarity index 100% rename from apps/bitwarden/Notes.md rename to archive/apps/bitwarden/Notes.md diff --git a/apps/bitwarden/README.md b/archive/apps/bitwarden/README.md similarity index 100% rename from apps/bitwarden/README.md rename to archive/apps/bitwarden/README.md diff --git a/apps/bitwarden/docker-compose.yml b/archive/apps/bitwarden/docker-compose.yml similarity index 100% rename from apps/bitwarden/docker-compose.yml rename to archive/apps/bitwarden/docker-compose.yml diff --git a/apps/browserless/src/README.md b/archive/apps/bitwarden/src/README.md similarity index 100% rename from apps/browserless/src/README.md rename to archive/apps/bitwarden/src/README.md diff --git a/apps/bitwarden/variables.json b/archive/apps/bitwarden/variables.json similarity index 100% rename from apps/bitwarden/variables.json rename to archive/apps/bitwarden/variables.json diff --git a/apps/bookstack/.env b/archive/apps/bookstack/.env similarity index 100% rename from apps/bookstack/.env rename to archive/apps/bookstack/.env diff --git a/apps/bookstack/CHANGELOG.md b/archive/apps/bookstack/CHANGELOG.md similarity index 100% rename from apps/bookstack/CHANGELOG.md rename to archive/apps/bookstack/CHANGELOG.md diff --git a/apps/bookstack/Notes.md b/archive/apps/bookstack/Notes.md similarity index 100% rename from apps/bookstack/Notes.md rename to archive/apps/bookstack/Notes.md diff --git a/apps/bookstack/README.md b/archive/apps/bookstack/README.md similarity index 100% rename from apps/bookstack/README.md rename to archive/apps/bookstack/README.md diff --git a/apps/bookstack/docker-compose.yml b/archive/apps/bookstack/docker-compose.yml similarity index 100% rename from apps/bookstack/docker-compose.yml rename to archive/apps/bookstack/docker-compose.yml diff --git a/apps/bunkerweb/src/README.md b/archive/apps/bookstack/src/README.md similarity index 100% rename from apps/bunkerweb/src/README.md rename to archive/apps/bookstack/src/README.md diff --git a/apps/bookstack/src/nginx-proxy.conf.template b/archive/apps/bookstack/src/nginx-proxy.conf.template similarity index 100% rename from apps/bookstack/src/nginx-proxy.conf.template rename to archive/apps/bookstack/src/nginx-proxy.conf.template diff --git a/apps/bookstack/src/php_exra.ini b/archive/apps/bookstack/src/php_exra.ini similarity index 100% rename from apps/bookstack/src/php_exra.ini rename to archive/apps/bookstack/src/php_exra.ini diff --git a/apps/bookstack/variables.json b/archive/apps/bookstack/variables.json similarity index 100% rename from apps/bookstack/variables.json rename to archive/apps/bookstack/variables.json diff --git a/apps/browserless/.env b/archive/apps/browserless/.env similarity index 100% rename from apps/browserless/.env rename to archive/apps/browserless/.env diff --git a/apps/browserless/CHANGELOG.md b/archive/apps/browserless/CHANGELOG.md similarity index 100% rename from apps/browserless/CHANGELOG.md rename to archive/apps/browserless/CHANGELOG.md diff --git a/apps/browserless/Notes.md b/archive/apps/browserless/Notes.md similarity index 100% rename from apps/browserless/Notes.md rename to archive/apps/browserless/Notes.md diff --git a/apps/browserless/README.md b/archive/apps/browserless/README.md similarity index 100% rename from apps/browserless/README.md rename to archive/apps/browserless/README.md diff --git a/apps/browserless/docker-compose.yml b/archive/apps/browserless/docker-compose.yml similarity index 100% rename from apps/browserless/docker-compose.yml rename to archive/apps/browserless/docker-compose.yml diff --git a/apps/bytebase/src/README.md b/archive/apps/browserless/src/README.md similarity index 100% rename from apps/bytebase/src/README.md rename to archive/apps/browserless/src/README.md diff --git a/apps/browserless/variables.json b/archive/apps/browserless/variables.json similarity index 100% rename from apps/browserless/variables.json rename to archive/apps/browserless/variables.json diff --git a/apps/bunkerweb/.env b/archive/apps/bunkerweb/.env similarity index 100% rename from apps/bunkerweb/.env rename to archive/apps/bunkerweb/.env diff --git a/apps/bunkerweb/CHANGELOG.md b/archive/apps/bunkerweb/CHANGELOG.md similarity index 100% rename from apps/bunkerweb/CHANGELOG.md rename to archive/apps/bunkerweb/CHANGELOG.md diff --git a/apps/bunkerweb/Notes.md b/archive/apps/bunkerweb/Notes.md similarity index 100% rename from apps/bunkerweb/Notes.md rename to archive/apps/bunkerweb/Notes.md diff --git a/apps/bunkerweb/README.md b/archive/apps/bunkerweb/README.md similarity index 100% rename from apps/bunkerweb/README.md rename to archive/apps/bunkerweb/README.md diff --git a/apps/bunkerweb/docker-compose.yml b/archive/apps/bunkerweb/docker-compose.yml similarity index 100% rename from apps/bunkerweb/docker-compose.yml rename to archive/apps/bunkerweb/docker-compose.yml diff --git a/apps/checkmate/src/README.md b/archive/apps/bunkerweb/src/README.md similarity index 100% rename from apps/checkmate/src/README.md rename to archive/apps/bunkerweb/src/README.md diff --git a/apps/bunkerweb/variables.json b/archive/apps/bunkerweb/variables.json similarity index 100% rename from apps/bunkerweb/variables.json rename to archive/apps/bunkerweb/variables.json diff --git a/apps/bytebase/.env b/archive/apps/bytebase/.env similarity index 100% rename from apps/bytebase/.env rename to archive/apps/bytebase/.env diff --git a/apps/bytebase/CHANGELOG.md b/archive/apps/bytebase/CHANGELOG.md similarity index 100% rename from apps/bytebase/CHANGELOG.md rename to archive/apps/bytebase/CHANGELOG.md diff --git a/apps/bytebase/Notes.md b/archive/apps/bytebase/Notes.md similarity index 100% rename from apps/bytebase/Notes.md rename to archive/apps/bytebase/Notes.md diff --git a/apps/bytebase/README.md b/archive/apps/bytebase/README.md similarity index 100% rename from apps/bytebase/README.md rename to archive/apps/bytebase/README.md diff --git a/apps/bytebase/docker-compose.yml b/archive/apps/bytebase/docker-compose.yml similarity index 100% rename from apps/bytebase/docker-compose.yml rename to archive/apps/bytebase/docker-compose.yml diff --git a/apps/cloudreve/src/README.md b/archive/apps/bytebase/src/README.md similarity index 100% rename from apps/cloudreve/src/README.md rename to archive/apps/bytebase/src/README.md diff --git a/apps/bytebase/variables.json b/archive/apps/bytebase/variables.json similarity index 100% rename from apps/bytebase/variables.json rename to archive/apps/bytebase/variables.json diff --git a/apps/checkmate/.env b/archive/apps/checkmate/.env similarity index 100% rename from apps/checkmate/.env rename to archive/apps/checkmate/.env diff --git a/apps/checkmate/CHANGELOG.md b/archive/apps/checkmate/CHANGELOG.md similarity index 100% rename from apps/checkmate/CHANGELOG.md rename to archive/apps/checkmate/CHANGELOG.md diff --git a/apps/checkmate/README.md b/archive/apps/checkmate/README.md similarity index 100% rename from apps/checkmate/README.md rename to archive/apps/checkmate/README.md diff --git a/apps/checkmate/docker-compose.yml b/archive/apps/checkmate/docker-compose.yml similarity index 100% rename from apps/checkmate/docker-compose.yml rename to archive/apps/checkmate/docker-compose.yml diff --git a/apps/collabora/src/README.md b/archive/apps/checkmate/src/README.md similarity index 100% rename from apps/collabora/src/README.md rename to archive/apps/checkmate/src/README.md diff --git a/apps/checkmate/tests/cases.yml b/archive/apps/checkmate/tests/cases.yml similarity index 100% rename from apps/checkmate/tests/cases.yml rename to archive/apps/checkmate/tests/cases.yml diff --git a/apps/checkmate/variables.json b/archive/apps/checkmate/variables.json similarity index 100% rename from apps/checkmate/variables.json rename to archive/apps/checkmate/variables.json diff --git a/apps/clamav/.env b/archive/apps/clamav/.env similarity index 100% rename from apps/clamav/.env rename to archive/apps/clamav/.env diff --git a/apps/clamav/CHANGELOG.md b/archive/apps/clamav/CHANGELOG.md similarity index 100% rename from apps/clamav/CHANGELOG.md rename to archive/apps/clamav/CHANGELOG.md diff --git a/apps/clamav/Notes.md b/archive/apps/clamav/Notes.md similarity index 100% rename from apps/clamav/Notes.md rename to archive/apps/clamav/Notes.md diff --git a/apps/clamav/README.md b/archive/apps/clamav/README.md similarity index 100% rename from apps/clamav/README.md rename to archive/apps/clamav/README.md diff --git a/apps/clamav/docker-compose.yml b/archive/apps/clamav/docker-compose.yml similarity index 100% rename from apps/clamav/docker-compose.yml rename to archive/apps/clamav/docker-compose.yml diff --git a/apps/clamav/variables.json b/archive/apps/clamav/variables.json similarity index 100% rename from apps/clamav/variables.json rename to archive/apps/clamav/variables.json diff --git a/apps/cloudreve/.env b/archive/apps/cloudreve/.env similarity index 100% rename from apps/cloudreve/.env rename to archive/apps/cloudreve/.env diff --git a/apps/cloudreve/CHANGELOG.md b/archive/apps/cloudreve/CHANGELOG.md similarity index 100% rename from apps/cloudreve/CHANGELOG.md rename to archive/apps/cloudreve/CHANGELOG.md diff --git a/apps/cloudreve/Notes.md b/archive/apps/cloudreve/Notes.md similarity index 100% rename from apps/cloudreve/Notes.md rename to archive/apps/cloudreve/Notes.md diff --git a/apps/cloudreve/README.md b/archive/apps/cloudreve/README.md similarity index 100% rename from apps/cloudreve/README.md rename to archive/apps/cloudreve/README.md diff --git a/apps/cloudreve/docker-compose.yml b/archive/apps/cloudreve/docker-compose.yml similarity index 100% rename from apps/cloudreve/docker-compose.yml rename to archive/apps/cloudreve/docker-compose.yml diff --git a/apps/commafeed/src/README.md b/archive/apps/cloudreve/src/README.md similarity index 100% rename from apps/commafeed/src/README.md rename to archive/apps/cloudreve/src/README.md diff --git a/apps/coze/src/volumes/etcd/etcd.conf.yml b/archive/apps/cloudreve/src/cloudreve.db old mode 100755 new mode 100644 similarity index 100% rename from apps/coze/src/volumes/etcd/etcd.conf.yml rename to archive/apps/cloudreve/src/cloudreve.db diff --git a/apps/cloudreve/src/conf.ini b/archive/apps/cloudreve/src/conf.ini similarity index 100% rename from apps/cloudreve/src/conf.ini rename to archive/apps/cloudreve/src/conf.ini diff --git a/apps/cloudreve/variables.json b/archive/apps/cloudreve/variables.json similarity index 100% rename from apps/cloudreve/variables.json rename to archive/apps/cloudreve/variables.json diff --git a/apps/cmak/.env b/archive/apps/cmak/.env similarity index 100% rename from apps/cmak/.env rename to archive/apps/cmak/.env diff --git a/apps/cmak/CHANGELOG.md b/archive/apps/cmak/CHANGELOG.md similarity index 100% rename from apps/cmak/CHANGELOG.md rename to archive/apps/cmak/CHANGELOG.md diff --git a/apps/cmak/Dockerfile b/archive/apps/cmak/Dockerfile similarity index 100% rename from apps/cmak/Dockerfile rename to archive/apps/cmak/Dockerfile diff --git a/apps/cmak/Notes.md b/archive/apps/cmak/Notes.md similarity index 100% rename from apps/cmak/Notes.md rename to archive/apps/cmak/Notes.md diff --git a/apps/cmak/README.md b/archive/apps/cmak/README.md similarity index 100% rename from apps/cmak/README.md rename to archive/apps/cmak/README.md diff --git a/apps/cmak/docker-compose.yml b/archive/apps/cmak/docker-compose.yml similarity index 100% rename from apps/cmak/docker-compose.yml rename to archive/apps/cmak/docker-compose.yml diff --git a/apps/cmak/src/Dockerfile b/archive/apps/cmak/src/Dockerfile similarity index 100% rename from apps/cmak/src/Dockerfile rename to archive/apps/cmak/src/Dockerfile diff --git a/apps/cmak/src/filelist b/archive/apps/cmak/src/filelist similarity index 100% rename from apps/cmak/src/filelist rename to archive/apps/cmak/src/filelist diff --git a/apps/cmak/variables.json b/archive/apps/cmak/variables.json similarity index 100% rename from apps/cmak/variables.json rename to archive/apps/cmak/variables.json diff --git a/apps/collabora/.env b/archive/apps/collabora/.env similarity index 100% rename from apps/collabora/.env rename to archive/apps/collabora/.env diff --git a/apps/collabora/CHANGELOG.md b/archive/apps/collabora/CHANGELOG.md similarity index 100% rename from apps/collabora/CHANGELOG.md rename to archive/apps/collabora/CHANGELOG.md diff --git a/apps/collabora/Notes.md b/archive/apps/collabora/Notes.md similarity index 100% rename from apps/collabora/Notes.md rename to archive/apps/collabora/Notes.md diff --git a/apps/collabora/README.md b/archive/apps/collabora/README.md similarity index 100% rename from apps/collabora/README.md rename to archive/apps/collabora/README.md diff --git a/apps/collabora/docker-compose.yml b/archive/apps/collabora/docker-compose.yml similarity index 100% rename from apps/collabora/docker-compose.yml rename to archive/apps/collabora/docker-compose.yml diff --git a/apps/compreface/src/README.md b/archive/apps/collabora/src/README.md similarity index 100% rename from apps/compreface/src/README.md rename to archive/apps/collabora/src/README.md diff --git a/apps/collabora/variables.json b/archive/apps/collabora/variables.json similarity index 100% rename from apps/collabora/variables.json rename to archive/apps/collabora/variables.json diff --git a/apps/commafeed/.env b/archive/apps/commafeed/.env similarity index 100% rename from apps/commafeed/.env rename to archive/apps/commafeed/.env diff --git a/apps/commafeed/CHANGELOG.md b/archive/apps/commafeed/CHANGELOG.md similarity index 100% rename from apps/commafeed/CHANGELOG.md rename to archive/apps/commafeed/CHANGELOG.md diff --git a/apps/commafeed/Notes.md b/archive/apps/commafeed/Notes.md similarity index 100% rename from apps/commafeed/Notes.md rename to archive/apps/commafeed/Notes.md diff --git a/apps/commafeed/README.md b/archive/apps/commafeed/README.md similarity index 100% rename from apps/commafeed/README.md rename to archive/apps/commafeed/README.md diff --git a/apps/commafeed/docker-compose.yml b/archive/apps/commafeed/docker-compose.yml similarity index 100% rename from apps/commafeed/docker-compose.yml rename to archive/apps/commafeed/docker-compose.yml diff --git a/apps/coredns/src/README.md b/archive/apps/commafeed/src/README.md similarity index 100% rename from apps/coredns/src/README.md rename to archive/apps/commafeed/src/README.md diff --git a/apps/commafeed/variables.json b/archive/apps/commafeed/variables.json similarity index 100% rename from apps/commafeed/variables.json rename to archive/apps/commafeed/variables.json diff --git a/apps/compreface/.env b/archive/apps/compreface/.env similarity index 100% rename from apps/compreface/.env rename to archive/apps/compreface/.env diff --git a/apps/compreface/CHANGELOG.md b/archive/apps/compreface/CHANGELOG.md similarity index 100% rename from apps/compreface/CHANGELOG.md rename to archive/apps/compreface/CHANGELOG.md diff --git a/apps/compreface/Dockerfile b/archive/apps/compreface/Dockerfile similarity index 100% rename from apps/compreface/Dockerfile rename to archive/apps/compreface/Dockerfile diff --git a/apps/compreface/Notes.md b/archive/apps/compreface/Notes.md similarity index 100% rename from apps/compreface/Notes.md rename to archive/apps/compreface/Notes.md diff --git a/apps/compreface/README.jinja2 b/archive/apps/compreface/README.jinja2 similarity index 100% rename from apps/compreface/README.jinja2 rename to archive/apps/compreface/README.jinja2 diff --git a/apps/compreface/README.md b/archive/apps/compreface/README.md similarity index 100% rename from apps/compreface/README.md rename to archive/apps/compreface/README.md diff --git a/apps/compreface/docker-compose.yml b/archive/apps/compreface/docker-compose.yml similarity index 100% rename from apps/compreface/docker-compose.yml rename to archive/apps/compreface/docker-compose.yml diff --git a/apps/coze/src/README.md b/archive/apps/compreface/src/README.md similarity index 100% rename from apps/coze/src/README.md rename to archive/apps/compreface/src/README.md diff --git a/apps/compreface/src/nginx-proxy.conf.template b/archive/apps/compreface/src/nginx-proxy.conf.template similarity index 100% rename from apps/compreface/src/nginx-proxy.conf.template rename to archive/apps/compreface/src/nginx-proxy.conf.template diff --git a/apps/compreface/src/php_exra.ini b/archive/apps/compreface/src/php_exra.ini similarity index 100% rename from apps/compreface/src/php_exra.ini rename to archive/apps/compreface/src/php_exra.ini diff --git a/apps/compreface/variables.json b/archive/apps/compreface/variables.json similarity index 100% rename from apps/compreface/variables.json rename to archive/apps/compreface/variables.json diff --git a/apps/coredns/.env b/archive/apps/coredns/.env similarity index 100% rename from apps/coredns/.env rename to archive/apps/coredns/.env diff --git a/apps/coredns/CHANGELOG.md b/archive/apps/coredns/CHANGELOG.md similarity index 100% rename from apps/coredns/CHANGELOG.md rename to archive/apps/coredns/CHANGELOG.md diff --git a/apps/coredns/Notes.md b/archive/apps/coredns/Notes.md similarity index 100% rename from apps/coredns/Notes.md rename to archive/apps/coredns/Notes.md diff --git a/apps/coredns/README.md b/archive/apps/coredns/README.md similarity index 100% rename from apps/coredns/README.md rename to archive/apps/coredns/README.md diff --git a/apps/coredns/docker-compose.yml b/archive/apps/coredns/docker-compose.yml similarity index 100% rename from apps/coredns/docker-compose.yml rename to archive/apps/coredns/docker-compose.yml diff --git a/apps/coredns/src/Corefile b/archive/apps/coredns/src/Corefile similarity index 100% rename from apps/coredns/src/Corefile rename to archive/apps/coredns/src/Corefile diff --git a/apps/crowdsec/src/README.md b/archive/apps/coredns/src/README.md similarity index 100% rename from apps/crowdsec/src/README.md rename to archive/apps/coredns/src/README.md diff --git a/apps/coredns/src/db.demo.inner b/archive/apps/coredns/src/db.demo.inner similarity index 100% rename from apps/coredns/src/db.demo.inner rename to archive/apps/coredns/src/db.demo.inner diff --git a/apps/coredns/variables.json b/archive/apps/coredns/variables.json similarity index 100% rename from apps/coredns/variables.json rename to archive/apps/coredns/variables.json diff --git a/apps/countly/.env b/archive/apps/countly/.env similarity index 100% rename from apps/countly/.env rename to archive/apps/countly/.env diff --git a/apps/countly/CHANGELOG.md b/archive/apps/countly/CHANGELOG.md similarity index 100% rename from apps/countly/CHANGELOG.md rename to archive/apps/countly/CHANGELOG.md diff --git a/apps/countly/Notes.md b/archive/apps/countly/Notes.md similarity index 100% rename from apps/countly/Notes.md rename to archive/apps/countly/Notes.md diff --git a/apps/countly/README.md b/archive/apps/countly/README.md similarity index 100% rename from apps/countly/README.md rename to archive/apps/countly/README.md diff --git a/apps/countly/docker-compose.yml b/archive/apps/countly/docker-compose.yml similarity index 100% rename from apps/countly/docker-compose.yml rename to archive/apps/countly/docker-compose.yml diff --git a/apps/countly/src/bin/README.md b/archive/apps/countly/src/bin/README.md similarity index 100% rename from apps/countly/src/bin/README.md rename to archive/apps/countly/src/bin/README.md diff --git a/apps/countly/src/bin/backup/app_crashgroups58bf06bd6cba850047ac9f19.json b/archive/apps/countly/src/bin/backup/app_crashgroups58bf06bd6cba850047ac9f19.json similarity index 100% rename from apps/countly/src/bin/backup/app_crashgroups58bf06bd6cba850047ac9f19.json rename to archive/apps/countly/src/bin/backup/app_crashgroups58bf06bd6cba850047ac9f19.json diff --git a/apps/countly/src/bin/backup/app_users58bf06bd6cba850047ac9f19.json b/archive/apps/countly/src/bin/backup/app_users58bf06bd6cba850047ac9f19.json similarity index 100% rename from apps/countly/src/bin/backup/app_users58bf06bd6cba850047ac9f19.json rename to archive/apps/countly/src/bin/backup/app_users58bf06bd6cba850047ac9f19.json diff --git a/apps/countly/src/bin/backup/app_viewdata58bf06bd6cba850047ac9f19.json b/archive/apps/countly/src/bin/backup/app_viewdata58bf06bd6cba850047ac9f19.json similarity index 100% rename from apps/countly/src/bin/backup/app_viewdata58bf06bd6cba850047ac9f19.json rename to archive/apps/countly/src/bin/backup/app_viewdata58bf06bd6cba850047ac9f19.json diff --git a/apps/countly/src/bin/backup/apps.json b/archive/apps/countly/src/bin/backup/apps.json similarity index 100% rename from apps/countly/src/bin/backup/apps.json rename to archive/apps/countly/src/bin/backup/apps.json diff --git a/apps/countly/src/bin/backup/jobs.json b/archive/apps/countly/src/bin/backup/jobs.json similarity index 100% rename from apps/countly/src/bin/backup/jobs.json rename to archive/apps/countly/src/bin/backup/jobs.json diff --git a/apps/countly/src/bin/backup/members.json b/archive/apps/countly/src/bin/backup/members.json similarity index 100% rename from apps/countly/src/bin/backup/members.json rename to archive/apps/countly/src/bin/backup/members.json diff --git a/apps/countly/src/bin/backup/run.sh b/archive/apps/countly/src/bin/backup/run.sh similarity index 100% rename from apps/countly/src/bin/backup/run.sh rename to archive/apps/countly/src/bin/backup/run.sh diff --git a/apps/countly/src/bin/backup/sessions_.json b/archive/apps/countly/src/bin/backup/sessions_.json similarity index 100% rename from apps/countly/src/bin/backup/sessions_.json rename to archive/apps/countly/src/bin/backup/sessions_.json diff --git a/apps/countly/src/bin/commands/countly.sh b/archive/apps/countly/src/bin/commands/countly.sh similarity index 100% rename from apps/countly/src/bin/commands/countly.sh rename to archive/apps/countly/src/bin/commands/countly.sh diff --git a/apps/countly/src/bin/commands/docker/countly-api.sh b/archive/apps/countly/src/bin/commands/docker/countly-api.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/countly-api.sh rename to archive/apps/countly/src/bin/commands/docker/countly-api.sh diff --git a/apps/countly/src/bin/commands/docker/countly-dashboard.sh b/archive/apps/countly/src/bin/commands/docker/countly-dashboard.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/countly-dashboard.sh rename to archive/apps/countly/src/bin/commands/docker/countly-dashboard.sh diff --git a/apps/countly/src/bin/commands/docker/countly.sh b/archive/apps/countly/src/bin/commands/docker/countly.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/countly.sh rename to archive/apps/countly/src/bin/commands/docker/countly.sh diff --git a/apps/countly/src/bin/commands/docker/install.sh b/archive/apps/countly/src/bin/commands/docker/install.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/install.sh rename to archive/apps/countly/src/bin/commands/docker/install.sh diff --git a/apps/countly/src/bin/commands/docker/mongodb.sh b/archive/apps/countly/src/bin/commands/docker/mongodb.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/mongodb.sh rename to archive/apps/countly/src/bin/commands/docker/mongodb.sh diff --git a/apps/countly/src/bin/commands/docker/nginx.sh b/archive/apps/countly/src/bin/commands/docker/nginx.sh similarity index 100% rename from apps/countly/src/bin/commands/docker/nginx.sh rename to archive/apps/countly/src/bin/commands/docker/nginx.sh diff --git a/apps/countly/src/bin/commands/enabled/.gitignore b/archive/apps/countly/src/bin/commands/enabled/.gitignore similarity index 100% rename from apps/countly/src/bin/commands/enabled/.gitignore rename to archive/apps/countly/src/bin/commands/enabled/.gitignore diff --git a/apps/countly/src/bin/commands/launchd/com.countly.api.plist b/archive/apps/countly/src/bin/commands/launchd/com.countly.api.plist similarity index 100% rename from apps/countly/src/bin/commands/launchd/com.countly.api.plist rename to archive/apps/countly/src/bin/commands/launchd/com.countly.api.plist diff --git a/apps/countly/src/bin/commands/launchd/com.countly.dashboard.plist b/archive/apps/countly/src/bin/commands/launchd/com.countly.dashboard.plist similarity index 100% rename from apps/countly/src/bin/commands/launchd/com.countly.dashboard.plist rename to archive/apps/countly/src/bin/commands/launchd/com.countly.dashboard.plist diff --git a/apps/countly/src/bin/commands/launchd/countly.sh b/archive/apps/countly/src/bin/commands/launchd/countly.sh similarity index 100% rename from apps/countly/src/bin/commands/launchd/countly.sh rename to archive/apps/countly/src/bin/commands/launchd/countly.sh diff --git a/apps/countly/src/bin/commands/launchd/install.sh b/archive/apps/countly/src/bin/commands/launchd/install.sh similarity index 100% rename from apps/countly/src/bin/commands/launchd/install.sh rename to archive/apps/countly/src/bin/commands/launchd/install.sh diff --git a/apps/countly/src/bin/commands/scripts/add_user.sh b/archive/apps/countly/src/bin/commands/scripts/add_user.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/add_user.sh rename to archive/apps/countly/src/bin/commands/scripts/add_user.sh diff --git a/apps/countly/src/bin/commands/scripts/api.js b/archive/apps/countly/src/bin/commands/scripts/api.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/api.js rename to archive/apps/countly/src/bin/commands/scripts/api.js diff --git a/apps/countly/src/bin/commands/scripts/api.sh b/archive/apps/countly/src/bin/commands/scripts/api.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/api.sh rename to archive/apps/countly/src/bin/commands/scripts/api.sh diff --git a/apps/countly/src/bin/commands/scripts/autocomplete.js b/archive/apps/countly/src/bin/commands/scripts/autocomplete.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/autocomplete.js rename to archive/apps/countly/src/bin/commands/scripts/autocomplete.js diff --git a/apps/countly/src/bin/commands/scripts/autocomplete.sh b/archive/apps/countly/src/bin/commands/scripts/autocomplete.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/autocomplete.sh rename to archive/apps/countly/src/bin/commands/scripts/autocomplete.sh diff --git a/apps/countly/src/bin/commands/scripts/autocomplete/countly b/archive/apps/countly/src/bin/commands/scripts/autocomplete/countly similarity index 100% rename from apps/countly/src/bin/commands/scripts/autocomplete/countly rename to archive/apps/countly/src/bin/commands/scripts/autocomplete/countly diff --git a/apps/countly/src/bin/commands/scripts/config.js b/archive/apps/countly/src/bin/commands/scripts/config.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/config.js rename to archive/apps/countly/src/bin/commands/scripts/config.js diff --git a/apps/countly/src/bin/commands/scripts/config.sh b/archive/apps/countly/src/bin/commands/scripts/config.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/config.sh rename to archive/apps/countly/src/bin/commands/scripts/config.sh diff --git a/apps/countly/src/bin/commands/scripts/countly.run.tests.sh b/archive/apps/countly/src/bin/commands/scripts/countly.run.tests.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/countly.run.tests.sh rename to archive/apps/countly/src/bin/commands/scripts/countly.run.tests.sh diff --git a/apps/countly/src/bin/commands/scripts/db.conf.js b/archive/apps/countly/src/bin/commands/scripts/db.conf.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/db.conf.js rename to archive/apps/countly/src/bin/commands/scripts/db.conf.js diff --git a/apps/countly/src/bin/commands/scripts/decrypt.js b/archive/apps/countly/src/bin/commands/scripts/decrypt.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/decrypt.js rename to archive/apps/countly/src/bin/commands/scripts/decrypt.js diff --git a/apps/countly/src/bin/commands/scripts/decrypt.sh b/archive/apps/countly/src/bin/commands/scripts/decrypt.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/decrypt.sh rename to archive/apps/countly/src/bin/commands/scripts/decrypt.sh diff --git a/apps/countly/src/bin/commands/scripts/docs.sh b/archive/apps/countly/src/bin/commands/scripts/docs.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/docs.sh rename to archive/apps/countly/src/bin/commands/scripts/docs.sh diff --git a/apps/countly/src/bin/commands/scripts/encrypt.js b/archive/apps/countly/src/bin/commands/scripts/encrypt.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/encrypt.js rename to archive/apps/countly/src/bin/commands/scripts/encrypt.js diff --git a/apps/countly/src/bin/commands/scripts/encrypt.sh b/archive/apps/countly/src/bin/commands/scripts/encrypt.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/encrypt.sh rename to archive/apps/countly/src/bin/commands/scripts/encrypt.sh diff --git a/apps/countly/src/bin/commands/scripts/fs.js b/archive/apps/countly/src/bin/commands/scripts/fs.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/fs.js rename to archive/apps/countly/src/bin/commands/scripts/fs.js diff --git a/apps/countly/src/bin/commands/scripts/fs.sh b/archive/apps/countly/src/bin/commands/scripts/fs.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/fs.sh rename to archive/apps/countly/src/bin/commands/scripts/fs.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/about.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/about.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/about.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/about.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/accessibility.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/accessibility.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/accessibility.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/accessibility.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/disk.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/disk.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/disk.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/disk.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/mongo.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/mongo.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/mongo.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/mongo.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/nginx.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/nginx.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/nginx.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/nginx.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/ntp.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/ntp.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/ntp.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/ntp.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/permissions.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/permissions.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/permissions.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/permissions.sh diff --git a/apps/countly/src/bin/commands/scripts/healthcheck/process.sh b/archive/apps/countly/src/bin/commands/scripts/healthcheck/process.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/healthcheck/process.sh rename to archive/apps/countly/src/bin/commands/scripts/healthcheck/process.sh diff --git a/apps/countly/src/bin/commands/scripts/mongo.sh b/archive/apps/countly/src/bin/commands/scripts/mongo.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/mongo.sh rename to archive/apps/countly/src/bin/commands/scripts/mongo.sh diff --git a/apps/countly/src/bin/commands/scripts/plugin.js b/archive/apps/countly/src/bin/commands/scripts/plugin.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/plugin.js rename to archive/apps/countly/src/bin/commands/scripts/plugin.js diff --git a/apps/countly/src/bin/commands/scripts/plugin.sh b/archive/apps/countly/src/bin/commands/scripts/plugin.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/plugin.sh rename to archive/apps/countly/src/bin/commands/scripts/plugin.sh diff --git a/apps/countly/src/bin/commands/scripts/reindex.sh b/archive/apps/countly/src/bin/commands/scripts/reindex.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/reindex.sh rename to archive/apps/countly/src/bin/commands/scripts/reindex.sh diff --git a/apps/countly/src/bin/commands/scripts/remove_user.sh b/archive/apps/countly/src/bin/commands/scripts/remove_user.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/remove_user.sh rename to archive/apps/countly/src/bin/commands/scripts/remove_user.sh diff --git a/apps/countly/src/bin/commands/scripts/shellcheck.sh b/archive/apps/countly/src/bin/commands/scripts/shellcheck.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/shellcheck.sh rename to archive/apps/countly/src/bin/commands/scripts/shellcheck.sh diff --git a/apps/countly/src/bin/commands/scripts/task.sh b/archive/apps/countly/src/bin/commands/scripts/task.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/task.sh rename to archive/apps/countly/src/bin/commands/scripts/task.sh diff --git a/apps/countly/src/bin/commands/scripts/update.sh b/archive/apps/countly/src/bin/commands/scripts/update.sh similarity index 100% rename from apps/countly/src/bin/commands/scripts/update.sh rename to archive/apps/countly/src/bin/commands/scripts/update.sh diff --git a/apps/countly/src/bin/commands/scripts/update_translations.js b/archive/apps/countly/src/bin/commands/scripts/update_translations.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/update_translations.js rename to archive/apps/countly/src/bin/commands/scripts/update_translations.js diff --git a/apps/countly/src/bin/commands/scripts/user_mgmt.js b/archive/apps/countly/src/bin/commands/scripts/user_mgmt.js similarity index 100% rename from apps/countly/src/bin/commands/scripts/user_mgmt.js rename to archive/apps/countly/src/bin/commands/scripts/user_mgmt.js diff --git a/apps/countly/src/bin/commands/systemd/countly.service b/archive/apps/countly/src/bin/commands/systemd/countly.service similarity index 100% rename from apps/countly/src/bin/commands/systemd/countly.service rename to archive/apps/countly/src/bin/commands/systemd/countly.service diff --git a/apps/countly/src/bin/commands/systemd/countly.sh b/archive/apps/countly/src/bin/commands/systemd/countly.sh similarity index 100% rename from apps/countly/src/bin/commands/systemd/countly.sh rename to archive/apps/countly/src/bin/commands/systemd/countly.sh diff --git a/apps/countly/src/bin/commands/systemd/install.sh b/archive/apps/countly/src/bin/commands/systemd/install.sh similarity index 100% rename from apps/countly/src/bin/commands/systemd/install.sh rename to archive/apps/countly/src/bin/commands/systemd/install.sh diff --git a/apps/countly/src/bin/commands/systemd/mongod.service b/archive/apps/countly/src/bin/commands/systemd/mongod.service similarity index 100% rename from apps/countly/src/bin/commands/systemd/mongod.service rename to archive/apps/countly/src/bin/commands/systemd/mongod.service diff --git a/apps/countly/src/bin/commands/systemd/mongodb.sh b/archive/apps/countly/src/bin/commands/systemd/mongodb.sh similarity index 100% rename from apps/countly/src/bin/commands/systemd/mongodb.sh rename to archive/apps/countly/src/bin/commands/systemd/mongodb.sh diff --git a/apps/countly/src/bin/commands/upstart/countly-supervisor.conf b/archive/apps/countly/src/bin/commands/upstart/countly-supervisor.conf similarity index 100% rename from apps/countly/src/bin/commands/upstart/countly-supervisor.conf rename to archive/apps/countly/src/bin/commands/upstart/countly-supervisor.conf diff --git a/apps/countly/src/bin/commands/upstart/countly.sh b/archive/apps/countly/src/bin/commands/upstart/countly.sh similarity index 100% rename from apps/countly/src/bin/commands/upstart/countly.sh rename to archive/apps/countly/src/bin/commands/upstart/countly.sh diff --git a/apps/countly/src/bin/commands/upstart/install.sh b/archive/apps/countly/src/bin/commands/upstart/install.sh similarity index 100% rename from apps/countly/src/bin/commands/upstart/install.sh rename to archive/apps/countly/src/bin/commands/upstart/install.sh diff --git a/apps/countly/src/bin/config/countly_user.sh b/archive/apps/countly/src/bin/config/countly_user.sh similarity index 100% rename from apps/countly/src/bin/config/countly_user.sh rename to archive/apps/countly/src/bin/config/countly_user.sh diff --git a/apps/countly/src/bin/config/nginx.conf b/archive/apps/countly/src/bin/config/nginx.conf similarity index 100% rename from apps/countly/src/bin/config/nginx.conf rename to archive/apps/countly/src/bin/config/nginx.conf diff --git a/apps/countly/src/bin/config/nginx.server.block.conf b/archive/apps/countly/src/bin/config/nginx.server.block.conf similarity index 100% rename from apps/countly/src/bin/config/nginx.server.block.conf rename to archive/apps/countly/src/bin/config/nginx.server.block.conf diff --git a/apps/countly/src/bin/config/nginx.server.conf b/archive/apps/countly/src/bin/config/nginx.server.conf similarity index 100% rename from apps/countly/src/bin/config/nginx.server.conf rename to archive/apps/countly/src/bin/config/nginx.server.conf diff --git a/apps/countly/src/bin/config/nginx.server.ssl.conf b/archive/apps/countly/src/bin/config/nginx.server.ssl.conf similarity index 100% rename from apps/countly/src/bin/config/nginx.server.ssl.conf rename to archive/apps/countly/src/bin/config/nginx.server.ssl.conf diff --git a/apps/countly/src/bin/config/supervisord.conf b/archive/apps/countly/src/bin/config/supervisord.conf similarity index 100% rename from apps/countly/src/bin/config/supervisord.conf rename to archive/apps/countly/src/bin/config/supervisord.conf diff --git a/apps/countly/src/bin/config/supervisort.wuser.conf b/archive/apps/countly/src/bin/config/supervisort.wuser.conf similarity index 100% rename from apps/countly/src/bin/config/supervisort.wuser.conf rename to archive/apps/countly/src/bin/config/supervisort.wuser.conf diff --git a/apps/countly/src/bin/countly.install.sh b/archive/apps/countly/src/bin/countly.install.sh similarity index 100% rename from apps/countly/src/bin/countly.install.sh rename to archive/apps/countly/src/bin/countly.install.sh diff --git a/apps/countly/src/bin/countly.install_rhel.sh b/archive/apps/countly/src/bin/countly.install_rhel.sh similarity index 100% rename from apps/countly/src/bin/countly.install_rhel.sh rename to archive/apps/countly/src/bin/countly.install_rhel.sh diff --git a/apps/countly/src/bin/countly.install_travis.sh b/archive/apps/countly/src/bin/countly.install_travis.sh similarity index 100% rename from apps/countly/src/bin/countly.install_travis.sh rename to archive/apps/countly/src/bin/countly.install_travis.sh diff --git a/apps/countly/src/bin/countly.install_ubuntu.sh b/archive/apps/countly/src/bin/countly.install_ubuntu.sh similarity index 100% rename from apps/countly/src/bin/countly.install_ubuntu.sh rename to archive/apps/countly/src/bin/countly.install_ubuntu.sh diff --git a/apps/countly/src/bin/docker/cmd.sh b/archive/apps/countly/src/bin/docker/cmd.sh similarity index 100% rename from apps/countly/src/bin/docker/cmd.sh rename to archive/apps/countly/src/bin/docker/cmd.sh diff --git a/apps/countly/src/bin/docker/k8s/countly-api.yaml b/archive/apps/countly/src/bin/docker/k8s/countly-api.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/countly-api.yaml rename to archive/apps/countly/src/bin/docker/k8s/countly-api.yaml diff --git a/apps/countly/src/bin/docker/k8s/countly-frontend.yaml b/archive/apps/countly/src/bin/docker/k8s/countly-frontend.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/countly-frontend.yaml rename to archive/apps/countly/src/bin/docker/k8s/countly-frontend.yaml diff --git a/apps/countly/src/bin/docker/k8s/countly-ingress-0.22+.yaml b/archive/apps/countly/src/bin/docker/k8s/countly-ingress-0.22+.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/countly-ingress-0.22+.yaml rename to archive/apps/countly/src/bin/docker/k8s/countly-ingress-0.22+.yaml diff --git a/apps/countly/src/bin/docker/k8s/countly-ingress-gce.yaml b/archive/apps/countly/src/bin/docker/k8s/countly-ingress-gce.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/countly-ingress-gce.yaml rename to archive/apps/countly/src/bin/docker/k8s/countly-ingress-gce.yaml diff --git a/apps/countly/src/bin/docker/k8s/countly-ingress.yaml b/archive/apps/countly/src/bin/docker/k8s/countly-ingress.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/countly-ingress.yaml rename to archive/apps/countly/src/bin/docker/k8s/countly-ingress.yaml diff --git a/apps/countly/src/bin/docker/k8s/gce-cluster-init.sh b/archive/apps/countly/src/bin/docker/k8s/gce-cluster-init.sh similarity index 100% rename from apps/countly/src/bin/docker/k8s/gce-cluster-init.sh rename to archive/apps/countly/src/bin/docker/k8s/gce-cluster-init.sh diff --git a/apps/countly/src/bin/docker/k8s/mongo/mongo-single.yaml b/archive/apps/countly/src/bin/docker/k8s/mongo/mongo-single.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/mongo/mongo-single.yaml rename to archive/apps/countly/src/bin/docker/k8s/mongo/mongo-single.yaml diff --git a/apps/countly/src/bin/docker/k8s/mongo/storage-class.yaml b/archive/apps/countly/src/bin/docker/k8s/mongo/storage-class.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/mongo/storage-class.yaml rename to archive/apps/countly/src/bin/docker/k8s/mongo/storage-class.yaml diff --git a/apps/countly/src/bin/docker/k8s/mongo/values.yaml b/archive/apps/countly/src/bin/docker/k8s/mongo/values.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/mongo/values.yaml rename to archive/apps/countly/src/bin/docker/k8s/mongo/values.yaml diff --git a/apps/countly/src/bin/docker/k8s/rbac-config.yaml b/archive/apps/countly/src/bin/docker/k8s/rbac-config.yaml similarity index 100% rename from apps/countly/src/bin/docker/k8s/rbac-config.yaml rename to archive/apps/countly/src/bin/docker/k8s/rbac-config.yaml diff --git a/apps/countly/src/bin/docker/modify.sh b/archive/apps/countly/src/bin/docker/modify.sh similarity index 100% rename from apps/countly/src/bin/docker/modify.sh rename to archive/apps/countly/src/bin/docker/modify.sh diff --git a/apps/countly/src/bin/docker/nginx.server.conf b/archive/apps/countly/src/bin/docker/nginx.server.conf similarity index 100% rename from apps/countly/src/bin/docker/nginx.server.conf rename to archive/apps/countly/src/bin/docker/nginx.server.conf diff --git a/apps/countly/src/bin/docker/postinstall.sh b/archive/apps/countly/src/bin/docker/postinstall.sh similarity index 100% rename from apps/countly/src/bin/docker/postinstall.sh rename to archive/apps/countly/src/bin/docker/postinstall.sh diff --git a/apps/countly/src/bin/docker/preinstall.sh b/archive/apps/countly/src/bin/docker/preinstall.sh similarity index 100% rename from apps/countly/src/bin/docker/preinstall.sh rename to archive/apps/countly/src/bin/docker/preinstall.sh diff --git a/apps/countly/src/bin/installer.sh b/archive/apps/countly/src/bin/installer.sh similarity index 100% rename from apps/countly/src/bin/installer.sh rename to archive/apps/countly/src/bin/installer.sh diff --git a/apps/countly/src/bin/scripts/add_indexes.js b/archive/apps/countly/src/bin/scripts/add_indexes.js similarity index 100% rename from apps/countly/src/bin/scripts/add_indexes.js rename to archive/apps/countly/src/bin/scripts/add_indexes.js diff --git a/apps/countly/src/bin/scripts/block.connections.sh b/archive/apps/countly/src/bin/scripts/block.connections.sh similarity index 100% rename from apps/countly/src/bin/scripts/block.connections.sh rename to archive/apps/countly/src/bin/scripts/block.connections.sh diff --git a/apps/countly/src/bin/scripts/check-translations.js b/archive/apps/countly/src/bin/scripts/check-translations.js similarity index 100% rename from apps/countly/src/bin/scripts/check-translations.js rename to archive/apps/countly/src/bin/scripts/check-translations.js diff --git a/apps/countly/src/bin/scripts/checking_versions.js b/archive/apps/countly/src/bin/scripts/checking_versions.js similarity index 100% rename from apps/countly/src/bin/scripts/checking_versions.js rename to archive/apps/countly/src/bin/scripts/checking_versions.js diff --git a/apps/countly/src/bin/scripts/countly.install.plugins.sh b/archive/apps/countly/src/bin/scripts/countly.install.plugins.sh similarity index 100% rename from apps/countly/src/bin/scripts/countly.install.plugins.sh rename to archive/apps/countly/src/bin/scripts/countly.install.plugins.sh diff --git a/apps/countly/src/bin/scripts/create_nginx_conf.js b/archive/apps/countly/src/bin/scripts/create_nginx_conf.js similarity index 100% rename from apps/countly/src/bin/scripts/create_nginx_conf.js rename to archive/apps/countly/src/bin/scripts/create_nginx_conf.js diff --git a/apps/countly/src/bin/scripts/data_retention.js b/archive/apps/countly/src/bin/scripts/data_retention.js similarity index 100% rename from apps/countly/src/bin/scripts/data_retention.js rename to archive/apps/countly/src/bin/scripts/data_retention.js diff --git a/apps/countly/src/bin/scripts/deploy.sh b/archive/apps/countly/src/bin/scripts/deploy.sh similarity index 100% rename from apps/countly/src/bin/scripts/deploy.sh rename to archive/apps/countly/src/bin/scripts/deploy.sh diff --git a/apps/countly/src/bin/scripts/detect.init.sh b/archive/apps/countly/src/bin/scripts/detect.init.sh similarity index 100% rename from apps/countly/src/bin/scripts/detect.init.sh rename to archive/apps/countly/src/bin/scripts/detect.init.sh diff --git a/apps/countly/src/bin/scripts/device_list/.gitignore b/archive/apps/countly/src/bin/scripts/device_list/.gitignore similarity index 100% rename from apps/countly/src/bin/scripts/device_list/.gitignore rename to archive/apps/countly/src/bin/scripts/device_list/.gitignore diff --git a/apps/countly/src/bin/scripts/device_list/amazon.json b/archive/apps/countly/src/bin/scripts/device_list/amazon.json similarity index 100% rename from apps/countly/src/bin/scripts/device_list/amazon.json rename to archive/apps/countly/src/bin/scripts/device_list/amazon.json diff --git a/apps/countly/src/bin/scripts/device_list/apple.json b/archive/apps/countly/src/bin/scripts/device_list/apple.json similarity index 100% rename from apps/countly/src/bin/scripts/device_list/apple.json rename to archive/apps/countly/src/bin/scripts/device_list/apple.json diff --git a/apps/countly/src/bin/scripts/device_list/generate.js b/archive/apps/countly/src/bin/scripts/device_list/generate.js similarity index 100% rename from apps/countly/src/bin/scripts/device_list/generate.js rename to archive/apps/countly/src/bin/scripts/device_list/generate.js diff --git a/apps/countly/src/bin/scripts/device_list/package.json b/archive/apps/countly/src/bin/scripts/device_list/package.json similarity index 100% rename from apps/countly/src/bin/scripts/device_list/package.json rename to archive/apps/countly/src/bin/scripts/device_list/package.json diff --git a/apps/countly/src/bin/scripts/device_list/scrape_mac_devices.txt b/archive/apps/countly/src/bin/scripts/device_list/scrape_mac_devices.txt similarity index 100% rename from apps/countly/src/bin/scripts/device_list/scrape_mac_devices.txt rename to archive/apps/countly/src/bin/scripts/device_list/scrape_mac_devices.txt diff --git a/apps/countly/src/bin/scripts/device_list/supported_devices.csv b/archive/apps/countly/src/bin/scripts/device_list/supported_devices.csv similarity index 100% rename from apps/countly/src/bin/scripts/device_list/supported_devices.csv rename to archive/apps/countly/src/bin/scripts/device_list/supported_devices.csv diff --git a/apps/countly/src/bin/scripts/done.sh b/archive/apps/countly/src/bin/scripts/done.sh similarity index 100% rename from apps/countly/src/bin/scripts/done.sh rename to archive/apps/countly/src/bin/scripts/done.sh diff --git a/apps/countly/src/bin/scripts/generateDocs.sh b/archive/apps/countly/src/bin/scripts/generateDocs.sh similarity index 100% rename from apps/countly/src/bin/scripts/generateDocs.sh rename to archive/apps/countly/src/bin/scripts/generateDocs.sh diff --git a/apps/countly/src/bin/scripts/install-google-chrome.sh b/archive/apps/countly/src/bin/scripts/install-google-chrome.sh similarity index 100% rename from apps/countly/src/bin/scripts/install-google-chrome.sh rename to archive/apps/countly/src/bin/scripts/install-google-chrome.sh diff --git a/apps/countly/src/bin/scripts/install-python27.sh b/archive/apps/countly/src/bin/scripts/install-python27.sh similarity index 100% rename from apps/countly/src/bin/scripts/install-python27.sh rename to archive/apps/countly/src/bin/scripts/install-python27.sh diff --git a/apps/countly/src/bin/scripts/install.nghttp2.sh b/archive/apps/countly/src/bin/scripts/install.nghttp2.sh similarity index 100% rename from apps/countly/src/bin/scripts/install.nghttp2.sh rename to archive/apps/countly/src/bin/scripts/install.nghttp2.sh diff --git a/apps/countly/src/bin/scripts/install_plugins.js b/archive/apps/countly/src/bin/scripts/install_plugins.js similarity index 100% rename from apps/countly/src/bin/scripts/install_plugins.js rename to archive/apps/countly/src/bin/scripts/install_plugins.js diff --git a/apps/countly/src/bin/scripts/logo.sh b/archive/apps/countly/src/bin/scripts/logo.sh similarity index 100% rename from apps/countly/src/bin/scripts/logo.sh rename to archive/apps/countly/src/bin/scripts/logo.sh diff --git a/apps/countly/src/bin/scripts/make.swap.sh b/archive/apps/countly/src/bin/scripts/make.swap.sh similarity index 100% rename from apps/countly/src/bin/scripts/make.swap.sh rename to archive/apps/countly/src/bin/scripts/make.swap.sh diff --git a/apps/countly/src/bin/scripts/mongodb.install.sh b/archive/apps/countly/src/bin/scripts/mongodb.install.sh similarity index 100% rename from apps/countly/src/bin/scripts/mongodb.install.sh rename to archive/apps/countly/src/bin/scripts/mongodb.install.sh diff --git a/apps/countly/src/bin/scripts/prepare.package.sh b/archive/apps/countly/src/bin/scripts/prepare.package.sh similarity index 100% rename from apps/countly/src/bin/scripts/prepare.package.sh rename to archive/apps/countly/src/bin/scripts/prepare.package.sh diff --git a/apps/countly/src/bin/scripts/timezones/.gitignore b/archive/apps/countly/src/bin/scripts/timezones/.gitignore similarity index 100% rename from apps/countly/src/bin/scripts/timezones/.gitignore rename to archive/apps/countly/src/bin/scripts/timezones/.gitignore diff --git a/apps/countly/src/bin/scripts/timezones/package-lock.json b/archive/apps/countly/src/bin/scripts/timezones/package-lock.json similarity index 100% rename from apps/countly/src/bin/scripts/timezones/package-lock.json rename to archive/apps/countly/src/bin/scripts/timezones/package-lock.json diff --git a/apps/countly/src/bin/scripts/timezones/package.json b/archive/apps/countly/src/bin/scripts/timezones/package.json similarity index 100% rename from apps/countly/src/bin/scripts/timezones/package.json rename to archive/apps/countly/src/bin/scripts/timezones/package.json diff --git a/apps/countly/src/bin/scripts/timezones/timezones.js b/archive/apps/countly/src/bin/scripts/timezones/timezones.js similarity index 100% rename from apps/countly/src/bin/scripts/timezones/timezones.js rename to archive/apps/countly/src/bin/scripts/timezones/timezones.js diff --git a/apps/countly/src/bin/scripts/version_marks.js b/archive/apps/countly/src/bin/scripts/version_marks.js similarity index 100% rename from apps/countly/src/bin/scripts/version_marks.js rename to archive/apps/countly/src/bin/scripts/version_marks.js diff --git a/apps/countly/src/bin/upgrade/15.03/add_uid_app_users.js b/archive/apps/countly/src/bin/upgrade/15.03/add_uid_app_users.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/add_uid_app_users.js rename to archive/apps/countly/src/bin/upgrade/15.03/add_uid_app_users.js diff --git a/apps/countly/src/bin/upgrade/15.03/cleanup.js b/archive/apps/countly/src/bin/upgrade/15.03/cleanup.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/cleanup.js rename to archive/apps/countly/src/bin/upgrade/15.03/cleanup.js diff --git a/apps/countly/src/bin/upgrade/15.03/community.upgrade.sh b/archive/apps/countly/src/bin/upgrade/15.03/community.upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/community.upgrade.sh rename to archive/apps/countly/src/bin/upgrade/15.03/community.upgrade.sh diff --git a/apps/countly/src/bin/upgrade/15.03/events.js b/archive/apps/countly/src/bin/upgrade/15.03/events.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/events.js rename to archive/apps/countly/src/bin/upgrade/15.03/events.js diff --git a/apps/countly/src/bin/upgrade/15.03/parseConnection.js b/archive/apps/countly/src/bin/upgrade/15.03/parseConnection.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/parseConnection.js rename to archive/apps/countly/src/bin/upgrade/15.03/parseConnection.js diff --git a/apps/countly/src/bin/upgrade/15.03/readme.md b/archive/apps/countly/src/bin/upgrade/15.03/readme.md similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/readme.md rename to archive/apps/countly/src/bin/upgrade/15.03/readme.md diff --git a/apps/countly/src/bin/upgrade/15.03/rename_event_collections.js b/archive/apps/countly/src/bin/upgrade/15.03/rename_event_collections.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/rename_event_collections.js rename to archive/apps/countly/src/bin/upgrade/15.03/rename_event_collections.js diff --git a/apps/countly/src/bin/upgrade/15.03/revert.js b/archive/apps/countly/src/bin/upgrade/15.03/revert.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/revert.js rename to archive/apps/countly/src/bin/upgrade/15.03/revert.js diff --git a/apps/countly/src/bin/upgrade/15.03/sessions.js b/archive/apps/countly/src/bin/upgrade/15.03/sessions.js similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/sessions.js rename to archive/apps/countly/src/bin/upgrade/15.03/sessions.js diff --git a/apps/countly/src/bin/upgrade/15.03/upgrade.sh b/archive/apps/countly/src/bin/upgrade/15.03/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/15.03/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/15.03/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/15.08/upgrade.sh b/archive/apps/countly/src/bin/upgrade/15.08/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/15.08/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/15.08/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/16.02/upgrade.sh b/archive/apps/countly/src/bin/upgrade/16.02/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/16.02/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/16.02/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/16.06/upgrade.sh b/archive/apps/countly/src/bin/upgrade/16.06/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/16.06/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/16.06/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/16.12.2/upgrade.sh b/archive/apps/countly/src/bin/upgrade/16.12.2/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/16.12.2/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/16.12.2/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/16.12/upgrade.sh b/archive/apps/countly/src/bin/upgrade/16.12/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/16.12/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/16.12/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/17.05/removeOld.js b/archive/apps/countly/src/bin/upgrade/17.05/removeOld.js similarity index 100% rename from apps/countly/src/bin/upgrade/17.05/removeOld.js rename to archive/apps/countly/src/bin/upgrade/17.05/removeOld.js diff --git a/apps/countly/src/bin/upgrade/17.05/upgrade.sh b/archive/apps/countly/src/bin/upgrade/17.05/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.05/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/17.05/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/17.05/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/17.05/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.05/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/17.05/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/17.05/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/17.05/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.05/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/17.05/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/17.09/upgrade.sh b/archive/apps/countly/src/bin/upgrade/17.09/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.09/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/17.09/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/17.09/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/17.09/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.09/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/17.09/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/17.09/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/17.09/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/17.09/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/17.09/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/18.01.1/scripts/push_clear.js b/archive/apps/countly/src/bin/upgrade/18.01.1/scripts/push_clear.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01.1/scripts/push_clear.js rename to archive/apps/countly/src/bin/upgrade/18.01.1/scripts/push_clear.js diff --git a/apps/countly/src/bin/upgrade/18.01.1/upgrade.sh b/archive/apps/countly/src/bin/upgrade/18.01.1/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01.1/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/18.01.1/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/18.01.1/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/18.01.1/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01.1/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/18.01.1/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/18.01.1/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/18.01.1/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01.1/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/18.01.1/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/18.01/.gitignore b/archive/apps/countly/src/bin/upgrade/18.01/.gitignore similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/.gitignore rename to archive/apps/countly/src/bin/upgrade/18.01/.gitignore diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/backup_drill_meta.sh b/archive/apps/countly/src/bin/upgrade/18.01/scripts/backup_drill_meta.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/backup_drill_meta.sh rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/backup_drill_meta.sh diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/delete_drill_meta.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/delete_drill_meta.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/delete_drill_meta.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/delete_drill_meta.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/export_drill_meta.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/export_drill_meta.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/export_drill_meta.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/export_drill_meta.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.sh b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.sh rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_drill_meta.sh diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_geo_data.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_geo_data.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_geo_data.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_geo_data.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_source.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_source.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_source.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_source.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_source.sh b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_source.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_source.sh rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_source.sh diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/process_users_meta.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/process_users_meta.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/process_users_meta.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/process_users_meta.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/removeUnusedData.js b/archive/apps/countly/src/bin/upgrade/18.01/scripts/removeUnusedData.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/removeUnusedData.js rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/removeUnusedData.js diff --git a/apps/countly/src/bin/upgrade/18.01/scripts/restore_drill_meta.sh b/archive/apps/countly/src/bin/upgrade/18.01/scripts/restore_drill_meta.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/scripts/restore_drill_meta.sh rename to archive/apps/countly/src/bin/upgrade/18.01/scripts/restore_drill_meta.sh diff --git a/apps/countly/src/bin/upgrade/18.01/upgrade.sh b/archive/apps/countly/src/bin/upgrade/18.01/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/18.01/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/18.01/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/18.01/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/18.01/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/18.01/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/18.01/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.01/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/18.01/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/18.04.1/upgrade.sh b/archive/apps/countly/src/bin/upgrade/18.04.1/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04.1/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/18.04.1/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/18.04.1/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/18.04.1/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04.1/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/18.04.1/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/18.04.1/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/18.04.1/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04.1/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/18.04.1/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/18.04/upgrade.sh b/archive/apps/countly/src/bin/upgrade/18.04/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/18.04/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/18.04/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/18.04/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/18.04/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/18.04/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/18.04/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.04/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/18.04/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/18.08/mongo.upgrade.instructions.md b/archive/apps/countly/src/bin/upgrade/18.08/mongo.upgrade.instructions.md similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/mongo.upgrade.instructions.md rename to archive/apps/countly/src/bin/upgrade/18.08/mongo.upgrade.instructions.md diff --git a/apps/countly/src/bin/upgrade/18.08/scripts/tokens_fix_owner.js b/archive/apps/countly/src/bin/upgrade/18.08/scripts/tokens_fix_owner.js similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/scripts/tokens_fix_owner.js rename to archive/apps/countly/src/bin/upgrade/18.08/scripts/tokens_fix_owner.js diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.34.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.34.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade.mongo.34.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.34.sh diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.36.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.36.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade.mongo.36.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.36.sh diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade.mongo.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade.mongo.sh diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/18.08/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/18.08/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/18.08/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/18.08/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/change_alerts_schedule.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/change_alerts_schedule.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/change_alerts_schedule.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/change_alerts_schedule.js diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/clear_jobs.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/clear_jobs.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/clear_jobs.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/clear_jobs.js diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/drop_sessions.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/drop_sessions.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/drop_sessions.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/drop_sessions.js diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/fix_broken_ratings.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/fix_broken_ratings.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/fix_broken_ratings.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/fix_broken_ratings.js diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/fix_report_manager.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/fix_report_manager.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/fix_report_manager.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/fix_report_manager.js diff --git a/apps/countly/src/bin/upgrade/19.02/scripts/updateViews.js b/archive/apps/countly/src/bin/upgrade/19.02/scripts/updateViews.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/scripts/updateViews.js rename to archive/apps/countly/src/bin/upgrade/19.02/scripts/updateViews.js diff --git a/apps/countly/src/bin/upgrade/19.02/upgrade.sh b/archive/apps/countly/src/bin/upgrade/19.02/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/19.02/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/19.02/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/19.02/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/19.02/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/19.02/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/19.02/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.02/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/19.02/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/19.08.1/upgrade.sh b/archive/apps/countly/src/bin/upgrade/19.08.1/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08.1/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/19.08.1/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/19.08.1/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/19.08.1/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08.1/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/19.08.1/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/live_concurrent.js b/archive/apps/countly/src/bin/upgrade/19.08/scripts/live_concurrent.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/live_concurrent.js rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/live_concurrent.js diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/migrate_totp.js b/archive/apps/countly/src/bin/upgrade/19.08/scripts/migrate_totp.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/migrate_totp.js rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/migrate_totp.js diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/notes_upgrade.js b/archive/apps/countly/src/bin/upgrade/19.08/scripts/notes_upgrade.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/notes_upgrade.js rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/notes_upgrade.js diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/push.js b/archive/apps/countly/src/bin/upgrade/19.08/scripts/push.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/push.js rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/push.js diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/remove_chrome_cache.sh b/archive/apps/countly/src/bin/upgrade/19.08/scripts/remove_chrome_cache.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/remove_chrome_cache.sh rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/remove_chrome_cache.sh diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/remove_flash_corssorigin.sh b/archive/apps/countly/src/bin/upgrade/19.08/scripts/remove_flash_corssorigin.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/remove_flash_corssorigin.sh rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/remove_flash_corssorigin.sh diff --git a/apps/countly/src/bin/upgrade/19.08/scripts/update_crashes.js b/archive/apps/countly/src/bin/upgrade/19.08/scripts/update_crashes.js similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/scripts/update_crashes.js rename to archive/apps/countly/src/bin/upgrade/19.08/scripts/update_crashes.js diff --git a/apps/countly/src/bin/upgrade/19.08/upgrade.sh b/archive/apps/countly/src/bin/upgrade/19.08/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/19.08/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/19.08/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/19.08/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/19.08/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/19.08/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/19.08/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/19.08/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/19.08/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/clearOldTokens.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/clearOldTokens.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/clearOldTokens.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/clearOldTokens.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/encrypt_2fa_secrets.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/encrypt_2fa_secrets.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/encrypt_2fa_secrets.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/encrypt_2fa_secrets.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/fix_nxret.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/fix_nxret.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/fix_nxret.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/fix_nxret.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/recover_widgets.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/recover_widgets.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/recover_widgets.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/recover_widgets.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/remove_drill_index.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/remove_drill_index.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/remove_drill_index.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/remove_drill_index.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/remove_moved_files.sh b/archive/apps/countly/src/bin/upgrade/20.04/scripts/remove_moved_files.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/remove_moved_files.sh rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/remove_moved_files.sh diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/set_additional_api_configs.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/set_additional_api_configs.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/set_additional_api_configs.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/set_additional_api_configs.js diff --git a/apps/countly/src/bin/upgrade/20.04/scripts/upgradeReports.js b/archive/apps/countly/src/bin/upgrade/20.04/scripts/upgradeReports.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/scripts/upgradeReports.js rename to archive/apps/countly/src/bin/upgrade/20.04/scripts/upgradeReports.js diff --git a/apps/countly/src/bin/upgrade/20.04/upgrade.sh b/archive/apps/countly/src/bin/upgrade/20.04/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/20.04/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/20.04/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/20.04/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/20.04/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/20.04/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/20.04/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.04/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/20.04/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/20.11.1/scripts/cleanup_concurrent.js b/archive/apps/countly/src/bin/upgrade/20.11.1/scripts/cleanup_concurrent.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.11.1/scripts/cleanup_concurrent.js rename to archive/apps/countly/src/bin/upgrade/20.11.1/scripts/cleanup_concurrent.js diff --git a/apps/countly/src/bin/upgrade/20.11.1/upgrade.sh b/archive/apps/countly/src/bin/upgrade/20.11.1/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11.1/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/20.11.1/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/20.11.1/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/20.11.1/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11.1/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/20.11.1/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/20.11.1/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/20.11.1/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11.1/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/20.11.1/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/20.11/scripts/cleanup_concurrent.js b/archive/apps/countly/src/bin/upgrade/20.11/scripts/cleanup_concurrent.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/scripts/cleanup_concurrent.js rename to archive/apps/countly/src/bin/upgrade/20.11/scripts/cleanup_concurrent.js diff --git a/apps/countly/src/bin/upgrade/20.11/scripts/mongo_connection.js b/archive/apps/countly/src/bin/upgrade/20.11/scripts/mongo_connection.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/scripts/mongo_connection.js rename to archive/apps/countly/src/bin/upgrade/20.11/scripts/mongo_connection.js diff --git a/apps/countly/src/bin/upgrade/20.11/scripts/removeUserProps.js b/archive/apps/countly/src/bin/upgrade/20.11/scripts/removeUserProps.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/scripts/removeUserProps.js rename to archive/apps/countly/src/bin/upgrade/20.11/scripts/removeUserProps.js diff --git a/apps/countly/src/bin/upgrade/20.11/scripts/update_app_users.js b/archive/apps/countly/src/bin/upgrade/20.11/scripts/update_app_users.js similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/scripts/update_app_users.js rename to archive/apps/countly/src/bin/upgrade/20.11/scripts/update_app_users.js diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.40.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.40.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade.mongo.40.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.40.sh diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.42.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.42.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade.mongo.42.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.42.sh diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.44.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.44.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade.mongo.44.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade.mongo.44.sh diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade.sh diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade_db.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade_db.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade_db.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade_db.sh diff --git a/apps/countly/src/bin/upgrade/20.11/upgrade_fs.sh b/archive/apps/countly/src/bin/upgrade/20.11/upgrade_fs.sh similarity index 100% rename from apps/countly/src/bin/upgrade/20.11/upgrade_fs.sh rename to archive/apps/countly/src/bin/upgrade/20.11/upgrade_fs.sh diff --git a/apps/countly/src/bin/upgrade/common.upgrade.sh b/archive/apps/countly/src/bin/upgrade/common.upgrade.sh similarity index 100% rename from apps/countly/src/bin/upgrade/common.upgrade.sh rename to archive/apps/countly/src/bin/upgrade/common.upgrade.sh diff --git a/apps/countly/src/bin/upgrade/countly.github.update.sh b/archive/apps/countly/src/bin/upgrade/countly.github.update.sh similarity index 100% rename from apps/countly/src/bin/upgrade/countly.github.update.sh rename to archive/apps/countly/src/bin/upgrade/countly.github.update.sh diff --git a/apps/countly/src/docker-compose.yml b/archive/apps/countly/src/docker-compose.yml similarity index 100% rename from apps/countly/src/docker-compose.yml rename to archive/apps/countly/src/docker-compose.yml diff --git a/apps/countly/src/filelist b/archive/apps/countly/src/filelist similarity index 100% rename from apps/countly/src/filelist rename to archive/apps/countly/src/filelist diff --git a/apps/countly/variables.json b/archive/apps/countly/variables.json similarity index 100% rename from apps/countly/variables.json rename to archive/apps/countly/variables.json diff --git a/apps/coze/.env b/archive/apps/coze/.env similarity index 100% rename from apps/coze/.env rename to archive/apps/coze/.env diff --git a/apps/coze/CHANGELOG.md b/archive/apps/coze/CHANGELOG.md similarity index 100% rename from apps/coze/CHANGELOG.md rename to archive/apps/coze/CHANGELOG.md diff --git a/apps/coze/Notes.md b/archive/apps/coze/Notes.md similarity index 100% rename from apps/coze/Notes.md rename to archive/apps/coze/Notes.md diff --git a/apps/coze/README.md b/archive/apps/coze/README.md similarity index 100% rename from apps/coze/README.md rename to archive/apps/coze/README.md diff --git a/apps/coze/docker-compose.yml b/archive/apps/coze/docker-compose.yml similarity index 100% rename from apps/coze/docker-compose.yml rename to archive/apps/coze/docker-compose.yml diff --git a/apps/dashy/src/README.md b/archive/apps/coze/src/README.md similarity index 100% rename from apps/dashy/src/README.md rename to archive/apps/coze/src/README.md diff --git a/apps/coze/src/atlas/opencoze_latest_schema.hcl b/archive/apps/coze/src/atlas/opencoze_latest_schema.hcl similarity index 100% rename from apps/coze/src/atlas/opencoze_latest_schema.hcl rename to archive/apps/coze/src/atlas/opencoze_latest_schema.hcl diff --git a/apps/coze/src/conf/admin/index.html b/archive/apps/coze/src/conf/admin/index.html similarity index 100% rename from apps/coze/src/conf/admin/index.html rename to archive/apps/coze/src/conf/admin/index.html diff --git a/apps/coze/src/conf/model/model_meta.json b/archive/apps/coze/src/conf/model/model_meta.json similarity index 100% rename from apps/coze/src/conf/model/model_meta.json rename to archive/apps/coze/src/conf/model/model_meta.json diff --git a/apps/coze/src/conf/model/template/model_template_ark.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-lite.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-lite.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-lite.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-lite.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-256k.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-256k.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-256k.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-256k.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-32k.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-32k.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-32k.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-pro-32k.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-pro.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-pro.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-pro.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-pro.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-vision-pro.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-vision-pro.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-vision-pro.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-thinking-vision-pro.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-lite.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-lite.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-lite.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-lite.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-pro.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-pro.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-pro.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-1.5-vision-pro.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-flash.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-flash.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-flash.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-flash.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-thinking.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-thinking.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-thinking.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6-thinking.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_doubao-seed-1.6.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-r1.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-r1.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-r1.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-r1.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-v3.yaml b/archive/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-v3.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-v3.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ark_volc_deepseek-v3.yaml diff --git a/apps/coze/src/conf/model/template/model_template_basic.yaml b/archive/apps/coze/src/conf/model/template/model_template_basic.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_basic.yaml rename to archive/apps/coze/src/conf/model/template/model_template_basic.yaml diff --git a/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6-flash.yaml b/archive/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6-flash.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6-flash.yaml rename to archive/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6-flash.yaml diff --git a/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6.yaml b/archive/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6.yaml rename to archive/apps/coze/src/conf/model/template/model_template_byteplus_seed-1.6.yaml diff --git a/apps/coze/src/conf/model/template/model_template_claude.yaml b/archive/apps/coze/src/conf/model/template/model_template_claude.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_claude.yaml rename to archive/apps/coze/src/conf/model/template/model_template_claude.yaml diff --git a/apps/coze/src/conf/model/template/model_template_deepseek.yaml b/archive/apps/coze/src/conf/model/template/model_template_deepseek.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_deepseek.yaml rename to archive/apps/coze/src/conf/model/template/model_template_deepseek.yaml diff --git a/apps/coze/src/conf/model/template/model_template_gemini.yaml b/archive/apps/coze/src/conf/model/template/model_template_gemini.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_gemini.yaml rename to archive/apps/coze/src/conf/model/template/model_template_gemini.yaml diff --git a/apps/coze/src/conf/model/template/model_template_ollama.yaml b/archive/apps/coze/src/conf/model/template/model_template_ollama.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_ollama.yaml rename to archive/apps/coze/src/conf/model/template/model_template_ollama.yaml diff --git a/apps/coze/src/conf/model/template/model_template_openai.yaml b/archive/apps/coze/src/conf/model/template/model_template_openai.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_openai.yaml rename to archive/apps/coze/src/conf/model/template/model_template_openai.yaml diff --git a/apps/coze/src/conf/model/template/model_template_qwen.yaml b/archive/apps/coze/src/conf/model/template/model_template_qwen.yaml similarity index 100% rename from apps/coze/src/conf/model/template/model_template_qwen.yaml rename to archive/apps/coze/src/conf/model/template/model_template_qwen.yaml diff --git a/apps/coze/src/conf/plugin/common/oauth_schema.json b/archive/apps/coze/src/conf/plugin/common/oauth_schema.json similarity index 100% rename from apps/coze/src/conf/plugin/common/oauth_schema.json rename to archive/apps/coze/src/conf/plugin/common/oauth_schema.json diff --git a/apps/coze/src/conf/plugin/pluginproduct/bocha_search.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/bocha_search.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/bocha_search.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/bocha_search.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/chestnut_sign.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/chestnut_sign.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/chestnut_sign.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/chestnut_sign.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/gaode_map.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/gaode_map.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/gaode_map.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/gaode_map.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/image_compression.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/image_compression.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/image_compression.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/image_compression.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_authentication_authorization.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_authentication_authorization.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_authentication_authorization.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_authentication_authorization.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_base.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_base.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_base.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_base.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_calendar.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_calendar.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_calendar.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_calendar.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_docx.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_docx.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_docx.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_docx.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_message.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_message.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_message.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_message.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_sheet.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_sheet.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_sheet.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_sheet.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_task.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_task.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_task.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_task.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/lark_wiki.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/lark_wiki.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/lark_wiki.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/lark_wiki.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/library_search.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/library_search.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/library_search.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/library_search.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/maker_smart_design.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/maker_smart_design.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/maker_smart_design.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/maker_smart_design.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/plugin_meta.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/plugin_meta.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/plugin_meta.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/plugin_meta.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/sky_eye_check.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/sky_eye_check.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/sky_eye_check.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/sky_eye_check.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/sohu_hot_news.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/sohu_hot_news.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/sohu_hot_news.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/sohu_hot_news.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/wolfram_alpha.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/wolfram_alpha.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/wolfram_alpha.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/wolfram_alpha.yaml diff --git a/apps/coze/src/conf/plugin/pluginproduct/worth_buying.yaml b/archive/apps/coze/src/conf/plugin/pluginproduct/worth_buying.yaml similarity index 100% rename from apps/coze/src/conf/plugin/pluginproduct/worth_buying.yaml rename to archive/apps/coze/src/conf/plugin/pluginproduct/worth_buying.yaml diff --git a/apps/coze/src/conf/prompt/messages_to_query_template_jinja2.json b/archive/apps/coze/src/conf/prompt/messages_to_query_template_jinja2.json similarity index 100% rename from apps/coze/src/conf/prompt/messages_to_query_template_jinja2.json rename to archive/apps/coze/src/conf/prompt/messages_to_query_template_jinja2.json diff --git a/apps/coze/src/conf/prompt/nl2sql_template_jinja2.json b/archive/apps/coze/src/conf/prompt/nl2sql_template_jinja2.json similarity index 100% rename from apps/coze/src/conf/prompt/nl2sql_template_jinja2.json rename to archive/apps/coze/src/conf/prompt/nl2sql_template_jinja2.json diff --git a/apps/coze/src/conf/workflow/config.yaml b/archive/apps/coze/src/conf/workflow/config.yaml similarity index 100% rename from apps/coze/src/conf/workflow/config.yaml rename to archive/apps/coze/src/conf/workflow/config.yaml diff --git a/apps/coze/src/nginx/conf.d/default.conf b/archive/apps/coze/src/nginx/conf.d/default.conf similarity index 100% rename from apps/coze/src/nginx/conf.d/default.conf rename to archive/apps/coze/src/nginx/conf.d/default.conf diff --git a/apps/coze/src/nginx/nginx.conf b/archive/apps/coze/src/nginx/nginx.conf similarity index 100% rename from apps/coze/src/nginx/nginx.conf rename to archive/apps/coze/src/nginx/nginx.conf diff --git a/apps/docker/src/nginx-proxy.conf b/archive/apps/coze/src/nginx/ssl/.gitkeep similarity index 100% rename from apps/docker/src/nginx-proxy.conf rename to archive/apps/coze/src/nginx/ssl/.gitkeep diff --git a/apps/coze/src/volumes/elasticsearch/analysis-smartcn.zip b/archive/apps/coze/src/volumes/elasticsearch/analysis-smartcn.zip similarity index 100% rename from apps/coze/src/volumes/elasticsearch/analysis-smartcn.zip rename to archive/apps/coze/src/volumes/elasticsearch/analysis-smartcn.zip diff --git a/apps/coze/src/volumes/elasticsearch/elasticsearch.yml b/archive/apps/coze/src/volumes/elasticsearch/elasticsearch.yml similarity index 100% rename from apps/coze/src/volumes/elasticsearch/elasticsearch.yml rename to archive/apps/coze/src/volumes/elasticsearch/elasticsearch.yml diff --git a/apps/coze/src/volumes/elasticsearch/es_index_schema/coze_resource.index-template.json b/archive/apps/coze/src/volumes/elasticsearch/es_index_schema/coze_resource.index-template.json similarity index 100% rename from apps/coze/src/volumes/elasticsearch/es_index_schema/coze_resource.index-template.json rename to archive/apps/coze/src/volumes/elasticsearch/es_index_schema/coze_resource.index-template.json diff --git a/apps/coze/src/volumes/elasticsearch/es_index_schema/project_draft.index-template.json b/archive/apps/coze/src/volumes/elasticsearch/es_index_schema/project_draft.index-template.json similarity index 100% rename from apps/coze/src/volumes/elasticsearch/es_index_schema/project_draft.index-template.json rename to archive/apps/coze/src/volumes/elasticsearch/es_index_schema/project_draft.index-template.json diff --git a/apps/coze/src/volumes/elasticsearch/setup_es.sh b/archive/apps/coze/src/volumes/elasticsearch/setup_es.sh similarity index 100% rename from apps/coze/src/volumes/elasticsearch/setup_es.sh rename to archive/apps/coze/src/volumes/elasticsearch/setup_es.sh diff --git a/apps/kasmweb/src/filelist b/archive/apps/coze/src/volumes/etcd/etcd.conf.yml old mode 100644 new mode 100755 similarity index 100% rename from apps/kasmweb/src/filelist rename to archive/apps/coze/src/volumes/etcd/etcd.conf.yml diff --git a/apps/coze/src/volumes/minio/.mc/config.json b/archive/apps/coze/src/volumes/minio/.mc/config.json similarity index 100% rename from apps/coze/src/volumes/minio/.mc/config.json rename to archive/apps/coze/src/volumes/minio/.mc/config.json diff --git a/apps/coze/src/volumes/minio/default_icon/claude_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/claude_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/claude_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/claude_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/connector-api.jpg b/archive/apps/coze/src/volumes/minio/default_icon/connector-api.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/connector-api.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/connector-api.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/connector-chat-sdk.jpg b/archive/apps/coze/src/volumes/minio/default_icon/connector-chat-sdk.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/connector-chat-sdk.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/connector-chat-sdk.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/connector-coze.png b/archive/apps/coze/src/volumes/minio/default_icon/connector-coze.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/connector-coze.png rename to archive/apps/coze/src/volumes/minio/default_icon/connector-coze.png diff --git a/apps/coze/src/volumes/minio/default_icon/deepseek_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/deepseek_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/deepseek_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/deepseek_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_agent_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_agent_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_agent_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_agent_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_app_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_app_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_app_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_app_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_database_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_database_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_database_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_database_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_dataset_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_dataset_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_dataset_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_dataset_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_prompt_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_prompt_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_prompt_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_prompt_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/default_workflow_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/default_workflow_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/default_workflow_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/default_workflow_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/doubao_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/doubao_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/doubao_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/doubao_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/gemini_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/gemini_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/gemini_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/gemini_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/image_kn_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/image_kn_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/image_kn_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/image_kn_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/ollama.png b/archive/apps/coze/src/volumes/minio/default_icon/ollama.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/ollama.png rename to archive/apps/coze/src/volumes/minio/default_icon/ollama.png diff --git a/apps/coze/src/volumes/minio/default_icon/openai_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/openai_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/openai_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/openai_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/plugin_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/plugin_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/plugin_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/plugin_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/qwen_v2.png b/archive/apps/coze/src/volumes/minio/default_icon/qwen_v2.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/qwen_v2.png rename to archive/apps/coze/src/volumes/minio/default_icon/qwen_v2.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_10coz_folder.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_10coz_folder.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_10coz_folder.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_10coz_folder.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_11coz_trans_switch.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_11coz_trans_switch.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_11coz_trans_switch.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_11coz_trans_switch.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_12coz_location.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_12coz_location.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_12coz_location.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_12coz_location.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_13coz_link.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_13coz_link.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_13coz_link.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_13coz_link.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_14coz_clock.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_14coz_clock.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_14coz_clock.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_14coz_clock.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_1coz_ai.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_1coz_ai.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_1coz_ai.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_1coz_ai.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_2icon_ai_writing.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_2icon_ai_writing.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_2icon_ai_writing.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_2icon_ai_writing.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_3coz_imageflow.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_3coz_imageflow.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_3coz_imageflow.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_3coz_imageflow.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_4icon_aisearch.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_4icon_aisearch.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_4icon_aisearch.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_4icon_aisearch.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_5icon_summary.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_5icon_summary.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_5icon_summary.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_5icon_summary.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_6icon_digest.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_6icon_digest.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_6icon_digest.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_6icon_digest.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_7icon_video.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_7icon_video.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_7icon_video.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_7icon_video.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_8icon_audio.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_8icon_audio.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_8icon_audio.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_8icon_audio.png diff --git a/apps/coze/src/volumes/minio/default_icon/shortcut_9coz_variables.png b/archive/apps/coze/src/volumes/minio/default_icon/shortcut_9coz_variables.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/shortcut_9coz_variables.png rename to archive/apps/coze/src/volumes/minio/default_icon/shortcut_9coz_variables.png diff --git a/apps/coze/src/volumes/minio/default_icon/table_kn_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/table_kn_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/table_kn_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/table_kn_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/team_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/team_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/team_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/team_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/template_7416518827749425204.png b/archive/apps/coze/src/volumes/minio/default_icon/template_7416518827749425204.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/template_7416518827749425204.png rename to archive/apps/coze/src/volumes/minio/default_icon/template_7416518827749425204.png diff --git a/apps/coze/src/volumes/minio/default_icon/template_7418535986059067392.png b/archive/apps/coze/src/volumes/minio/default_icon/template_7418535986059067392.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/template_7418535986059067392.png rename to archive/apps/coze/src/volumes/minio/default_icon/template_7418535986059067392.png diff --git a/apps/coze/src/volumes/minio/default_icon/text_kn_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/text_kn_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/text_kn_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/text_kn_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/user_default_icon.png b/archive/apps/coze/src/volumes/minio/default_icon/user_default_icon.png similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/user_default_icon.png rename to archive/apps/coze/src/volumes/minio/default_icon/user_default_icon.png diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-batch.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-batch.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-batch.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-batch.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-break.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-break.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-break.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-break.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-clear-context.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-clear-context.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-clear-context.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-clear-context.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-code.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-code.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-code.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-code.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-condition.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-condition.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-condition.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-condition.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-continue.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-continue.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-continue.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-continue.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-conversation.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-conversation.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-conversation.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-conversation.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-message.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-message.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-message.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-create-message.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-create.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-create.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-create.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-create.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-delete.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-delete.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-delete.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-delete.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-query.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-query.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-query.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-query.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-update.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-update.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-update.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database-update.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-database.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-conversation.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-conversation.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-conversation.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-conversation.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-message.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-message.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-message.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-delete-message.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-end.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-end.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-end.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-end.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-http.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-http.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-http.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-http.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-canvas.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-canvas.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-canvas.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-canvas.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-generate.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-generate.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-generate.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-generate.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-reference.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-reference.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-reference.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-image-reference.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-imageflow.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-imageflow.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-imageflow.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-imageflow.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-intent.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-intent.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-intent.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-intent.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-parser.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-parser.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-parser.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-parser.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-stringify.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-stringify.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-stringify.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-json-stringify.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-delete.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-delete.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-delete.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-delete.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-query.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-query.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-query.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-query.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-write.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-write.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-write.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-knowledge-write.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-llm.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-llm.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-llm.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-llm.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop-set-variable.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop-set-variable.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop-set-variable.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop-set-variable.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-loop.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-ltm.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-ltm.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-ltm.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-ltm.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-output.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-output.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-output.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-output.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-plugin.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-plugin.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-plugin.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-plugin.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-history.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-history.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-history.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-history.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-list.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-list.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-list.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-conversation-list.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-message-list.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-message-list.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-message-list.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-query-message-list.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-question.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-question.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-question.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-question.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-chat.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-chat.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-chat.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-chat.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-variable.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-variable.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-variable.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-scene-variable.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-start.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-start.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-start.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-start.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-text.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-text.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-text.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-text.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-delete.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-delete.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-delete.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-delete.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-read.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-read.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-read.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-read.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-upsert.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-upsert.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-upsert.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-trigger-upsert.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-conversation.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-conversation.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-conversation.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-conversation.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-message.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-message.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-message.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-update-message.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-assign.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-assign.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-assign.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-assign.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-merge.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-merge.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-merge.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable-merge.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-variable.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-audio-extractor.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-audio-extractor.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-audio-extractor.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-audio-extractor.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-frame-extractor.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-frame-extractor.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-frame-extractor.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-frame-extractor.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-generation.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-generation.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-generation.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-video-generation.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-workflow.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-workflow.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-workflow.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon-workflow.jpg diff --git a/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon_input.jpg b/archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon_input.jpg similarity index 100% rename from apps/coze/src/volumes/minio/default_icon/workflow_icon/icon_input.jpg rename to archive/apps/coze/src/volumes/minio/default_icon/workflow_icon/icon_input.jpg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_ai_ppt.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_ai_ppt.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_ai_ppt.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_ai_ppt.jpeg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_bocha_search.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_bocha_search.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_bocha_search.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_bocha_search.jpeg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chat_ppt.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chat_ppt.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_chat_ppt.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chat_ppt.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chestnut_sign.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chestnut_sign.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_chestnut_sign.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_chestnut_sign.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_constellation.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_constellation.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_constellation.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_constellation.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_gaode_map.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_gaode_map.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_gaode_map.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_gaode_map.jpeg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_image_compression.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_image_compression.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_image_compression.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_image_compression.jpeg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_authentication_authorization.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_authentication_authorization.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_authentication_authorization.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_authentication_authorization.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_base.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_base.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_base.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_base.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_calendar.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_calendar.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_calendar.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_calendar.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_docx.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_docx.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_docx.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_docx.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_message.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_message.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_message.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_message.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_sheet.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_sheet.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_sheet.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_sheet.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_task.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_task.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_task.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_task.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_wiki.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_wiki.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_wiki.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_lark_wiki.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_library_search.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_library_search.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_library_search.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_library_search.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_liepin.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_liepin.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_liepin.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_liepin.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_maker_smart_design.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_maker_smart_design.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_maker_smart_design.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_maker_smart_design.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sky_eye_check.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sky_eye_check.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_sky_eye_check.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sky_eye_check.jpeg diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sohu_hot_news.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sohu_hot_news.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_sohu_hot_news.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_sohu_hot_news.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_wolfram_alpha.png b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_wolfram_alpha.png similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_wolfram_alpha.png rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_wolfram_alpha.png diff --git a/apps/coze/src/volumes/minio/official_plugin_icon/plugin_worth_buying.jpeg b/archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_worth_buying.jpeg similarity index 100% rename from apps/coze/src/volumes/minio/official_plugin_icon/plugin_worth_buying.jpeg rename to archive/apps/coze/src/volumes/minio/official_plugin_icon/plugin_worth_buying.jpeg diff --git a/apps/coze/src/volumes/mysql/schema.sql b/archive/apps/coze/src/volumes/mysql/schema.sql similarity index 100% rename from apps/coze/src/volumes/mysql/schema.sql rename to archive/apps/coze/src/volumes/mysql/schema.sql diff --git a/apps/coze/src/volumes/mysql/sql_init.sql b/archive/apps/coze/src/volumes/mysql/sql_init.sql similarity index 100% rename from apps/coze/src/volumes/mysql/sql_init.sql rename to archive/apps/coze/src/volumes/mysql/sql_init.sql diff --git a/apps/coze/variables.json b/archive/apps/coze/variables.json similarity index 100% rename from apps/coze/variables.json rename to archive/apps/coze/variables.json diff --git a/apps/crowdsec/.env b/archive/apps/crowdsec/.env similarity index 100% rename from apps/crowdsec/.env rename to archive/apps/crowdsec/.env diff --git a/apps/crowdsec/CHANGELOG.md b/archive/apps/crowdsec/CHANGELOG.md similarity index 100% rename from apps/crowdsec/CHANGELOG.md rename to archive/apps/crowdsec/CHANGELOG.md diff --git a/apps/crowdsec/Notes.md b/archive/apps/crowdsec/Notes.md similarity index 100% rename from apps/crowdsec/Notes.md rename to archive/apps/crowdsec/Notes.md diff --git a/apps/crowdsec/README.md b/archive/apps/crowdsec/README.md similarity index 100% rename from apps/crowdsec/README.md rename to archive/apps/crowdsec/README.md diff --git a/apps/crowdsec/docker-compose.yml b/archive/apps/crowdsec/docker-compose.yml similarity index 100% rename from apps/crowdsec/docker-compose.yml rename to archive/apps/crowdsec/docker-compose.yml diff --git a/apps/databasus/src/README.md b/archive/apps/crowdsec/src/README.md similarity index 100% rename from apps/databasus/src/README.md rename to archive/apps/crowdsec/src/README.md diff --git a/apps/crowdsec/variables.json b/archive/apps/crowdsec/variables.json similarity index 100% rename from apps/crowdsec/variables.json rename to archive/apps/crowdsec/variables.json diff --git a/apps/dashy/.env b/archive/apps/dashy/.env similarity index 100% rename from apps/dashy/.env rename to archive/apps/dashy/.env diff --git a/apps/dashy/CHANGELOG.md b/archive/apps/dashy/CHANGELOG.md similarity index 100% rename from apps/dashy/CHANGELOG.md rename to archive/apps/dashy/CHANGELOG.md diff --git a/apps/dashy/Notes.md b/archive/apps/dashy/Notes.md similarity index 100% rename from apps/dashy/Notes.md rename to archive/apps/dashy/Notes.md diff --git a/apps/dashy/README.md b/archive/apps/dashy/README.md similarity index 100% rename from apps/dashy/README.md rename to archive/apps/dashy/README.md diff --git a/apps/dashy/docker-compose.yml b/archive/apps/dashy/docker-compose.yml similarity index 100% rename from apps/dashy/docker-compose.yml rename to archive/apps/dashy/docker-compose.yml diff --git a/apps/ddnsgo/src/README.md b/archive/apps/dashy/src/README.md similarity index 100% rename from apps/ddnsgo/src/README.md rename to archive/apps/dashy/src/README.md diff --git a/apps/dashy/variables.json b/archive/apps/dashy/variables.json similarity index 100% rename from apps/dashy/variables.json rename to archive/apps/dashy/variables.json diff --git a/apps/databasus/.env b/archive/apps/databasus/.env similarity index 100% rename from apps/databasus/.env rename to archive/apps/databasus/.env diff --git a/apps/databasus/CHANGELOG.md b/archive/apps/databasus/CHANGELOG.md similarity index 100% rename from apps/databasus/CHANGELOG.md rename to archive/apps/databasus/CHANGELOG.md diff --git a/apps/consul/Notes.md b/archive/apps/databasus/Notes.md similarity index 100% rename from apps/consul/Notes.md rename to archive/apps/databasus/Notes.md diff --git a/apps/databasus/README.md b/archive/apps/databasus/README.md similarity index 100% rename from apps/databasus/README.md rename to archive/apps/databasus/README.md diff --git a/apps/databasus/docker-compose.yml b/archive/apps/databasus/docker-compose.yml similarity index 100% rename from apps/databasus/docker-compose.yml rename to archive/apps/databasus/docker-compose.yml diff --git a/apps/debezium/src/README.md b/archive/apps/databasus/src/README.md similarity index 100% rename from apps/debezium/src/README.md rename to archive/apps/databasus/src/README.md diff --git a/apps/databasus/src/nginx-proxy.conf.template b/archive/apps/databasus/src/nginx-proxy.conf.template similarity index 100% rename from apps/databasus/src/nginx-proxy.conf.template rename to archive/apps/databasus/src/nginx-proxy.conf.template diff --git a/apps/databasus/src/php_exra.ini b/archive/apps/databasus/src/php_exra.ini similarity index 100% rename from apps/databasus/src/php_exra.ini rename to archive/apps/databasus/src/php_exra.ini diff --git a/apps/databasus/tests/cases.yml b/archive/apps/databasus/tests/cases.yml similarity index 100% rename from apps/databasus/tests/cases.yml rename to archive/apps/databasus/tests/cases.yml diff --git a/apps/databasus/variables.json b/archive/apps/databasus/variables.json similarity index 100% rename from apps/databasus/variables.json rename to archive/apps/databasus/variables.json diff --git a/apps/datahub/.env b/archive/apps/datahub/.env similarity index 100% rename from apps/datahub/.env rename to archive/apps/datahub/.env diff --git a/apps/datahub/CHANGELOG.md b/archive/apps/datahub/CHANGELOG.md similarity index 100% rename from apps/datahub/CHANGELOG.md rename to archive/apps/datahub/CHANGELOG.md diff --git a/apps/datahub/Notes.md b/archive/apps/datahub/Notes.md similarity index 100% rename from apps/datahub/Notes.md rename to archive/apps/datahub/Notes.md diff --git a/apps/datahub/README.md b/archive/apps/datahub/README.md similarity index 100% rename from apps/datahub/README.md rename to archive/apps/datahub/README.md diff --git a/apps/datahub/docker-compose.yml b/archive/apps/datahub/docker-compose.yml similarity index 100% rename from apps/datahub/docker-compose.yml rename to archive/apps/datahub/docker-compose.yml diff --git a/apps/datahub/variables.json b/archive/apps/datahub/variables.json similarity index 100% rename from apps/datahub/variables.json rename to archive/apps/datahub/variables.json diff --git a/apps/ddnsgo/.env b/archive/apps/ddnsgo/.env similarity index 100% rename from apps/ddnsgo/.env rename to archive/apps/ddnsgo/.env diff --git a/apps/ddnsgo/CHANGELOG.md b/archive/apps/ddnsgo/CHANGELOG.md similarity index 100% rename from apps/ddnsgo/CHANGELOG.md rename to archive/apps/ddnsgo/CHANGELOG.md diff --git a/apps/ddnsgo/Notes.md b/archive/apps/ddnsgo/Notes.md similarity index 100% rename from apps/ddnsgo/Notes.md rename to archive/apps/ddnsgo/Notes.md diff --git a/apps/ddnsgo/README.md b/archive/apps/ddnsgo/README.md similarity index 100% rename from apps/ddnsgo/README.md rename to archive/apps/ddnsgo/README.md diff --git a/apps/ddnsgo/docker-compose.yml b/archive/apps/ddnsgo/docker-compose.yml similarity index 100% rename from apps/ddnsgo/docker-compose.yml rename to archive/apps/ddnsgo/docker-compose.yml diff --git a/apps/docker/src/README.md b/archive/apps/ddnsgo/src/README.md similarity index 100% rename from apps/docker/src/README.md rename to archive/apps/ddnsgo/src/README.md diff --git a/apps/ddnsgo/variables.json b/archive/apps/ddnsgo/variables.json similarity index 100% rename from apps/ddnsgo/variables.json rename to archive/apps/ddnsgo/variables.json diff --git a/apps/debezium/.env b/archive/apps/debezium/.env similarity index 100% rename from apps/debezium/.env rename to archive/apps/debezium/.env diff --git a/apps/debezium/CHANGELOG.md b/archive/apps/debezium/CHANGELOG.md similarity index 100% rename from apps/debezium/CHANGELOG.md rename to archive/apps/debezium/CHANGELOG.md diff --git a/apps/debezium/Dockerfile b/archive/apps/debezium/Dockerfile similarity index 100% rename from apps/debezium/Dockerfile rename to archive/apps/debezium/Dockerfile diff --git a/apps/databasus/Notes.md b/archive/apps/debezium/Notes.md similarity index 100% rename from apps/databasus/Notes.md rename to archive/apps/debezium/Notes.md diff --git a/apps/debezium/README.jinja2 b/archive/apps/debezium/README.jinja2 similarity index 100% rename from apps/debezium/README.jinja2 rename to archive/apps/debezium/README.jinja2 diff --git a/apps/debezium/docker-compose.yml b/archive/apps/debezium/docker-compose.yml similarity index 100% rename from apps/debezium/docker-compose.yml rename to archive/apps/debezium/docker-compose.yml diff --git a/apps/dockermailserver/src/README.md b/archive/apps/debezium/src/README.md similarity index 100% rename from apps/dockermailserver/src/README.md rename to archive/apps/debezium/src/README.md diff --git a/apps/debezium/src/nginx-proxy.conf.template b/archive/apps/debezium/src/nginx-proxy.conf.template similarity index 100% rename from apps/debezium/src/nginx-proxy.conf.template rename to archive/apps/debezium/src/nginx-proxy.conf.template diff --git a/apps/debezium/src/php_exra.ini b/archive/apps/debezium/src/php_exra.ini similarity index 100% rename from apps/debezium/src/php_exra.ini rename to archive/apps/debezium/src/php_exra.ini diff --git a/apps/debezium/variables.json b/archive/apps/debezium/variables.json similarity index 100% rename from apps/debezium/variables.json rename to archive/apps/debezium/variables.json diff --git a/apps/dgraph/.env b/archive/apps/dgraph/.env similarity index 100% rename from apps/dgraph/.env rename to archive/apps/dgraph/.env diff --git a/apps/dgraph/CHANGELOG.md b/archive/apps/dgraph/CHANGELOG.md similarity index 100% rename from apps/dgraph/CHANGELOG.md rename to archive/apps/dgraph/CHANGELOG.md diff --git a/apps/dgraph/Notes.md b/archive/apps/dgraph/Notes.md similarity index 100% rename from apps/dgraph/Notes.md rename to archive/apps/dgraph/Notes.md diff --git a/apps/dgraph/README.md b/archive/apps/dgraph/README.md similarity index 100% rename from apps/dgraph/README.md rename to archive/apps/dgraph/README.md diff --git a/apps/dgraph/docker-compose.yml b/archive/apps/dgraph/docker-compose.yml similarity index 100% rename from apps/dgraph/docker-compose.yml rename to archive/apps/dgraph/docker-compose.yml diff --git a/apps/dgraph/src/filelist b/archive/apps/dgraph/src/filelist similarity index 100% rename from apps/dgraph/src/filelist rename to archive/apps/dgraph/src/filelist diff --git a/apps/dgraph/variables.json b/archive/apps/dgraph/variables.json similarity index 100% rename from apps/dgraph/variables.json rename to archive/apps/dgraph/variables.json diff --git a/apps/discourse/.env b/archive/apps/discourse/.env similarity index 100% rename from apps/discourse/.env rename to archive/apps/discourse/.env diff --git a/apps/discourse/CHANGELOG.md b/archive/apps/discourse/CHANGELOG.md similarity index 100% rename from apps/discourse/CHANGELOG.md rename to archive/apps/discourse/CHANGELOG.md diff --git a/apps/discourse/Notes.md b/archive/apps/discourse/Notes.md similarity index 100% rename from apps/discourse/Notes.md rename to archive/apps/discourse/Notes.md diff --git a/apps/discourse/README.md b/archive/apps/discourse/README.md similarity index 100% rename from apps/discourse/README.md rename to archive/apps/discourse/README.md diff --git a/apps/discourse/docker-compose.yml b/archive/apps/discourse/docker-compose.yml similarity index 100% rename from apps/discourse/docker-compose.yml rename to archive/apps/discourse/docker-compose.yml diff --git a/apps/discourse/variables.json b/archive/apps/discourse/variables.json similarity index 100% rename from apps/discourse/variables.json rename to archive/apps/discourse/variables.json diff --git a/apps/docker/.env b/archive/apps/docker/.env similarity index 100% rename from apps/docker/.env rename to archive/apps/docker/.env diff --git a/apps/docker/CHANGELOG.md b/archive/apps/docker/CHANGELOG.md similarity index 100% rename from apps/docker/CHANGELOG.md rename to archive/apps/docker/CHANGELOG.md diff --git a/apps/docker/Notes.md b/archive/apps/docker/Notes.md similarity index 100% rename from apps/docker/Notes.md rename to archive/apps/docker/Notes.md diff --git a/apps/docker/README.md b/archive/apps/docker/README.md similarity index 100% rename from apps/docker/README.md rename to archive/apps/docker/README.md diff --git a/apps/docker/docker-compose.yml b/archive/apps/docker/docker-compose.yml similarity index 100% rename from apps/docker/docker-compose.yml rename to archive/apps/docker/docker-compose.yml diff --git a/apps/docuseal/src/README.md b/archive/apps/docker/src/README.md similarity index 100% rename from apps/docuseal/src/README.md rename to archive/apps/docker/src/README.md diff --git a/apps/kodbox/Notes.md b/archive/apps/docker/src/nginx-proxy.conf similarity index 100% rename from apps/kodbox/Notes.md rename to archive/apps/docker/src/nginx-proxy.conf diff --git a/apps/docker/variables.json b/archive/apps/docker/variables.json similarity index 100% rename from apps/docker/variables.json rename to archive/apps/docker/variables.json diff --git a/apps/dockermailserver/.env b/archive/apps/dockermailserver/.env similarity index 100% rename from apps/dockermailserver/.env rename to archive/apps/dockermailserver/.env diff --git a/apps/dockermailserver/CHANGELOG.md b/archive/apps/dockermailserver/CHANGELOG.md similarity index 100% rename from apps/dockermailserver/CHANGELOG.md rename to archive/apps/dockermailserver/CHANGELOG.md diff --git a/apps/dockermailserver/Dockerfile b/archive/apps/dockermailserver/Dockerfile similarity index 100% rename from apps/dockermailserver/Dockerfile rename to archive/apps/dockermailserver/Dockerfile diff --git a/apps/debezium/Notes.md b/archive/apps/dockermailserver/Notes.md similarity index 100% rename from apps/debezium/Notes.md rename to archive/apps/dockermailserver/Notes.md diff --git a/apps/dockermailserver/README.jinja2 b/archive/apps/dockermailserver/README.jinja2 similarity index 100% rename from apps/dockermailserver/README.jinja2 rename to archive/apps/dockermailserver/README.jinja2 diff --git a/apps/dockermailserver/README.md b/archive/apps/dockermailserver/README.md similarity index 100% rename from apps/dockermailserver/README.md rename to archive/apps/dockermailserver/README.md diff --git a/apps/dockermailserver/docker-compose.yml b/archive/apps/dockermailserver/docker-compose.yml similarity index 100% rename from apps/dockermailserver/docker-compose.yml rename to archive/apps/dockermailserver/docker-compose.yml diff --git a/apps/doris/src/README.md b/archive/apps/dockermailserver/src/README.md similarity index 100% rename from apps/doris/src/README.md rename to archive/apps/dockermailserver/src/README.md diff --git a/apps/dockermailserver/src/nginx-proxy.conf.template b/archive/apps/dockermailserver/src/nginx-proxy.conf.template similarity index 100% rename from apps/dockermailserver/src/nginx-proxy.conf.template rename to archive/apps/dockermailserver/src/nginx-proxy.conf.template diff --git a/apps/dockermailserver/src/php_exra.ini b/archive/apps/dockermailserver/src/php_exra.ini similarity index 100% rename from apps/dockermailserver/src/php_exra.ini rename to archive/apps/dockermailserver/src/php_exra.ini diff --git a/apps/dockermailserver/variables.json b/archive/apps/dockermailserver/variables.json similarity index 100% rename from apps/dockermailserver/variables.json rename to archive/apps/dockermailserver/variables.json diff --git a/apps/docusaurus/.env b/archive/apps/docusaurus/.env similarity index 100% rename from apps/docusaurus/.env rename to archive/apps/docusaurus/.env diff --git a/apps/docusaurus/CHANGELOG.md b/archive/apps/docusaurus/CHANGELOG.md similarity index 100% rename from apps/docusaurus/CHANGELOG.md rename to archive/apps/docusaurus/CHANGELOG.md diff --git a/apps/docusaurus/Notes.md b/archive/apps/docusaurus/Notes.md similarity index 100% rename from apps/docusaurus/Notes.md rename to archive/apps/docusaurus/Notes.md diff --git a/apps/docusaurus/README.md b/archive/apps/docusaurus/README.md similarity index 100% rename from apps/docusaurus/README.md rename to archive/apps/docusaurus/README.md diff --git a/apps/docusaurus/docker-compose.yml b/archive/apps/docusaurus/docker-compose.yml similarity index 100% rename from apps/docusaurus/docker-compose.yml rename to archive/apps/docusaurus/docker-compose.yml diff --git a/apps/docusaurus/src/filelist b/archive/apps/docusaurus/src/filelist similarity index 100% rename from apps/docusaurus/src/filelist rename to archive/apps/docusaurus/src/filelist diff --git a/apps/docusaurus/variables.json b/archive/apps/docusaurus/variables.json similarity index 100% rename from apps/docusaurus/variables.json rename to archive/apps/docusaurus/variables.json diff --git a/apps/docuseal/.env b/archive/apps/docuseal/.env similarity index 100% rename from apps/docuseal/.env rename to archive/apps/docuseal/.env diff --git a/apps/docuseal/CHANGELOG.md b/archive/apps/docuseal/CHANGELOG.md similarity index 100% rename from apps/docuseal/CHANGELOG.md rename to archive/apps/docuseal/CHANGELOG.md diff --git a/apps/docuseal/Notes.md b/archive/apps/docuseal/Notes.md similarity index 100% rename from apps/docuseal/Notes.md rename to archive/apps/docuseal/Notes.md diff --git a/apps/docuseal/README.md b/archive/apps/docuseal/README.md similarity index 100% rename from apps/docuseal/README.md rename to archive/apps/docuseal/README.md diff --git a/apps/docuseal/docker-compose.yml b/archive/apps/docuseal/docker-compose.yml similarity index 100% rename from apps/docuseal/docker-compose.yml rename to archive/apps/docuseal/docker-compose.yml diff --git a/apps/dotnet/src/README.md b/archive/apps/docuseal/src/README.md similarity index 100% rename from apps/dotnet/src/README.md rename to archive/apps/docuseal/src/README.md diff --git a/apps/docuseal/variables.json b/archive/apps/docuseal/variables.json similarity index 100% rename from apps/docuseal/variables.json rename to archive/apps/docuseal/variables.json diff --git a/apps/doris/.env b/archive/apps/doris/.env similarity index 100% rename from apps/doris/.env rename to archive/apps/doris/.env diff --git a/apps/doris/CHANGELOG.md b/archive/apps/doris/CHANGELOG.md similarity index 100% rename from apps/doris/CHANGELOG.md rename to archive/apps/doris/CHANGELOG.md diff --git a/apps/dify/Notes.md b/archive/apps/doris/Notes.md similarity index 100% rename from apps/dify/Notes.md rename to archive/apps/doris/Notes.md diff --git a/apps/doris/docker-compose.yml b/archive/apps/doris/docker-compose.yml similarity index 100% rename from apps/doris/docker-compose.yml rename to archive/apps/doris/docker-compose.yml diff --git a/apps/drawio/src/README.md b/archive/apps/doris/src/README.md similarity index 100% rename from apps/drawio/src/README.md rename to archive/apps/doris/src/README.md diff --git a/apps/doris/variables.json b/archive/apps/doris/variables.json similarity index 100% rename from apps/doris/variables.json rename to archive/apps/doris/variables.json diff --git a/apps/dotnet/.env b/archive/apps/dotnet/.env similarity index 100% rename from apps/dotnet/.env rename to archive/apps/dotnet/.env diff --git a/apps/dotnet/CHANGELOG.md b/archive/apps/dotnet/CHANGELOG.md similarity index 100% rename from apps/dotnet/CHANGELOG.md rename to archive/apps/dotnet/CHANGELOG.md diff --git a/apps/dotnet/Notes.md b/archive/apps/dotnet/Notes.md similarity index 100% rename from apps/dotnet/Notes.md rename to archive/apps/dotnet/Notes.md diff --git a/apps/dotnet/README.md b/archive/apps/dotnet/README.md similarity index 100% rename from apps/dotnet/README.md rename to archive/apps/dotnet/README.md diff --git a/apps/dotnet/docker-compose.yml b/archive/apps/dotnet/docker-compose.yml similarity index 100% rename from apps/dotnet/docker-compose.yml rename to archive/apps/dotnet/docker-compose.yml diff --git a/apps/duplicati/src/README.md b/archive/apps/dotnet/src/README.md similarity index 100% rename from apps/duplicati/src/README.md rename to archive/apps/dotnet/src/README.md diff --git a/apps/dotnet/src/cmd.sh b/archive/apps/dotnet/src/cmd.sh similarity index 100% rename from apps/dotnet/src/cmd.sh rename to archive/apps/dotnet/src/cmd.sh diff --git a/apps/dotnet/variables.json b/archive/apps/dotnet/variables.json similarity index 100% rename from apps/dotnet/variables.json rename to archive/apps/dotnet/variables.json diff --git a/apps/drawio/.env b/archive/apps/drawio/.env similarity index 100% rename from apps/drawio/.env rename to archive/apps/drawio/.env diff --git a/apps/drawio/CHANGELOG.md b/archive/apps/drawio/CHANGELOG.md similarity index 100% rename from apps/drawio/CHANGELOG.md rename to archive/apps/drawio/CHANGELOG.md diff --git a/apps/dockermailserver/Notes.md b/archive/apps/drawio/Notes.md similarity index 100% rename from apps/dockermailserver/Notes.md rename to archive/apps/drawio/Notes.md diff --git a/apps/drawio/README.md b/archive/apps/drawio/README.md similarity index 100% rename from apps/drawio/README.md rename to archive/apps/drawio/README.md diff --git a/apps/drawio/docker-compose.yml b/archive/apps/drawio/docker-compose.yml similarity index 100% rename from apps/drawio/docker-compose.yml rename to archive/apps/drawio/docker-compose.yml diff --git a/apps/ejbca/src/README.md b/archive/apps/drawio/src/README.md similarity index 100% rename from apps/ejbca/src/README.md rename to archive/apps/drawio/src/README.md diff --git a/apps/drawio/variables.json b/archive/apps/drawio/variables.json similarity index 100% rename from apps/drawio/variables.json rename to archive/apps/drawio/variables.json diff --git a/apps/duplicati/.env b/archive/apps/duplicati/.env similarity index 100% rename from apps/duplicati/.env rename to archive/apps/duplicati/.env diff --git a/apps/duplicati/CHANGELOG.md b/archive/apps/duplicati/CHANGELOG.md similarity index 100% rename from apps/duplicati/CHANGELOG.md rename to archive/apps/duplicati/CHANGELOG.md diff --git a/apps/duplicati/Notes.md b/archive/apps/duplicati/Notes.md similarity index 100% rename from apps/duplicati/Notes.md rename to archive/apps/duplicati/Notes.md diff --git a/apps/duplicati/README.md b/archive/apps/duplicati/README.md similarity index 100% rename from apps/duplicati/README.md rename to archive/apps/duplicati/README.md diff --git a/apps/duplicati/docker-compose.yml b/archive/apps/duplicati/docker-compose.yml similarity index 100% rename from apps/duplicati/docker-compose.yml rename to archive/apps/duplicati/docker-compose.yml diff --git a/apps/emqx/src/README.md b/archive/apps/duplicati/src/README.md similarity index 100% rename from apps/emqx/src/README.md rename to archive/apps/duplicati/src/README.md diff --git a/apps/duplicati/src/nginx-proxy.conf b/archive/apps/duplicati/src/nginx-proxy.conf similarity index 100% rename from apps/duplicati/src/nginx-proxy.conf rename to archive/apps/duplicati/src/nginx-proxy.conf diff --git a/apps/duplicati/variables.json b/archive/apps/duplicati/variables.json similarity index 100% rename from apps/duplicati/variables.json rename to archive/apps/duplicati/variables.json diff --git a/apps/ejbca/.env b/archive/apps/ejbca/.env similarity index 100% rename from apps/ejbca/.env rename to archive/apps/ejbca/.env diff --git a/apps/ejbca/CHANGELOG.md b/archive/apps/ejbca/CHANGELOG.md similarity index 100% rename from apps/ejbca/CHANGELOG.md rename to archive/apps/ejbca/CHANGELOG.md diff --git a/apps/ejbca/Dockerfile b/archive/apps/ejbca/Dockerfile similarity index 100% rename from apps/ejbca/Dockerfile rename to archive/apps/ejbca/Dockerfile diff --git a/apps/doris/Notes.md b/archive/apps/ejbca/Notes.md similarity index 100% rename from apps/doris/Notes.md rename to archive/apps/ejbca/Notes.md diff --git a/apps/ejbca/README.jinja2 b/archive/apps/ejbca/README.jinja2 similarity index 100% rename from apps/ejbca/README.jinja2 rename to archive/apps/ejbca/README.jinja2 diff --git a/apps/ejbca/README.md b/archive/apps/ejbca/README.md similarity index 100% rename from apps/ejbca/README.md rename to archive/apps/ejbca/README.md diff --git a/apps/ejbca/docker-compose.yml b/archive/apps/ejbca/docker-compose.yml similarity index 100% rename from apps/ejbca/docker-compose.yml rename to archive/apps/ejbca/docker-compose.yml diff --git a/apps/filepizza/src/README.md b/archive/apps/ejbca/src/README.md similarity index 100% rename from apps/filepizza/src/README.md rename to archive/apps/ejbca/src/README.md diff --git a/apps/ejbca/src/nginx-proxy.conf.template b/archive/apps/ejbca/src/nginx-proxy.conf.template similarity index 100% rename from apps/ejbca/src/nginx-proxy.conf.template rename to archive/apps/ejbca/src/nginx-proxy.conf.template diff --git a/apps/ejbca/src/php_exra.ini b/archive/apps/ejbca/src/php_exra.ini similarity index 100% rename from apps/ejbca/src/php_exra.ini rename to archive/apps/ejbca/src/php_exra.ini diff --git a/apps/ejbca/variables.json b/archive/apps/ejbca/variables.json similarity index 100% rename from apps/ejbca/variables.json rename to archive/apps/ejbca/variables.json diff --git a/apps/emqx/.env b/archive/apps/emqx/.env similarity index 100% rename from apps/emqx/.env rename to archive/apps/emqx/.env diff --git a/apps/emqx/CHANGELOG.md b/archive/apps/emqx/CHANGELOG.md similarity index 100% rename from apps/emqx/CHANGELOG.md rename to archive/apps/emqx/CHANGELOG.md diff --git a/apps/emqx/Notes.md b/archive/apps/emqx/Notes.md similarity index 100% rename from apps/emqx/Notes.md rename to archive/apps/emqx/Notes.md diff --git a/apps/emqx/README.md b/archive/apps/emqx/README.md similarity index 100% rename from apps/emqx/README.md rename to archive/apps/emqx/README.md diff --git a/apps/emqx/docker-compose.yml b/archive/apps/emqx/docker-compose.yml similarity index 100% rename from apps/emqx/docker-compose.yml rename to archive/apps/emqx/docker-compose.yml diff --git a/apps/filerun/src/README.md b/archive/apps/emqx/src/README.md similarity index 100% rename from apps/filerun/src/README.md rename to archive/apps/emqx/src/README.md diff --git a/apps/emqx/variables.json b/archive/apps/emqx/variables.json similarity index 100% rename from apps/emqx/variables.json rename to archive/apps/emqx/variables.json diff --git a/apps/excalidraw/.env b/archive/apps/excalidraw/.env similarity index 100% rename from apps/excalidraw/.env rename to archive/apps/excalidraw/.env diff --git a/apps/excalidraw/CHANGELOG.md b/archive/apps/excalidraw/CHANGELOG.md similarity index 100% rename from apps/excalidraw/CHANGELOG.md rename to archive/apps/excalidraw/CHANGELOG.md diff --git a/apps/excalidraw/Notes.md b/archive/apps/excalidraw/Notes.md similarity index 100% rename from apps/excalidraw/Notes.md rename to archive/apps/excalidraw/Notes.md diff --git a/apps/excalidraw/README.md b/archive/apps/excalidraw/README.md similarity index 100% rename from apps/excalidraw/README.md rename to archive/apps/excalidraw/README.md diff --git a/apps/excalidraw/docker-compose.yml b/archive/apps/excalidraw/docker-compose.yml similarity index 100% rename from apps/excalidraw/docker-compose.yml rename to archive/apps/excalidraw/docker-compose.yml diff --git a/apps/excalidraw/variables.json b/archive/apps/excalidraw/variables.json similarity index 100% rename from apps/excalidraw/variables.json rename to archive/apps/excalidraw/variables.json diff --git a/apps/falcon/.env b/archive/apps/falcon/.env similarity index 100% rename from apps/falcon/.env rename to archive/apps/falcon/.env diff --git a/apps/falcon/CHANGELOG.md b/archive/apps/falcon/CHANGELOG.md similarity index 100% rename from apps/falcon/CHANGELOG.md rename to archive/apps/falcon/CHANGELOG.md diff --git a/apps/falcon/Notes.md b/archive/apps/falcon/Notes.md similarity index 100% rename from apps/falcon/Notes.md rename to archive/apps/falcon/Notes.md diff --git a/apps/falcon/README.md b/archive/apps/falcon/README.md similarity index 100% rename from apps/falcon/README.md rename to archive/apps/falcon/README.md diff --git a/apps/falcon/docker-compose.yml b/archive/apps/falcon/docker-compose.yml similarity index 100% rename from apps/falcon/docker-compose.yml rename to archive/apps/falcon/docker-compose.yml diff --git a/apps/falcon/src/docker-compose.yml b/archive/apps/falcon/src/docker-compose.yml similarity index 100% rename from apps/falcon/src/docker-compose.yml rename to archive/apps/falcon/src/docker-compose.yml diff --git a/apps/falcon/src/filelist b/archive/apps/falcon/src/filelist similarity index 100% rename from apps/falcon/src/filelist rename to archive/apps/falcon/src/filelist diff --git a/apps/falcon/src/scripts/mysql/.gitignore b/archive/apps/falcon/src/scripts/mysql/.gitignore similarity index 100% rename from apps/falcon/src/scripts/mysql/.gitignore rename to archive/apps/falcon/src/scripts/mysql/.gitignore diff --git a/apps/falcon/src/scripts/mysql/LICENSE b/archive/apps/falcon/src/scripts/mysql/LICENSE similarity index 100% rename from apps/falcon/src/scripts/mysql/LICENSE rename to archive/apps/falcon/src/scripts/mysql/LICENSE diff --git a/apps/falcon/src/scripts/mysql/NOTICE b/archive/apps/falcon/src/scripts/mysql/NOTICE similarity index 100% rename from apps/falcon/src/scripts/mysql/NOTICE rename to archive/apps/falcon/src/scripts/mysql/NOTICE diff --git a/apps/falcon/src/scripts/mysql/db_schema/1_uic-db-schema.sql b/archive/apps/falcon/src/scripts/mysql/db_schema/1_uic-db-schema.sql similarity index 100% rename from apps/falcon/src/scripts/mysql/db_schema/1_uic-db-schema.sql rename to archive/apps/falcon/src/scripts/mysql/db_schema/1_uic-db-schema.sql diff --git a/apps/falcon/src/scripts/mysql/db_schema/2_portal-db-schema.sql b/archive/apps/falcon/src/scripts/mysql/db_schema/2_portal-db-schema.sql similarity index 100% rename from apps/falcon/src/scripts/mysql/db_schema/2_portal-db-schema.sql rename to archive/apps/falcon/src/scripts/mysql/db_schema/2_portal-db-schema.sql diff --git a/apps/falcon/src/scripts/mysql/db_schema/3_dashboard-db-schema.sql b/archive/apps/falcon/src/scripts/mysql/db_schema/3_dashboard-db-schema.sql similarity index 100% rename from apps/falcon/src/scripts/mysql/db_schema/3_dashboard-db-schema.sql rename to archive/apps/falcon/src/scripts/mysql/db_schema/3_dashboard-db-schema.sql diff --git a/apps/falcon/src/scripts/mysql/db_schema/4_graph-db-schema.sql b/archive/apps/falcon/src/scripts/mysql/db_schema/4_graph-db-schema.sql similarity index 100% rename from apps/falcon/src/scripts/mysql/db_schema/4_graph-db-schema.sql rename to archive/apps/falcon/src/scripts/mysql/db_schema/4_graph-db-schema.sql diff --git a/apps/falcon/src/scripts/mysql/db_schema/5_alarms-db-schema.sql b/archive/apps/falcon/src/scripts/mysql/db_schema/5_alarms-db-schema.sql similarity index 100% rename from apps/falcon/src/scripts/mysql/db_schema/5_alarms-db-schema.sql rename to archive/apps/falcon/src/scripts/mysql/db_schema/5_alarms-db-schema.sql diff --git a/apps/falcon/variables.json b/archive/apps/falcon/variables.json similarity index 100% rename from apps/falcon/variables.json rename to archive/apps/falcon/variables.json diff --git a/apps/filepizza/.env b/archive/apps/filepizza/.env similarity index 100% rename from apps/filepizza/.env rename to archive/apps/filepizza/.env diff --git a/apps/filepizza/CHANGELOG.md b/archive/apps/filepizza/CHANGELOG.md similarity index 100% rename from apps/filepizza/CHANGELOG.md rename to archive/apps/filepizza/CHANGELOG.md diff --git a/apps/filepizza/Notes.md b/archive/apps/filepizza/Notes.md similarity index 100% rename from apps/filepizza/Notes.md rename to archive/apps/filepizza/Notes.md diff --git a/apps/filepizza/README.md b/archive/apps/filepizza/README.md similarity index 100% rename from apps/filepizza/README.md rename to archive/apps/filepizza/README.md diff --git a/apps/filepizza/docker-compose.yml b/archive/apps/filepizza/docker-compose.yml similarity index 100% rename from apps/filepizza/docker-compose.yml rename to archive/apps/filepizza/docker-compose.yml diff --git a/apps/firecrawl/src/README.md b/archive/apps/filepizza/src/README.md similarity index 100% rename from apps/firecrawl/src/README.md rename to archive/apps/filepizza/src/README.md diff --git a/apps/filepizza/variables.json b/archive/apps/filepizza/variables.json similarity index 100% rename from apps/filepizza/variables.json rename to archive/apps/filepizza/variables.json diff --git a/apps/filerun/.env b/archive/apps/filerun/.env similarity index 100% rename from apps/filerun/.env rename to archive/apps/filerun/.env diff --git a/apps/filerun/CHANGELOG.md b/archive/apps/filerun/CHANGELOG.md similarity index 100% rename from apps/filerun/CHANGELOG.md rename to archive/apps/filerun/CHANGELOG.md diff --git a/apps/drawio/Notes.md b/archive/apps/filerun/Notes.md similarity index 100% rename from apps/drawio/Notes.md rename to archive/apps/filerun/Notes.md diff --git a/apps/filerun/README.md b/archive/apps/filerun/README.md similarity index 100% rename from apps/filerun/README.md rename to archive/apps/filerun/README.md diff --git a/apps/filerun/docker-compose.yml b/archive/apps/filerun/docker-compose.yml similarity index 100% rename from apps/filerun/docker-compose.yml rename to archive/apps/filerun/docker-compose.yml diff --git a/apps/flowise/src/README.md b/archive/apps/filerun/src/README.md similarity index 100% rename from apps/flowise/src/README.md rename to archive/apps/filerun/src/README.md diff --git a/apps/filerun/variables.json b/archive/apps/filerun/variables.json similarity index 100% rename from apps/filerun/variables.json rename to archive/apps/filerun/variables.json diff --git a/apps/firecrawl/.env b/archive/apps/firecrawl/.env similarity index 100% rename from apps/firecrawl/.env rename to archive/apps/firecrawl/.env diff --git a/apps/firecrawl/CHANGELOG.md b/archive/apps/firecrawl/CHANGELOG.md similarity index 100% rename from apps/firecrawl/CHANGELOG.md rename to archive/apps/firecrawl/CHANGELOG.md diff --git a/apps/firecrawl/Notes.md b/archive/apps/firecrawl/Notes.md similarity index 100% rename from apps/firecrawl/Notes.md rename to archive/apps/firecrawl/Notes.md diff --git a/apps/firecrawl/README.md b/archive/apps/firecrawl/README.md similarity index 100% rename from apps/firecrawl/README.md rename to archive/apps/firecrawl/README.md diff --git a/apps/firecrawl/docker-compose.yml b/archive/apps/firecrawl/docker-compose.yml similarity index 100% rename from apps/firecrawl/docker-compose.yml rename to archive/apps/firecrawl/docker-compose.yml diff --git a/apps/fluentbit/src/README.md b/archive/apps/firecrawl/src/README.md similarity index 100% rename from apps/fluentbit/src/README.md rename to archive/apps/firecrawl/src/README.md diff --git a/apps/firecrawl/variables.json b/archive/apps/firecrawl/variables.json similarity index 100% rename from apps/firecrawl/variables.json rename to archive/apps/firecrawl/variables.json diff --git a/apps/flowise/.env b/archive/apps/flowise/.env similarity index 100% rename from apps/flowise/.env rename to archive/apps/flowise/.env diff --git a/apps/flowise/CHANGELOG.md b/archive/apps/flowise/CHANGELOG.md similarity index 100% rename from apps/flowise/CHANGELOG.md rename to archive/apps/flowise/CHANGELOG.md diff --git a/apps/flowise/Notes.md b/archive/apps/flowise/Notes.md similarity index 100% rename from apps/flowise/Notes.md rename to archive/apps/flowise/Notes.md diff --git a/apps/flowise/README.md b/archive/apps/flowise/README.md similarity index 100% rename from apps/flowise/README.md rename to archive/apps/flowise/README.md diff --git a/apps/flowise/docker-compose.yml b/archive/apps/flowise/docker-compose.yml similarity index 100% rename from apps/flowise/docker-compose.yml rename to archive/apps/flowise/docker-compose.yml diff --git a/apps/fluentd/src/README.md b/archive/apps/flowise/src/README.md similarity index 100% rename from apps/fluentd/src/README.md rename to archive/apps/flowise/src/README.md diff --git a/apps/flowise/variables.json b/archive/apps/flowise/variables.json similarity index 100% rename from apps/flowise/variables.json rename to archive/apps/flowise/variables.json diff --git a/apps/fluentbit/.env b/archive/apps/fluentbit/.env similarity index 100% rename from apps/fluentbit/.env rename to archive/apps/fluentbit/.env diff --git a/apps/fluentbit/CHANGELOG.md b/archive/apps/fluentbit/CHANGELOG.md similarity index 100% rename from apps/fluentbit/CHANGELOG.md rename to archive/apps/fluentbit/CHANGELOG.md diff --git a/apps/fluentbit/Notes.md b/archive/apps/fluentbit/Notes.md similarity index 100% rename from apps/fluentbit/Notes.md rename to archive/apps/fluentbit/Notes.md diff --git a/apps/fluentbit/README.md b/archive/apps/fluentbit/README.md similarity index 100% rename from apps/fluentbit/README.md rename to archive/apps/fluentbit/README.md diff --git a/apps/fluentbit/docker-compose.yml b/archive/apps/fluentbit/docker-compose.yml similarity index 100% rename from apps/fluentbit/docker-compose.yml rename to archive/apps/fluentbit/docker-compose.yml diff --git a/apps/formbricks/src/README.md b/archive/apps/fluentbit/src/README.md similarity index 100% rename from apps/formbricks/src/README.md rename to archive/apps/fluentbit/src/README.md diff --git a/apps/fluentbit/src/fluent-bit.conf b/archive/apps/fluentbit/src/fluent-bit.conf similarity index 100% rename from apps/fluentbit/src/fluent-bit.conf rename to archive/apps/fluentbit/src/fluent-bit.conf diff --git a/apps/fluentbit/variables.json b/archive/apps/fluentbit/variables.json similarity index 100% rename from apps/fluentbit/variables.json rename to archive/apps/fluentbit/variables.json diff --git a/apps/fluentd/.env b/archive/apps/fluentd/.env similarity index 100% rename from apps/fluentd/.env rename to archive/apps/fluentd/.env diff --git a/apps/fluentd/CHANGELOG.md b/archive/apps/fluentd/CHANGELOG.md similarity index 100% rename from apps/fluentd/CHANGELOG.md rename to archive/apps/fluentd/CHANGELOG.md diff --git a/apps/fluentd/Dockerfile b/archive/apps/fluentd/Dockerfile similarity index 100% rename from apps/fluentd/Dockerfile rename to archive/apps/fluentd/Dockerfile diff --git a/apps/ejbca/Notes.md b/archive/apps/fluentd/Notes.md similarity index 100% rename from apps/ejbca/Notes.md rename to archive/apps/fluentd/Notes.md diff --git a/apps/fluentd/README.jinja2 b/archive/apps/fluentd/README.jinja2 similarity index 100% rename from apps/fluentd/README.jinja2 rename to archive/apps/fluentd/README.jinja2 diff --git a/apps/fluentd/README.md b/archive/apps/fluentd/README.md similarity index 100% rename from apps/fluentd/README.md rename to archive/apps/fluentd/README.md diff --git a/apps/fluentd/docker-compose.yml b/archive/apps/fluentd/docker-compose.yml similarity index 100% rename from apps/fluentd/docker-compose.yml rename to archive/apps/fluentd/docker-compose.yml diff --git a/apps/freshrss/src/README.md b/archive/apps/fluentd/src/README.md similarity index 100% rename from apps/freshrss/src/README.md rename to archive/apps/fluentd/src/README.md diff --git a/apps/fluentd/src/nginx-proxy.conf.template b/archive/apps/fluentd/src/nginx-proxy.conf.template similarity index 100% rename from apps/fluentd/src/nginx-proxy.conf.template rename to archive/apps/fluentd/src/nginx-proxy.conf.template diff --git a/apps/fluentd/src/php_exra.ini b/archive/apps/fluentd/src/php_exra.ini similarity index 100% rename from apps/fluentd/src/php_exra.ini rename to archive/apps/fluentd/src/php_exra.ini diff --git a/apps/fluentd/variables.json b/archive/apps/fluentd/variables.json similarity index 100% rename from apps/fluentd/variables.json rename to archive/apps/fluentd/variables.json diff --git a/apps/focalboard/.env b/archive/apps/focalboard/.env similarity index 100% rename from apps/focalboard/.env rename to archive/apps/focalboard/.env diff --git a/apps/focalboard/Notes.md b/archive/apps/focalboard/Notes.md similarity index 100% rename from apps/focalboard/Notes.md rename to archive/apps/focalboard/Notes.md diff --git a/apps/focalboard/README.md b/archive/apps/focalboard/README.md similarity index 100% rename from apps/focalboard/README.md rename to archive/apps/focalboard/README.md diff --git a/apps/focalboard/docker-compose.yml b/archive/apps/focalboard/docker-compose.yml similarity index 100% rename from apps/focalboard/docker-compose.yml rename to archive/apps/focalboard/docker-compose.yml diff --git a/apps/focalboard/variables.json b/archive/apps/focalboard/variables.json similarity index 100% rename from apps/focalboard/variables.json rename to archive/apps/focalboard/variables.json diff --git a/apps/formbricks/.env b/archive/apps/formbricks/.env similarity index 100% rename from apps/formbricks/.env rename to archive/apps/formbricks/.env diff --git a/apps/formbricks/CHANGELOG.md b/archive/apps/formbricks/CHANGELOG.md similarity index 100% rename from apps/formbricks/CHANGELOG.md rename to archive/apps/formbricks/CHANGELOG.md diff --git a/apps/formbricks/Notes.md b/archive/apps/formbricks/Notes.md similarity index 100% rename from apps/formbricks/Notes.md rename to archive/apps/formbricks/Notes.md diff --git a/apps/formbricks/README.md b/archive/apps/formbricks/README.md similarity index 100% rename from apps/formbricks/README.md rename to archive/apps/formbricks/README.md diff --git a/apps/formbricks/docker-compose.yml b/archive/apps/formbricks/docker-compose.yml similarity index 100% rename from apps/formbricks/docker-compose.yml rename to archive/apps/formbricks/docker-compose.yml diff --git a/apps/frigate/src/README.md b/archive/apps/formbricks/src/README.md similarity index 100% rename from apps/frigate/src/README.md rename to archive/apps/formbricks/src/README.md diff --git a/apps/formbricks/variables.json b/archive/apps/formbricks/variables.json similarity index 100% rename from apps/formbricks/variables.json rename to archive/apps/formbricks/variables.json diff --git a/apps/frappe/.env b/archive/apps/frappe/.env similarity index 100% rename from apps/frappe/.env rename to archive/apps/frappe/.env diff --git a/apps/frappe/CHANGELOG.md b/archive/apps/frappe/CHANGELOG.md similarity index 100% rename from apps/frappe/CHANGELOG.md rename to archive/apps/frappe/CHANGELOG.md diff --git a/apps/frappe/Notes.md b/archive/apps/frappe/Notes.md similarity index 100% rename from apps/frappe/Notes.md rename to archive/apps/frappe/Notes.md diff --git a/apps/frappe/README.md b/archive/apps/frappe/README.md similarity index 100% rename from apps/frappe/README.md rename to archive/apps/frappe/README.md diff --git a/apps/frappe/docker-compose.yml b/archive/apps/frappe/docker-compose.yml similarity index 100% rename from apps/frappe/docker-compose.yml rename to archive/apps/frappe/docker-compose.yml diff --git a/apps/frappe/src/after_up.sh b/archive/apps/frappe/src/after_up.sh similarity index 100% rename from apps/frappe/src/after_up.sh rename to archive/apps/frappe/src/after_up.sh diff --git a/apps/frappe/src/compose.yaml b/archive/apps/frappe/src/compose.yaml similarity index 100% rename from apps/frappe/src/compose.yaml rename to archive/apps/frappe/src/compose.yaml diff --git a/apps/frappe/src/encrypt.sh b/archive/apps/frappe/src/encrypt.sh similarity index 100% rename from apps/frappe/src/encrypt.sh rename to archive/apps/frappe/src/encrypt.sh diff --git a/apps/frappe/src/example.env b/archive/apps/frappe/src/example.env similarity index 100% rename from apps/frappe/src/example.env rename to archive/apps/frappe/src/example.env diff --git a/apps/frappe/src/filelist b/archive/apps/frappe/src/filelist similarity index 100% rename from apps/frappe/src/filelist rename to archive/apps/frappe/src/filelist diff --git a/apps/frappe/src/get_version.sh b/archive/apps/frappe/src/get_version.sh similarity index 100% rename from apps/frappe/src/get_version.sh rename to archive/apps/frappe/src/get_version.sh diff --git a/apps/frappe/src/overrides/compose.erpnext.yaml b/archive/apps/frappe/src/overrides/compose.erpnext.yaml similarity index 100% rename from apps/frappe/src/overrides/compose.erpnext.yaml rename to archive/apps/frappe/src/overrides/compose.erpnext.yaml diff --git a/apps/frappe/src/overrides/compose.mariadb.yaml b/archive/apps/frappe/src/overrides/compose.mariadb.yaml similarity index 100% rename from apps/frappe/src/overrides/compose.mariadb.yaml rename to archive/apps/frappe/src/overrides/compose.mariadb.yaml diff --git a/apps/frappe/src/overrides/compose.noproxy.yaml b/archive/apps/frappe/src/overrides/compose.noproxy.yaml similarity index 100% rename from apps/frappe/src/overrides/compose.noproxy.yaml rename to archive/apps/frappe/src/overrides/compose.noproxy.yaml diff --git a/apps/frappe/src/overrides/compose.redis.yaml b/archive/apps/frappe/src/overrides/compose.redis.yaml similarity index 100% rename from apps/frappe/src/overrides/compose.redis.yaml rename to archive/apps/frappe/src/overrides/compose.redis.yaml diff --git a/apps/frappe/variables.json b/archive/apps/frappe/variables.json similarity index 100% rename from apps/frappe/variables.json rename to archive/apps/frappe/variables.json diff --git a/apps/freshrss/.env b/archive/apps/freshrss/.env similarity index 100% rename from apps/freshrss/.env rename to archive/apps/freshrss/.env diff --git a/apps/freshrss/CHANGELOG.md b/archive/apps/freshrss/CHANGELOG.md similarity index 100% rename from apps/freshrss/CHANGELOG.md rename to archive/apps/freshrss/CHANGELOG.md diff --git a/apps/freshrss/Notes.md b/archive/apps/freshrss/Notes.md similarity index 100% rename from apps/freshrss/Notes.md rename to archive/apps/freshrss/Notes.md diff --git a/apps/freshrss/README.md b/archive/apps/freshrss/README.md similarity index 100% rename from apps/freshrss/README.md rename to archive/apps/freshrss/README.md diff --git a/apps/freshrss/docker-compose.yml b/archive/apps/freshrss/docker-compose.yml similarity index 100% rename from apps/freshrss/docker-compose.yml rename to archive/apps/freshrss/docker-compose.yml diff --git a/apps/frp/src/README.md b/archive/apps/freshrss/src/README.md similarity index 100% rename from apps/frp/src/README.md rename to archive/apps/freshrss/src/README.md diff --git a/apps/freshrss/src/after_up.sh b/archive/apps/freshrss/src/after_up.sh similarity index 100% rename from apps/freshrss/src/after_up.sh rename to archive/apps/freshrss/src/after_up.sh diff --git a/apps/freshrss/src/encrypt.sh b/archive/apps/freshrss/src/encrypt.sh similarity index 100% rename from apps/freshrss/src/encrypt.sh rename to archive/apps/freshrss/src/encrypt.sh diff --git a/apps/freshrss/src/filelist b/archive/apps/freshrss/src/filelist similarity index 100% rename from apps/freshrss/src/filelist rename to archive/apps/freshrss/src/filelist diff --git a/apps/freshrss/src/get_version.sh b/archive/apps/freshrss/src/get_version.sh similarity index 100% rename from apps/freshrss/src/get_version.sh rename to archive/apps/freshrss/src/get_version.sh diff --git a/apps/freshrss/src/nginx-proxy.conf b/archive/apps/freshrss/src/nginx-proxy.conf similarity index 100% rename from apps/freshrss/src/nginx-proxy.conf rename to archive/apps/freshrss/src/nginx-proxy.conf diff --git a/apps/freshrss/src/php_exra.ini b/archive/apps/freshrss/src/php_exra.ini similarity index 100% rename from apps/freshrss/src/php_exra.ini rename to archive/apps/freshrss/src/php_exra.ini diff --git a/apps/freshrss/src/replace_url.sh b/archive/apps/freshrss/src/replace_url.sh similarity index 100% rename from apps/freshrss/src/replace_url.sh rename to archive/apps/freshrss/src/replace_url.sh diff --git a/apps/freshrss/variables.json b/archive/apps/freshrss/variables.json similarity index 100% rename from apps/freshrss/variables.json rename to archive/apps/freshrss/variables.json diff --git a/apps/frigate/.env b/archive/apps/frigate/.env similarity index 100% rename from apps/frigate/.env rename to archive/apps/frigate/.env diff --git a/apps/frigate/CHANGELOG.md b/archive/apps/frigate/CHANGELOG.md similarity index 100% rename from apps/frigate/CHANGELOG.md rename to archive/apps/frigate/CHANGELOG.md diff --git a/apps/frigate/Dockerfile b/archive/apps/frigate/Dockerfile similarity index 100% rename from apps/frigate/Dockerfile rename to archive/apps/frigate/Dockerfile diff --git a/apps/filerun/Notes.md b/archive/apps/frigate/Notes.md similarity index 100% rename from apps/filerun/Notes.md rename to archive/apps/frigate/Notes.md diff --git a/apps/frigate/README.jinja2 b/archive/apps/frigate/README.jinja2 similarity index 100% rename from apps/frigate/README.jinja2 rename to archive/apps/frigate/README.jinja2 diff --git a/apps/frigate/README.md b/archive/apps/frigate/README.md similarity index 100% rename from apps/frigate/README.md rename to archive/apps/frigate/README.md diff --git a/apps/frigate/docker-compose.yml b/archive/apps/frigate/docker-compose.yml similarity index 100% rename from apps/frigate/docker-compose.yml rename to archive/apps/frigate/docker-compose.yml diff --git a/apps/headscale/src/README.md b/archive/apps/frigate/src/README.md similarity index 100% rename from apps/headscale/src/README.md rename to archive/apps/frigate/src/README.md diff --git a/apps/frigate/src/nginx-proxy.conf.template b/archive/apps/frigate/src/nginx-proxy.conf.template similarity index 100% rename from apps/frigate/src/nginx-proxy.conf.template rename to archive/apps/frigate/src/nginx-proxy.conf.template diff --git a/apps/frigate/src/php_exra.ini b/archive/apps/frigate/src/php_exra.ini similarity index 100% rename from apps/frigate/src/php_exra.ini rename to archive/apps/frigate/src/php_exra.ini diff --git a/apps/frigate/variables.json b/archive/apps/frigate/variables.json similarity index 100% rename from apps/frigate/variables.json rename to archive/apps/frigate/variables.json diff --git a/apps/frp/.env b/archive/apps/frp/.env similarity index 100% rename from apps/frp/.env rename to archive/apps/frp/.env diff --git a/apps/frp/CHANGELOG.md b/archive/apps/frp/CHANGELOG.md similarity index 100% rename from apps/frp/CHANGELOG.md rename to archive/apps/frp/CHANGELOG.md diff --git a/apps/frp/Notes.md b/archive/apps/frp/Notes.md similarity index 100% rename from apps/frp/Notes.md rename to archive/apps/frp/Notes.md diff --git a/apps/frp/README.md b/archive/apps/frp/README.md similarity index 100% rename from apps/frp/README.md rename to archive/apps/frp/README.md diff --git a/apps/frp/docker-compose.yml b/archive/apps/frp/docker-compose.yml similarity index 100% rename from apps/frp/docker-compose.yml rename to archive/apps/frp/docker-compose.yml diff --git a/apps/immich/src/README.md b/archive/apps/frp/src/README.md similarity index 100% rename from apps/immich/src/README.md rename to archive/apps/frp/src/README.md diff --git a/apps/frp/src/frpc.toml b/archive/apps/frp/src/frpc.toml similarity index 100% rename from apps/frp/src/frpc.toml rename to archive/apps/frp/src/frpc.toml diff --git a/apps/frp/src/frps.toml b/archive/apps/frp/src/frps.toml similarity index 100% rename from apps/frp/src/frps.toml rename to archive/apps/frp/src/frps.toml diff --git a/apps/frp/variables.json b/archive/apps/frp/variables.json similarity index 100% rename from apps/frp/variables.json rename to archive/apps/frp/variables.json diff --git a/apps/go/.env b/archive/apps/go/.env similarity index 100% rename from apps/go/.env rename to archive/apps/go/.env diff --git a/apps/go/CHANGELOG.md b/archive/apps/go/CHANGELOG.md similarity index 100% rename from apps/go/CHANGELOG.md rename to archive/apps/go/CHANGELOG.md diff --git a/apps/go/Notes.md b/archive/apps/go/Notes.md similarity index 100% rename from apps/go/Notes.md rename to archive/apps/go/Notes.md diff --git a/apps/go/README.md b/archive/apps/go/README.md similarity index 100% rename from apps/go/README.md rename to archive/apps/go/README.md diff --git a/apps/go/docker-compose.yml b/archive/apps/go/docker-compose.yml similarity index 100% rename from apps/go/docker-compose.yml rename to archive/apps/go/docker-compose.yml diff --git a/apps/go/src/README.md b/archive/apps/go/src/README.md similarity index 100% rename from apps/go/src/README.md rename to archive/apps/go/src/README.md diff --git a/apps/go/src/cmd.sh b/archive/apps/go/src/cmd.sh similarity index 100% rename from apps/go/src/cmd.sh rename to archive/apps/go/src/cmd.sh diff --git a/apps/go/src/myapp.go b/archive/apps/go/src/myapp.go similarity index 100% rename from apps/go/src/myapp.go rename to archive/apps/go/src/myapp.go diff --git a/apps/go/variables.json b/archive/apps/go/variables.json similarity index 100% rename from apps/go/variables.json rename to archive/apps/go/variables.json diff --git a/apps/headscale/.env b/archive/apps/headscale/.env similarity index 100% rename from apps/headscale/.env rename to archive/apps/headscale/.env diff --git a/apps/headscale/CHANGELOG.md b/archive/apps/headscale/CHANGELOG.md similarity index 100% rename from apps/headscale/CHANGELOG.md rename to archive/apps/headscale/CHANGELOG.md diff --git a/apps/fluentd/Notes.md b/archive/apps/headscale/Notes.md similarity index 100% rename from apps/fluentd/Notes.md rename to archive/apps/headscale/Notes.md diff --git a/apps/headscale/README.md b/archive/apps/headscale/README.md similarity index 100% rename from apps/headscale/README.md rename to archive/apps/headscale/README.md diff --git a/apps/headscale/docker-compose.yml b/archive/apps/headscale/docker-compose.yml similarity index 100% rename from apps/headscale/docker-compose.yml rename to archive/apps/headscale/docker-compose.yml diff --git a/apps/k0s/src/README.md b/archive/apps/headscale/src/README.md similarity index 100% rename from apps/k0s/src/README.md rename to archive/apps/headscale/src/README.md diff --git a/apps/headscale/variables.json b/archive/apps/headscale/variables.json similarity index 100% rename from apps/headscale/variables.json rename to archive/apps/headscale/variables.json diff --git a/apps/immich/.env b/archive/apps/immich/.env similarity index 100% rename from apps/immich/.env rename to archive/apps/immich/.env diff --git a/apps/immich/CHANGELOG.md b/archive/apps/immich/CHANGELOG.md similarity index 100% rename from apps/immich/CHANGELOG.md rename to archive/apps/immich/CHANGELOG.md diff --git a/apps/immich/Notes.md b/archive/apps/immich/Notes.md similarity index 100% rename from apps/immich/Notes.md rename to archive/apps/immich/Notes.md diff --git a/apps/immich/README.md b/archive/apps/immich/README.md similarity index 100% rename from apps/immich/README.md rename to archive/apps/immich/README.md diff --git a/apps/immich/docker-compose.yml b/archive/apps/immich/docker-compose.yml similarity index 100% rename from apps/immich/docker-compose.yml rename to archive/apps/immich/docker-compose.yml diff --git a/apps/kavita/src/README.md b/archive/apps/immich/src/README.md similarity index 100% rename from apps/kavita/src/README.md rename to archive/apps/immich/src/README.md diff --git a/apps/immich/variables.json b/archive/apps/immich/variables.json similarity index 100% rename from apps/immich/variables.json rename to archive/apps/immich/variables.json diff --git a/apps/k0s/.env b/archive/apps/k0s/.env similarity index 100% rename from apps/k0s/.env rename to archive/apps/k0s/.env diff --git a/apps/k0s/CHANGELOG.md b/archive/apps/k0s/CHANGELOG.md similarity index 100% rename from apps/k0s/CHANGELOG.md rename to archive/apps/k0s/CHANGELOG.md diff --git a/apps/k0s/Dockerfile b/archive/apps/k0s/Dockerfile similarity index 100% rename from apps/k0s/Dockerfile rename to archive/apps/k0s/Dockerfile diff --git a/apps/frigate/Notes.md b/archive/apps/k0s/Notes.md similarity index 100% rename from apps/frigate/Notes.md rename to archive/apps/k0s/Notes.md diff --git a/apps/k0s/README.jinja2 b/archive/apps/k0s/README.jinja2 similarity index 100% rename from apps/k0s/README.jinja2 rename to archive/apps/k0s/README.jinja2 diff --git a/apps/k0s/README.md b/archive/apps/k0s/README.md similarity index 100% rename from apps/k0s/README.md rename to archive/apps/k0s/README.md diff --git a/apps/k0s/docker-compose.yml b/archive/apps/k0s/docker-compose.yml similarity index 100% rename from apps/k0s/docker-compose.yml rename to archive/apps/k0s/docker-compose.yml diff --git a/apps/keep/src/README.md b/archive/apps/k0s/src/README.md similarity index 100% rename from apps/keep/src/README.md rename to archive/apps/k0s/src/README.md diff --git a/apps/k0s/src/nginx-proxy.conf.template b/archive/apps/k0s/src/nginx-proxy.conf.template similarity index 100% rename from apps/k0s/src/nginx-proxy.conf.template rename to archive/apps/k0s/src/nginx-proxy.conf.template diff --git a/apps/k0s/src/php_exra.ini b/archive/apps/k0s/src/php_exra.ini similarity index 100% rename from apps/k0s/src/php_exra.ini rename to archive/apps/k0s/src/php_exra.ini diff --git a/apps/k0s/variables.json b/archive/apps/k0s/variables.json similarity index 100% rename from apps/k0s/variables.json rename to archive/apps/k0s/variables.json diff --git a/apps/kasmweb/.env b/archive/apps/kasmweb/.env similarity index 100% rename from apps/kasmweb/.env rename to archive/apps/kasmweb/.env diff --git a/apps/kasmweb/CHANGELOG.md b/archive/apps/kasmweb/CHANGELOG.md similarity index 100% rename from apps/kasmweb/CHANGELOG.md rename to archive/apps/kasmweb/CHANGELOG.md diff --git a/apps/kasmweb/Notes.md b/archive/apps/kasmweb/Notes.md similarity index 100% rename from apps/kasmweb/Notes.md rename to archive/apps/kasmweb/Notes.md diff --git a/apps/kasmweb/README.md b/archive/apps/kasmweb/README.md similarity index 100% rename from apps/kasmweb/README.md rename to archive/apps/kasmweb/README.md diff --git a/apps/kasmweb/docker-compose.yml b/archive/apps/kasmweb/docker-compose.yml similarity index 100% rename from apps/kasmweb/docker-compose.yml rename to archive/apps/kasmweb/docker-compose.yml diff --git a/apps/kodbox/src/filelist b/archive/apps/kasmweb/src/filelist similarity index 100% rename from apps/kodbox/src/filelist rename to archive/apps/kasmweb/src/filelist diff --git a/apps/kasmweb/variables.json b/archive/apps/kasmweb/variables.json similarity index 100% rename from apps/kasmweb/variables.json rename to archive/apps/kasmweb/variables.json diff --git a/apps/kavita/.env b/archive/apps/kavita/.env similarity index 100% rename from apps/kavita/.env rename to archive/apps/kavita/.env diff --git a/apps/kavita/CHANGELOG.md b/archive/apps/kavita/CHANGELOG.md similarity index 100% rename from apps/kavita/CHANGELOG.md rename to archive/apps/kavita/CHANGELOG.md diff --git a/apps/kavita/Notes.md b/archive/apps/kavita/Notes.md similarity index 100% rename from apps/kavita/Notes.md rename to archive/apps/kavita/Notes.md diff --git a/apps/kavita/README.md b/archive/apps/kavita/README.md similarity index 100% rename from apps/kavita/README.md rename to archive/apps/kavita/README.md diff --git a/apps/kavita/docker-compose.yml b/archive/apps/kavita/docker-compose.yml similarity index 100% rename from apps/kavita/docker-compose.yml rename to archive/apps/kavita/docker-compose.yml diff --git a/apps/keila/src/README.md b/archive/apps/kavita/src/README.md similarity index 100% rename from apps/keila/src/README.md rename to archive/apps/kavita/src/README.md diff --git a/apps/kavita/variables.json b/archive/apps/kavita/variables.json similarity index 100% rename from apps/kavita/variables.json rename to archive/apps/kavita/variables.json diff --git a/apps/keep/.env b/archive/apps/keep/.env similarity index 100% rename from apps/keep/.env rename to archive/apps/keep/.env diff --git a/apps/keep/CHANGELOG.md b/archive/apps/keep/CHANGELOG.md similarity index 100% rename from apps/keep/CHANGELOG.md rename to archive/apps/keep/CHANGELOG.md diff --git a/apps/keep/Dockerfile b/archive/apps/keep/Dockerfile similarity index 100% rename from apps/keep/Dockerfile rename to archive/apps/keep/Dockerfile diff --git a/apps/headscale/Notes.md b/archive/apps/keep/Notes.md similarity index 100% rename from apps/headscale/Notes.md rename to archive/apps/keep/Notes.md diff --git a/apps/keep/README.jinja2 b/archive/apps/keep/README.jinja2 similarity index 100% rename from apps/keep/README.jinja2 rename to archive/apps/keep/README.jinja2 diff --git a/apps/keep/README.md b/archive/apps/keep/README.md similarity index 100% rename from apps/keep/README.md rename to archive/apps/keep/README.md diff --git a/apps/keep/docker-compose.yml b/archive/apps/keep/docker-compose.yml similarity index 100% rename from apps/keep/docker-compose.yml rename to archive/apps/keep/docker-compose.yml diff --git a/apps/kener/src/README.md b/archive/apps/keep/src/README.md similarity index 100% rename from apps/kener/src/README.md rename to archive/apps/keep/src/README.md diff --git a/apps/keep/src/nginx-proxy.conf.template b/archive/apps/keep/src/nginx-proxy.conf.template similarity index 100% rename from apps/keep/src/nginx-proxy.conf.template rename to archive/apps/keep/src/nginx-proxy.conf.template diff --git a/apps/keep/src/php_exra.ini b/archive/apps/keep/src/php_exra.ini similarity index 100% rename from apps/keep/src/php_exra.ini rename to archive/apps/keep/src/php_exra.ini diff --git a/apps/keep/variables.json b/archive/apps/keep/variables.json similarity index 100% rename from apps/keep/variables.json rename to archive/apps/keep/variables.json diff --git a/apps/keila/.env b/archive/apps/keila/.env similarity index 100% rename from apps/keila/.env rename to archive/apps/keila/.env diff --git a/apps/keila/CHANGELOG.md b/archive/apps/keila/CHANGELOG.md similarity index 100% rename from apps/keila/CHANGELOG.md rename to archive/apps/keila/CHANGELOG.md diff --git a/apps/keila/Notes.md b/archive/apps/keila/Notes.md similarity index 100% rename from apps/keila/Notes.md rename to archive/apps/keila/Notes.md diff --git a/apps/keila/README.md b/archive/apps/keila/README.md similarity index 100% rename from apps/keila/README.md rename to archive/apps/keila/README.md diff --git a/apps/keila/docker-compose.yml b/archive/apps/keila/docker-compose.yml similarity index 100% rename from apps/keila/docker-compose.yml rename to archive/apps/keila/docker-compose.yml diff --git a/apps/keploy/src/README.md b/archive/apps/keila/src/README.md similarity index 100% rename from apps/keploy/src/README.md rename to archive/apps/keila/src/README.md diff --git a/apps/keila/variables.json b/archive/apps/keila/variables.json similarity index 100% rename from apps/keila/variables.json rename to archive/apps/keila/variables.json diff --git a/apps/kener/.env b/archive/apps/kener/.env similarity index 100% rename from apps/kener/.env rename to archive/apps/kener/.env diff --git a/apps/kener/CHANGELOG.md b/archive/apps/kener/CHANGELOG.md similarity index 100% rename from apps/kener/CHANGELOG.md rename to archive/apps/kener/CHANGELOG.md diff --git a/apps/kener/Notes.md b/archive/apps/kener/Notes.md similarity index 100% rename from apps/kener/Notes.md rename to archive/apps/kener/Notes.md diff --git a/apps/kener/README.md b/archive/apps/kener/README.md similarity index 100% rename from apps/kener/README.md rename to archive/apps/kener/README.md diff --git a/apps/kener/docker-compose.yml b/archive/apps/kener/docker-compose.yml similarity index 100% rename from apps/kener/docker-compose.yml rename to archive/apps/kener/docker-compose.yml diff --git a/apps/kestra/src/README.md b/archive/apps/kener/src/README.md similarity index 100% rename from apps/kestra/src/README.md rename to archive/apps/kener/src/README.md diff --git a/apps/kener/src/nginx-proxy.conf.template b/archive/apps/kener/src/nginx-proxy.conf.template similarity index 100% rename from apps/kener/src/nginx-proxy.conf.template rename to archive/apps/kener/src/nginx-proxy.conf.template diff --git a/apps/kener/src/php_exra.ini b/archive/apps/kener/src/php_exra.ini similarity index 100% rename from apps/kener/src/php_exra.ini rename to archive/apps/kener/src/php_exra.ini diff --git a/apps/kener/variables.json b/archive/apps/kener/variables.json similarity index 100% rename from apps/kener/variables.json rename to archive/apps/kener/variables.json diff --git a/apps/keploy/.env b/archive/apps/keploy/.env similarity index 100% rename from apps/keploy/.env rename to archive/apps/keploy/.env diff --git a/apps/keploy/CHANGELOG.md b/archive/apps/keploy/CHANGELOG.md similarity index 100% rename from apps/keploy/CHANGELOG.md rename to archive/apps/keploy/CHANGELOG.md diff --git a/apps/k0s/Notes.md b/archive/apps/keploy/Notes.md similarity index 100% rename from apps/k0s/Notes.md rename to archive/apps/keploy/Notes.md diff --git a/apps/keploy/README.md b/archive/apps/keploy/README.md similarity index 100% rename from apps/keploy/README.md rename to archive/apps/keploy/README.md diff --git a/apps/keploy/docker-compose.yml b/archive/apps/keploy/docker-compose.yml similarity index 100% rename from apps/keploy/docker-compose.yml rename to archive/apps/keploy/docker-compose.yml diff --git a/apps/khoj/src/README.md b/archive/apps/keploy/src/README.md similarity index 100% rename from apps/khoj/src/README.md rename to archive/apps/keploy/src/README.md diff --git a/apps/keploy/variables.json b/archive/apps/keploy/variables.json similarity index 100% rename from apps/keploy/variables.json rename to archive/apps/keploy/variables.json diff --git a/apps/kestra/.env b/archive/apps/kestra/.env similarity index 100% rename from apps/kestra/.env rename to archive/apps/kestra/.env diff --git a/apps/kestra/CHANGELOG.md b/archive/apps/kestra/CHANGELOG.md similarity index 100% rename from apps/kestra/CHANGELOG.md rename to archive/apps/kestra/CHANGELOG.md diff --git a/apps/keep/Notes.md b/archive/apps/kestra/Notes.md similarity index 100% rename from apps/keep/Notes.md rename to archive/apps/kestra/Notes.md diff --git a/apps/kestra/README.md b/archive/apps/kestra/README.md similarity index 100% rename from apps/kestra/README.md rename to archive/apps/kestra/README.md diff --git a/apps/kestra/docker-compose.yml b/archive/apps/kestra/docker-compose.yml similarity index 100% rename from apps/kestra/docker-compose.yml rename to archive/apps/kestra/docker-compose.yml diff --git a/apps/killbill/src/README.md b/archive/apps/kestra/src/README.md similarity index 100% rename from apps/killbill/src/README.md rename to archive/apps/kestra/src/README.md diff --git a/apps/kestra/variables.json b/archive/apps/kestra/variables.json similarity index 100% rename from apps/kestra/variables.json rename to archive/apps/kestra/variables.json diff --git a/apps/khoj/.env b/archive/apps/khoj/.env similarity index 100% rename from apps/khoj/.env rename to archive/apps/khoj/.env diff --git a/apps/khoj/CHANGELOG.md b/archive/apps/khoj/CHANGELOG.md similarity index 100% rename from apps/khoj/CHANGELOG.md rename to archive/apps/khoj/CHANGELOG.md diff --git a/apps/khoj/Dockerfile b/archive/apps/khoj/Dockerfile similarity index 100% rename from apps/khoj/Dockerfile rename to archive/apps/khoj/Dockerfile diff --git a/apps/keploy/Notes.md b/archive/apps/khoj/Notes.md similarity index 100% rename from apps/keploy/Notes.md rename to archive/apps/khoj/Notes.md diff --git a/apps/khoj/README.jinja2 b/archive/apps/khoj/README.jinja2 similarity index 100% rename from apps/khoj/README.jinja2 rename to archive/apps/khoj/README.jinja2 diff --git a/apps/khoj/README.md b/archive/apps/khoj/README.md similarity index 100% rename from apps/khoj/README.md rename to archive/apps/khoj/README.md diff --git a/apps/khoj/docker-compose.yml b/archive/apps/khoj/docker-compose.yml similarity index 100% rename from apps/khoj/docker-compose.yml rename to archive/apps/khoj/docker-compose.yml diff --git a/apps/knowage/src/README.md b/archive/apps/khoj/src/README.md similarity index 100% rename from apps/knowage/src/README.md rename to archive/apps/khoj/src/README.md diff --git a/apps/khoj/src/after_up.sh b/archive/apps/khoj/src/after_up.sh similarity index 100% rename from apps/khoj/src/after_up.sh rename to archive/apps/khoj/src/after_up.sh diff --git a/apps/khoj/src/encrypt.sh b/archive/apps/khoj/src/encrypt.sh similarity index 100% rename from apps/khoj/src/encrypt.sh rename to archive/apps/khoj/src/encrypt.sh diff --git a/apps/khoj/src/filelist b/archive/apps/khoj/src/filelist similarity index 100% rename from apps/khoj/src/filelist rename to archive/apps/khoj/src/filelist diff --git a/apps/khoj/src/get_version.sh b/archive/apps/khoj/src/get_version.sh similarity index 100% rename from apps/khoj/src/get_version.sh rename to archive/apps/khoj/src/get_version.sh diff --git a/apps/khoj/src/nginx-proxy.conf.template b/archive/apps/khoj/src/nginx-proxy.conf.template similarity index 100% rename from apps/khoj/src/nginx-proxy.conf.template rename to archive/apps/khoj/src/nginx-proxy.conf.template diff --git a/apps/khoj/src/php_exra.ini b/archive/apps/khoj/src/php_exra.ini similarity index 100% rename from apps/khoj/src/php_exra.ini rename to archive/apps/khoj/src/php_exra.ini diff --git a/apps/khoj/src/replace_url.sh b/archive/apps/khoj/src/replace_url.sh similarity index 100% rename from apps/khoj/src/replace_url.sh rename to archive/apps/khoj/src/replace_url.sh diff --git a/apps/khoj/variables.json b/archive/apps/khoj/variables.json similarity index 100% rename from apps/khoj/variables.json rename to archive/apps/khoj/variables.json diff --git a/apps/killbill/.env b/archive/apps/killbill/.env similarity index 100% rename from apps/killbill/.env rename to archive/apps/killbill/.env diff --git a/apps/killbill/CHANGELOG.md b/archive/apps/killbill/CHANGELOG.md similarity index 100% rename from apps/killbill/CHANGELOG.md rename to archive/apps/killbill/CHANGELOG.md diff --git a/apps/kestra/Notes.md b/archive/apps/killbill/Notes.md similarity index 100% rename from apps/kestra/Notes.md rename to archive/apps/killbill/Notes.md diff --git a/apps/killbill/README.md b/archive/apps/killbill/README.md similarity index 100% rename from apps/killbill/README.md rename to archive/apps/killbill/README.md diff --git a/apps/killbill/docker-compose.yml b/archive/apps/killbill/docker-compose.yml similarity index 100% rename from apps/killbill/docker-compose.yml rename to archive/apps/killbill/docker-compose.yml diff --git a/apps/koishi/src/README.md b/archive/apps/killbill/src/README.md similarity index 100% rename from apps/koishi/src/README.md rename to archive/apps/killbill/src/README.md diff --git a/apps/killbill/variables.json b/archive/apps/killbill/variables.json similarity index 100% rename from apps/killbill/variables.json rename to archive/apps/killbill/variables.json diff --git a/apps/knowage/.env b/archive/apps/knowage/.env similarity index 100% rename from apps/knowage/.env rename to archive/apps/knowage/.env diff --git a/apps/knowage/CHANGELOG.md b/archive/apps/knowage/CHANGELOG.md similarity index 100% rename from apps/knowage/CHANGELOG.md rename to archive/apps/knowage/CHANGELOG.md diff --git a/apps/knowage/Notes.md b/archive/apps/knowage/Notes.md similarity index 100% rename from apps/knowage/Notes.md rename to archive/apps/knowage/Notes.md diff --git a/apps/knowage/README.md b/archive/apps/knowage/README.md similarity index 100% rename from apps/knowage/README.md rename to archive/apps/knowage/README.md diff --git a/apps/knowage/docker-compose.yml b/archive/apps/knowage/docker-compose.yml similarity index 100% rename from apps/knowage/docker-compose.yml rename to archive/apps/knowage/docker-compose.yml diff --git a/apps/komga/src/README.md b/archive/apps/knowage/src/README.md similarity index 100% rename from apps/komga/src/README.md rename to archive/apps/knowage/src/README.md diff --git a/apps/knowage/src/hazelcast-server.xml b/archive/apps/knowage/src/hazelcast-server.xml similarity index 100% rename from apps/knowage/src/hazelcast-server.xml rename to archive/apps/knowage/src/hazelcast-server.xml diff --git a/apps/knowage/variables.json b/archive/apps/knowage/variables.json similarity index 100% rename from apps/knowage/variables.json rename to archive/apps/knowage/variables.json diff --git a/apps/kodbox/.env b/archive/apps/kodbox/.env similarity index 100% rename from apps/kodbox/.env rename to archive/apps/kodbox/.env diff --git a/apps/kodbox/CHANGELOG.md b/archive/apps/kodbox/CHANGELOG.md similarity index 100% rename from apps/kodbox/CHANGELOG.md rename to archive/apps/kodbox/CHANGELOG.md diff --git a/apps/kodbox/src/get_version.sh b/archive/apps/kodbox/Notes.md similarity index 100% rename from apps/kodbox/src/get_version.sh rename to archive/apps/kodbox/Notes.md diff --git a/apps/kodbox/README.md b/archive/apps/kodbox/README.md similarity index 100% rename from apps/kodbox/README.md rename to archive/apps/kodbox/README.md diff --git a/apps/kodbox/docker-compose.yml b/archive/apps/kodbox/docker-compose.yml similarity index 100% rename from apps/kodbox/docker-compose.yml rename to archive/apps/kodbox/docker-compose.yml diff --git a/apps/kodbox/src/after_up.sh b/archive/apps/kodbox/src/after_up.sh similarity index 100% rename from apps/kodbox/src/after_up.sh rename to archive/apps/kodbox/src/after_up.sh diff --git a/apps/kopia/src/get_version.sh b/archive/apps/kodbox/src/filelist similarity index 100% rename from apps/kopia/src/get_version.sh rename to archive/apps/kodbox/src/filelist diff --git a/archive/apps/kodbox/src/get_version.sh b/archive/apps/kodbox/src/get_version.sh new file mode 100644 index 000000000..e69de29bb diff --git a/apps/kodbox/variables.json b/archive/apps/kodbox/variables.json similarity index 100% rename from apps/kodbox/variables.json rename to archive/apps/kodbox/variables.json diff --git a/apps/koishi/.env b/archive/apps/koishi/.env similarity index 100% rename from apps/koishi/.env rename to archive/apps/koishi/.env diff --git a/apps/koishi/CHANGELOG.md b/archive/apps/koishi/CHANGELOG.md similarity index 100% rename from apps/koishi/CHANGELOG.md rename to archive/apps/koishi/CHANGELOG.md diff --git a/apps/koishi/Notes.md b/archive/apps/koishi/Notes.md similarity index 100% rename from apps/koishi/Notes.md rename to archive/apps/koishi/Notes.md diff --git a/apps/koishi/README.md b/archive/apps/koishi/README.md similarity index 100% rename from apps/koishi/README.md rename to archive/apps/koishi/README.md diff --git a/apps/koishi/docker-compose.yml b/archive/apps/koishi/docker-compose.yml similarity index 100% rename from apps/koishi/docker-compose.yml rename to archive/apps/koishi/docker-compose.yml diff --git a/apps/lago/src/README.md b/archive/apps/koishi/src/README.md similarity index 100% rename from apps/lago/src/README.md rename to archive/apps/koishi/src/README.md diff --git a/apps/koishi/variables.json b/archive/apps/koishi/variables.json similarity index 100% rename from apps/koishi/variables.json rename to archive/apps/koishi/variables.json diff --git a/apps/komga/.env b/archive/apps/komga/.env similarity index 100% rename from apps/komga/.env rename to archive/apps/komga/.env diff --git a/apps/komga/CHANGELOG.md b/archive/apps/komga/CHANGELOG.md similarity index 100% rename from apps/komga/CHANGELOG.md rename to archive/apps/komga/CHANGELOG.md diff --git a/apps/khoj/Notes.md b/archive/apps/komga/Notes.md similarity index 100% rename from apps/khoj/Notes.md rename to archive/apps/komga/Notes.md diff --git a/apps/komga/README.md b/archive/apps/komga/README.md similarity index 100% rename from apps/komga/README.md rename to archive/apps/komga/README.md diff --git a/apps/komga/docker-compose.yml b/archive/apps/komga/docker-compose.yml similarity index 100% rename from apps/komga/docker-compose.yml rename to archive/apps/komga/docker-compose.yml diff --git a/apps/langflow/src/README.md b/archive/apps/komga/src/README.md similarity index 100% rename from apps/langflow/src/README.md rename to archive/apps/komga/src/README.md diff --git a/apps/komga/variables.json b/archive/apps/komga/variables.json similarity index 100% rename from apps/komga/variables.json rename to archive/apps/komga/variables.json diff --git a/apps/kopia/.env b/archive/apps/kopia/.env similarity index 100% rename from apps/kopia/.env rename to archive/apps/kopia/.env diff --git a/apps/kopia/CHANGELOG.md b/archive/apps/kopia/CHANGELOG.md similarity index 100% rename from apps/kopia/CHANGELOG.md rename to archive/apps/kopia/CHANGELOG.md diff --git a/apps/kopia/Notes.md b/archive/apps/kopia/Notes.md similarity index 100% rename from apps/kopia/Notes.md rename to archive/apps/kopia/Notes.md diff --git a/apps/kopia/README.md b/archive/apps/kopia/README.md similarity index 100% rename from apps/kopia/README.md rename to archive/apps/kopia/README.md diff --git a/apps/kopia/docker-compose.yml b/archive/apps/kopia/docker-compose.yml similarity index 100% rename from apps/kopia/docker-compose.yml rename to archive/apps/kopia/docker-compose.yml diff --git a/apps/kopia/image.png b/archive/apps/kopia/image.png similarity index 100% rename from apps/kopia/image.png rename to archive/apps/kopia/image.png diff --git a/apps/kopia/src/after_up.sh b/archive/apps/kopia/src/after_up.sh similarity index 100% rename from apps/kopia/src/after_up.sh rename to archive/apps/kopia/src/after_up.sh diff --git a/apps/kopia/src/filelist b/archive/apps/kopia/src/filelist similarity index 100% rename from apps/kopia/src/filelist rename to archive/apps/kopia/src/filelist diff --git a/archive/apps/kopia/src/get_version.sh b/archive/apps/kopia/src/get_version.sh new file mode 100644 index 000000000..e69de29bb diff --git a/apps/kopia/variables.json b/archive/apps/kopia/variables.json similarity index 100% rename from apps/kopia/variables.json rename to archive/apps/kopia/variables.json diff --git a/apps/lago/.env b/archive/apps/lago/.env similarity index 100% rename from apps/lago/.env rename to archive/apps/lago/.env diff --git a/apps/lago/CHANGELOG.md b/archive/apps/lago/CHANGELOG.md similarity index 100% rename from apps/lago/CHANGELOG.md rename to archive/apps/lago/CHANGELOG.md diff --git a/apps/lago/Dockerfile b/archive/apps/lago/Dockerfile similarity index 100% rename from apps/lago/Dockerfile rename to archive/apps/lago/Dockerfile diff --git a/apps/killbill/Notes.md b/archive/apps/lago/Notes.md similarity index 100% rename from apps/killbill/Notes.md rename to archive/apps/lago/Notes.md diff --git a/apps/lago/README.jinja2 b/archive/apps/lago/README.jinja2 similarity index 100% rename from apps/lago/README.jinja2 rename to archive/apps/lago/README.jinja2 diff --git a/apps/lago/README.md b/archive/apps/lago/README.md similarity index 100% rename from apps/lago/README.md rename to archive/apps/lago/README.md diff --git a/apps/lago/docker-compose.yml b/archive/apps/lago/docker-compose.yml similarity index 100% rename from apps/lago/docker-compose.yml rename to archive/apps/lago/docker-compose.yml diff --git a/apps/langfuse/src/README.md b/archive/apps/lago/src/README.md similarity index 100% rename from apps/langfuse/src/README.md rename to archive/apps/lago/src/README.md diff --git a/apps/lago/src/after_up.sh b/archive/apps/lago/src/after_up.sh similarity index 100% rename from apps/lago/src/after_up.sh rename to archive/apps/lago/src/after_up.sh diff --git a/apps/lago/src/encrypt.sh b/archive/apps/lago/src/encrypt.sh similarity index 100% rename from apps/lago/src/encrypt.sh rename to archive/apps/lago/src/encrypt.sh diff --git a/apps/lago/src/filelist b/archive/apps/lago/src/filelist similarity index 100% rename from apps/lago/src/filelist rename to archive/apps/lago/src/filelist diff --git a/apps/lago/src/get_version.sh b/archive/apps/lago/src/get_version.sh similarity index 100% rename from apps/lago/src/get_version.sh rename to archive/apps/lago/src/get_version.sh diff --git a/apps/lago/src/nginx-proxy.conf.template b/archive/apps/lago/src/nginx-proxy.conf.template similarity index 100% rename from apps/lago/src/nginx-proxy.conf.template rename to archive/apps/lago/src/nginx-proxy.conf.template diff --git a/apps/lago/src/php_exra.ini b/archive/apps/lago/src/php_exra.ini similarity index 100% rename from apps/lago/src/php_exra.ini rename to archive/apps/lago/src/php_exra.ini diff --git a/apps/lago/src/replace_url.sh b/archive/apps/lago/src/replace_url.sh similarity index 100% rename from apps/lago/src/replace_url.sh rename to archive/apps/lago/src/replace_url.sh diff --git a/apps/lago/variables.json b/archive/apps/lago/variables.json similarity index 100% rename from apps/lago/variables.json rename to archive/apps/lago/variables.json diff --git a/apps/langflow/.env b/archive/apps/langflow/.env similarity index 100% rename from apps/langflow/.env rename to archive/apps/langflow/.env diff --git a/apps/langflow/CHANGELOG.md b/archive/apps/langflow/CHANGELOG.md similarity index 100% rename from apps/langflow/CHANGELOG.md rename to archive/apps/langflow/CHANGELOG.md diff --git a/apps/langflow/Notes.md b/archive/apps/langflow/Notes.md similarity index 100% rename from apps/langflow/Notes.md rename to archive/apps/langflow/Notes.md diff --git a/apps/langflow/README.md b/archive/apps/langflow/README.md similarity index 100% rename from apps/langflow/README.md rename to archive/apps/langflow/README.md diff --git a/apps/langflow/docker-compose.yml b/archive/apps/langflow/docker-compose.yml similarity index 100% rename from apps/langflow/docker-compose.yml rename to archive/apps/langflow/docker-compose.yml diff --git a/apps/lemmy/src/README.md b/archive/apps/langflow/src/README.md similarity index 100% rename from apps/lemmy/src/README.md rename to archive/apps/langflow/src/README.md diff --git a/apps/langflow/variables.json b/archive/apps/langflow/variables.json similarity index 100% rename from apps/langflow/variables.json rename to archive/apps/langflow/variables.json diff --git a/apps/langfuse/.env b/archive/apps/langfuse/.env similarity index 100% rename from apps/langfuse/.env rename to archive/apps/langfuse/.env diff --git a/apps/langfuse/CHANGELOG.md b/archive/apps/langfuse/CHANGELOG.md similarity index 100% rename from apps/langfuse/CHANGELOG.md rename to archive/apps/langfuse/CHANGELOG.md diff --git a/apps/komga/Notes.md b/archive/apps/langfuse/Notes.md similarity index 100% rename from apps/komga/Notes.md rename to archive/apps/langfuse/Notes.md diff --git a/apps/langfuse/docker-compose.yml b/archive/apps/langfuse/docker-compose.yml similarity index 100% rename from apps/langfuse/docker-compose.yml rename to archive/apps/langfuse/docker-compose.yml diff --git a/apps/linkwarden/src/README.md b/archive/apps/langfuse/src/README.md similarity index 100% rename from apps/linkwarden/src/README.md rename to archive/apps/langfuse/src/README.md diff --git a/apps/langfuse/variables.json b/archive/apps/langfuse/variables.json similarity index 100% rename from apps/langfuse/variables.json rename to archive/apps/langfuse/variables.json diff --git a/apps/lemmy/.env b/archive/apps/lemmy/.env similarity index 100% rename from apps/lemmy/.env rename to archive/apps/lemmy/.env diff --git a/apps/lemmy/CHANGELOG.md b/archive/apps/lemmy/CHANGELOG.md similarity index 100% rename from apps/lemmy/CHANGELOG.md rename to archive/apps/lemmy/CHANGELOG.md diff --git a/apps/lemmy/Notes.md b/archive/apps/lemmy/Notes.md similarity index 100% rename from apps/lemmy/Notes.md rename to archive/apps/lemmy/Notes.md diff --git a/apps/lemmy/README.md b/archive/apps/lemmy/README.md similarity index 100% rename from apps/lemmy/README.md rename to archive/apps/lemmy/README.md diff --git a/apps/lemmy/docker-compose.yml b/archive/apps/lemmy/docker-compose.yml similarity index 100% rename from apps/lemmy/docker-compose.yml rename to archive/apps/lemmy/docker-compose.yml diff --git a/apps/listmonk/src/README.md b/archive/apps/lemmy/src/README.md similarity index 100% rename from apps/listmonk/src/README.md rename to archive/apps/lemmy/src/README.md diff --git a/apps/lemmy/src/lemmy.hjson b/archive/apps/lemmy/src/lemmy.hjson similarity index 100% rename from apps/lemmy/src/lemmy.hjson rename to archive/apps/lemmy/src/lemmy.hjson diff --git a/apps/lemmy/src/nginx_internal.conf b/archive/apps/lemmy/src/nginx_internal.conf similarity index 100% rename from apps/lemmy/src/nginx_internal.conf rename to archive/apps/lemmy/src/nginx_internal.conf diff --git a/apps/lemmy/src/proxy_params b/archive/apps/lemmy/src/proxy_params similarity index 100% rename from apps/lemmy/src/proxy_params rename to archive/apps/lemmy/src/proxy_params diff --git a/apps/lemmy/variables.json b/archive/apps/lemmy/variables.json similarity index 100% rename from apps/lemmy/variables.json rename to archive/apps/lemmy/variables.json diff --git a/apps/linkwarden/.env b/archive/apps/linkwarden/.env similarity index 100% rename from apps/linkwarden/.env rename to archive/apps/linkwarden/.env diff --git a/apps/linkwarden/CHANGELOG.md b/archive/apps/linkwarden/CHANGELOG.md similarity index 100% rename from apps/linkwarden/CHANGELOG.md rename to archive/apps/linkwarden/CHANGELOG.md diff --git a/apps/linkwarden/Notes.md b/archive/apps/linkwarden/Notes.md similarity index 100% rename from apps/linkwarden/Notes.md rename to archive/apps/linkwarden/Notes.md diff --git a/apps/linkwarden/README.md b/archive/apps/linkwarden/README.md similarity index 100% rename from apps/linkwarden/README.md rename to archive/apps/linkwarden/README.md diff --git a/apps/linkwarden/docker-compose.yml b/archive/apps/linkwarden/docker-compose.yml similarity index 100% rename from apps/linkwarden/docker-compose.yml rename to archive/apps/linkwarden/docker-compose.yml diff --git a/apps/mage/src/README.md b/archive/apps/linkwarden/src/README.md similarity index 100% rename from apps/mage/src/README.md rename to archive/apps/linkwarden/src/README.md diff --git a/apps/linkwarden/variables.json b/archive/apps/linkwarden/variables.json similarity index 100% rename from apps/linkwarden/variables.json rename to archive/apps/linkwarden/variables.json diff --git a/apps/listmonk/.env b/archive/apps/listmonk/.env similarity index 100% rename from apps/listmonk/.env rename to archive/apps/listmonk/.env diff --git a/apps/listmonk/CHANGELOG.md b/archive/apps/listmonk/CHANGELOG.md similarity index 100% rename from apps/listmonk/CHANGELOG.md rename to archive/apps/listmonk/CHANGELOG.md diff --git a/apps/listmonk/Notes.md b/archive/apps/listmonk/Notes.md similarity index 100% rename from apps/listmonk/Notes.md rename to archive/apps/listmonk/Notes.md diff --git a/apps/listmonk/README.md b/archive/apps/listmonk/README.md similarity index 100% rename from apps/listmonk/README.md rename to archive/apps/listmonk/README.md diff --git a/apps/listmonk/docker-compose.yml b/archive/apps/listmonk/docker-compose.yml similarity index 100% rename from apps/listmonk/docker-compose.yml rename to archive/apps/listmonk/docker-compose.yml diff --git a/apps/manageiq/src/README.md b/archive/apps/listmonk/src/README.md similarity index 100% rename from apps/manageiq/src/README.md rename to archive/apps/listmonk/src/README.md diff --git a/apps/listmonk/variables.json b/archive/apps/listmonk/variables.json similarity index 100% rename from apps/listmonk/variables.json rename to archive/apps/listmonk/variables.json diff --git a/apps/mage/.env b/archive/apps/mage/.env similarity index 100% rename from apps/mage/.env rename to archive/apps/mage/.env diff --git a/apps/mage/CHANGELOG.md b/archive/apps/mage/CHANGELOG.md similarity index 100% rename from apps/mage/CHANGELOG.md rename to archive/apps/mage/CHANGELOG.md diff --git a/apps/mage/Notes.md b/archive/apps/mage/Notes.md similarity index 100% rename from apps/mage/Notes.md rename to archive/apps/mage/Notes.md diff --git a/apps/mage/README.md b/archive/apps/mage/README.md similarity index 100% rename from apps/mage/README.md rename to archive/apps/mage/README.md diff --git a/apps/mage/docker-compose.yml b/archive/apps/mage/docker-compose.yml similarity index 100% rename from apps/mage/docker-compose.yml rename to archive/apps/mage/docker-compose.yml diff --git a/apps/mathesar/src/README.md b/archive/apps/mage/src/README.md similarity index 100% rename from apps/mathesar/src/README.md rename to archive/apps/mage/src/README.md diff --git a/apps/mage/variables.json b/archive/apps/mage/variables.json similarity index 100% rename from apps/mage/variables.json rename to archive/apps/mage/variables.json diff --git a/apps/mailu/.env b/archive/apps/mailu/.env similarity index 100% rename from apps/mailu/.env rename to archive/apps/mailu/.env diff --git a/apps/mailu/CHANGELOG.md b/archive/apps/mailu/CHANGELOG.md similarity index 100% rename from apps/mailu/CHANGELOG.md rename to archive/apps/mailu/CHANGELOG.md diff --git a/apps/mailu/Notes.md b/archive/apps/mailu/Notes.md similarity index 100% rename from apps/mailu/Notes.md rename to archive/apps/mailu/Notes.md diff --git a/apps/mailu/README.md b/archive/apps/mailu/README.md similarity index 100% rename from apps/mailu/README.md rename to archive/apps/mailu/README.md diff --git a/apps/mailu/docker-compose.yml b/archive/apps/mailu/docker-compose.yml similarity index 100% rename from apps/mailu/docker-compose.yml rename to archive/apps/mailu/docker-compose.yml diff --git a/apps/mailu/variables.json b/archive/apps/mailu/variables.json similarity index 100% rename from apps/mailu/variables.json rename to archive/apps/mailu/variables.json diff --git a/apps/manageiq/.env b/archive/apps/manageiq/.env similarity index 100% rename from apps/manageiq/.env rename to archive/apps/manageiq/.env diff --git a/apps/manageiq/CHANGELOG.md b/archive/apps/manageiq/CHANGELOG.md similarity index 100% rename from apps/manageiq/CHANGELOG.md rename to archive/apps/manageiq/CHANGELOG.md diff --git a/apps/manageiq/Notes.md b/archive/apps/manageiq/Notes.md similarity index 100% rename from apps/manageiq/Notes.md rename to archive/apps/manageiq/Notes.md diff --git a/apps/manageiq/README.md b/archive/apps/manageiq/README.md similarity index 100% rename from apps/manageiq/README.md rename to archive/apps/manageiq/README.md diff --git a/apps/manageiq/docker-compose.yml b/archive/apps/manageiq/docker-compose.yml similarity index 100% rename from apps/manageiq/docker-compose.yml rename to archive/apps/manageiq/docker-compose.yml diff --git a/apps/matlab/src/README.md b/archive/apps/manageiq/src/README.md similarity index 100% rename from apps/matlab/src/README.md rename to archive/apps/manageiq/src/README.md diff --git a/apps/manageiq/variables.json b/archive/apps/manageiq/variables.json similarity index 100% rename from apps/manageiq/variables.json rename to archive/apps/manageiq/variables.json diff --git a/apps/mathesar/.env b/archive/apps/mathesar/.env similarity index 100% rename from apps/mathesar/.env rename to archive/apps/mathesar/.env diff --git a/apps/mathesar/CHANGELOG.md b/archive/apps/mathesar/CHANGELOG.md similarity index 100% rename from apps/mathesar/CHANGELOG.md rename to archive/apps/mathesar/CHANGELOG.md diff --git a/apps/mathesar/Notes.md b/archive/apps/mathesar/Notes.md similarity index 100% rename from apps/mathesar/Notes.md rename to archive/apps/mathesar/Notes.md diff --git a/apps/mathesar/README.md b/archive/apps/mathesar/README.md similarity index 100% rename from apps/mathesar/README.md rename to archive/apps/mathesar/README.md diff --git a/apps/mathesar/docker-compose.yml b/archive/apps/mathesar/docker-compose.yml similarity index 100% rename from apps/mathesar/docker-compose.yml rename to archive/apps/mathesar/docker-compose.yml diff --git a/apps/maven/src/README.md b/archive/apps/mathesar/src/README.md similarity index 100% rename from apps/maven/src/README.md rename to archive/apps/mathesar/src/README.md diff --git a/apps/mathesar/variables.json b/archive/apps/mathesar/variables.json similarity index 100% rename from apps/mathesar/variables.json rename to archive/apps/mathesar/variables.json diff --git a/apps/matlab/.env b/archive/apps/matlab/.env similarity index 100% rename from apps/matlab/.env rename to archive/apps/matlab/.env diff --git a/apps/matlab/CHANGELOG.md b/archive/apps/matlab/CHANGELOG.md similarity index 100% rename from apps/matlab/CHANGELOG.md rename to archive/apps/matlab/CHANGELOG.md diff --git a/apps/matlab/Notes.md b/archive/apps/matlab/Notes.md similarity index 100% rename from apps/matlab/Notes.md rename to archive/apps/matlab/Notes.md diff --git a/apps/matlab/README.md b/archive/apps/matlab/README.md similarity index 100% rename from apps/matlab/README.md rename to archive/apps/matlab/README.md diff --git a/apps/matlab/docker-compose.yml b/archive/apps/matlab/docker-compose.yml similarity index 100% rename from apps/matlab/docker-compose.yml rename to archive/apps/matlab/docker-compose.yml diff --git a/apps/miniflux/src/README.md b/archive/apps/matlab/src/README.md similarity index 100% rename from apps/miniflux/src/README.md rename to archive/apps/matlab/src/README.md diff --git a/apps/matlab/variables.json b/archive/apps/matlab/variables.json similarity index 100% rename from apps/matlab/variables.json rename to archive/apps/matlab/variables.json diff --git a/apps/maven/.env b/archive/apps/maven/.env similarity index 100% rename from apps/maven/.env rename to archive/apps/maven/.env diff --git a/apps/maven/CHANGELOG.md b/archive/apps/maven/CHANGELOG.md similarity index 100% rename from apps/maven/CHANGELOG.md rename to archive/apps/maven/CHANGELOG.md diff --git a/apps/maven/Notes.md b/archive/apps/maven/Notes.md similarity index 100% rename from apps/maven/Notes.md rename to archive/apps/maven/Notes.md diff --git a/apps/maven/README.md b/archive/apps/maven/README.md similarity index 100% rename from apps/maven/README.md rename to archive/apps/maven/README.md diff --git a/apps/maven/docker-compose.yml b/archive/apps/maven/docker-compose.yml similarity index 100% rename from apps/maven/docker-compose.yml rename to archive/apps/maven/docker-compose.yml diff --git a/apps/mixpost/src/README.md b/archive/apps/maven/src/README.md similarity index 100% rename from apps/mixpost/src/README.md rename to archive/apps/maven/src/README.md diff --git a/apps/maven/src/cmd.sh b/archive/apps/maven/src/cmd.sh similarity index 100% rename from apps/maven/src/cmd.sh rename to archive/apps/maven/src/cmd.sh diff --git a/apps/maven/variables.json b/archive/apps/maven/variables.json similarity index 100% rename from apps/maven/variables.json rename to archive/apps/maven/variables.json diff --git a/apps/memadmin/.env b/archive/apps/memadmin/.env similarity index 100% rename from apps/memadmin/.env rename to archive/apps/memadmin/.env diff --git a/apps/memadmin/CHANGELOG.md b/archive/apps/memadmin/CHANGELOG.md similarity index 100% rename from apps/memadmin/CHANGELOG.md rename to archive/apps/memadmin/CHANGELOG.md diff --git a/apps/memadmin/Notes.md b/archive/apps/memadmin/Notes.md similarity index 100% rename from apps/memadmin/Notes.md rename to archive/apps/memadmin/Notes.md diff --git a/apps/memadmin/README.md b/archive/apps/memadmin/README.md similarity index 100% rename from apps/memadmin/README.md rename to archive/apps/memadmin/README.md diff --git a/apps/memadmin/docker-compose.yml b/archive/apps/memadmin/docker-compose.yml similarity index 100% rename from apps/memadmin/docker-compose.yml rename to archive/apps/memadmin/docker-compose.yml diff --git a/apps/memadmin/src/filelist b/archive/apps/memadmin/src/filelist similarity index 100% rename from apps/memadmin/src/filelist rename to archive/apps/memadmin/src/filelist diff --git a/apps/memadmin/variables.json b/archive/apps/memadmin/variables.json similarity index 100% rename from apps/memadmin/variables.json rename to archive/apps/memadmin/variables.json diff --git a/apps/memcached/.env b/archive/apps/memcached/.env similarity index 100% rename from apps/memcached/.env rename to archive/apps/memcached/.env diff --git a/apps/memcached/CHANGELOG.md b/archive/apps/memcached/CHANGELOG.md similarity index 100% rename from apps/memcached/CHANGELOG.md rename to archive/apps/memcached/CHANGELOG.md diff --git a/apps/memcached/Notes.md b/archive/apps/memcached/Notes.md similarity index 100% rename from apps/memcached/Notes.md rename to archive/apps/memcached/Notes.md diff --git a/apps/memcached/README.md b/archive/apps/memcached/README.md similarity index 100% rename from apps/memcached/README.md rename to archive/apps/memcached/README.md diff --git a/apps/memcached/docker-compose.yml b/archive/apps/memcached/docker-compose.yml similarity index 100% rename from apps/memcached/docker-compose.yml rename to archive/apps/memcached/docker-compose.yml diff --git a/apps/memcached/src/after_up.sh b/archive/apps/memcached/src/after_up.sh similarity index 100% rename from apps/memcached/src/after_up.sh rename to archive/apps/memcached/src/after_up.sh diff --git a/apps/memcached/src/filelist b/archive/apps/memcached/src/filelist similarity index 100% rename from apps/memcached/src/filelist rename to archive/apps/memcached/src/filelist diff --git a/apps/memcached/src/get_version.sh b/archive/apps/memcached/src/get_version.sh similarity index 100% rename from apps/memcached/src/get_version.sh rename to archive/apps/memcached/src/get_version.sh diff --git a/apps/memcached/variables.json b/archive/apps/memcached/variables.json similarity index 100% rename from apps/memcached/variables.json rename to archive/apps/memcached/variables.json diff --git a/apps/miniflux/.env b/archive/apps/miniflux/.env similarity index 100% rename from apps/miniflux/.env rename to archive/apps/miniflux/.env diff --git a/apps/miniflux/CHANGELOG.md b/archive/apps/miniflux/CHANGELOG.md similarity index 100% rename from apps/miniflux/CHANGELOG.md rename to archive/apps/miniflux/CHANGELOG.md diff --git a/apps/miniflux/Notes.md b/archive/apps/miniflux/Notes.md similarity index 100% rename from apps/miniflux/Notes.md rename to archive/apps/miniflux/Notes.md diff --git a/apps/miniflux/README.md b/archive/apps/miniflux/README.md similarity index 100% rename from apps/miniflux/README.md rename to archive/apps/miniflux/README.md diff --git a/apps/miniflux/docker-compose.yml b/archive/apps/miniflux/docker-compose.yml similarity index 100% rename from apps/miniflux/docker-compose.yml rename to archive/apps/miniflux/docker-compose.yml diff --git a/apps/modsecurity/src/README.md b/archive/apps/miniflux/src/README.md similarity index 100% rename from apps/modsecurity/src/README.md rename to archive/apps/miniflux/src/README.md diff --git a/apps/miniflux/variables.json b/archive/apps/miniflux/variables.json similarity index 100% rename from apps/miniflux/variables.json rename to archive/apps/miniflux/variables.json diff --git a/apps/minio/.env b/archive/apps/minio/.env similarity index 100% rename from apps/minio/.env rename to archive/apps/minio/.env diff --git a/apps/minio/CHANGELOG.md b/archive/apps/minio/CHANGELOG.md similarity index 100% rename from apps/minio/CHANGELOG.md rename to archive/apps/minio/CHANGELOG.md diff --git a/apps/minio/Notes.md b/archive/apps/minio/Notes.md similarity index 100% rename from apps/minio/Notes.md rename to archive/apps/minio/Notes.md diff --git a/apps/minio/README.md b/archive/apps/minio/README.md similarity index 100% rename from apps/minio/README.md rename to archive/apps/minio/README.md diff --git a/apps/minio/docker-compose.yml b/archive/apps/minio/docker-compose.yml similarity index 100% rename from apps/minio/docker-compose.yml rename to archive/apps/minio/docker-compose.yml diff --git a/apps/minio/src/filelist b/archive/apps/minio/src/filelist similarity index 100% rename from apps/minio/src/filelist rename to archive/apps/minio/src/filelist diff --git a/apps/minio/src/get_version.sh b/archive/apps/minio/src/get_version.sh similarity index 100% rename from apps/minio/src/get_version.sh rename to archive/apps/minio/src/get_version.sh diff --git a/apps/minio/variables.json b/archive/apps/minio/variables.json similarity index 100% rename from apps/minio/variables.json rename to archive/apps/minio/variables.json diff --git a/apps/mixpost/.env b/archive/apps/mixpost/.env similarity index 100% rename from apps/mixpost/.env rename to archive/apps/mixpost/.env diff --git a/apps/mixpost/Notes.md b/archive/apps/mixpost/Notes.md similarity index 100% rename from apps/mixpost/Notes.md rename to archive/apps/mixpost/Notes.md diff --git a/apps/mixpost/README.md b/archive/apps/mixpost/README.md similarity index 100% rename from apps/mixpost/README.md rename to archive/apps/mixpost/README.md diff --git a/apps/mixpost/docker-compose.yml b/archive/apps/mixpost/docker-compose.yml similarity index 100% rename from apps/mixpost/docker-compose.yml rename to archive/apps/mixpost/docker-compose.yml diff --git a/apps/monkeycode/src/README.md b/archive/apps/mixpost/src/README.md similarity index 100% rename from apps/monkeycode/src/README.md rename to archive/apps/mixpost/src/README.md diff --git a/apps/mixpost/variables.json b/archive/apps/mixpost/variables.json similarity index 100% rename from apps/mixpost/variables.json rename to archive/apps/mixpost/variables.json diff --git a/apps/modsecurity/.env b/archive/apps/modsecurity/.env similarity index 100% rename from apps/modsecurity/.env rename to archive/apps/modsecurity/.env diff --git a/apps/modsecurity/CHANGELOG.md b/archive/apps/modsecurity/CHANGELOG.md similarity index 100% rename from apps/modsecurity/CHANGELOG.md rename to archive/apps/modsecurity/CHANGELOG.md diff --git a/apps/lago/Notes.md b/archive/apps/modsecurity/Notes.md similarity index 100% rename from apps/lago/Notes.md rename to archive/apps/modsecurity/Notes.md diff --git a/apps/modsecurity/docker-compose.yml b/archive/apps/modsecurity/docker-compose.yml similarity index 100% rename from apps/modsecurity/docker-compose.yml rename to archive/apps/modsecurity/docker-compose.yml diff --git a/apps/mqttx/src/README.md b/archive/apps/modsecurity/src/README.md similarity index 100% rename from apps/mqttx/src/README.md rename to archive/apps/modsecurity/src/README.md diff --git a/apps/modsecurity/variables.json b/archive/apps/modsecurity/variables.json similarity index 100% rename from apps/modsecurity/variables.json rename to archive/apps/modsecurity/variables.json diff --git a/apps/mongocompass/.env b/archive/apps/mongocompass/.env similarity index 100% rename from apps/mongocompass/.env rename to archive/apps/mongocompass/.env diff --git a/apps/mongocompass/CHANGELOG.md b/archive/apps/mongocompass/CHANGELOG.md similarity index 100% rename from apps/mongocompass/CHANGELOG.md rename to archive/apps/mongocompass/CHANGELOG.md diff --git a/apps/mongocompass/Dockerfile b/archive/apps/mongocompass/Dockerfile similarity index 100% rename from apps/mongocompass/Dockerfile rename to archive/apps/mongocompass/Dockerfile diff --git a/apps/mongocompass/Notes.md b/archive/apps/mongocompass/Notes.md similarity index 100% rename from apps/mongocompass/Notes.md rename to archive/apps/mongocompass/Notes.md diff --git a/apps/mongocompass/README.md b/archive/apps/mongocompass/README.md similarity index 100% rename from apps/mongocompass/README.md rename to archive/apps/mongocompass/README.md diff --git a/apps/mongocompass/docker-compose.yml b/archive/apps/mongocompass/docker-compose.yml similarity index 100% rename from apps/mongocompass/docker-compose.yml rename to archive/apps/mongocompass/docker-compose.yml diff --git a/apps/mongocompass/src/get_version.sh b/archive/apps/mongocompass/src/get_version.sh similarity index 100% rename from apps/mongocompass/src/get_version.sh rename to archive/apps/mongocompass/src/get_version.sh diff --git a/apps/mongocompass/variables.json b/archive/apps/mongocompass/variables.json similarity index 100% rename from apps/mongocompass/variables.json rename to archive/apps/mongocompass/variables.json diff --git a/apps/mongoexpress/.env b/archive/apps/mongoexpress/.env similarity index 100% rename from apps/mongoexpress/.env rename to archive/apps/mongoexpress/.env diff --git a/apps/mongoexpress/CHANGELOG.md b/archive/apps/mongoexpress/CHANGELOG.md similarity index 100% rename from apps/mongoexpress/CHANGELOG.md rename to archive/apps/mongoexpress/CHANGELOG.md diff --git a/apps/mongoexpress/Notes.md b/archive/apps/mongoexpress/Notes.md similarity index 100% rename from apps/mongoexpress/Notes.md rename to archive/apps/mongoexpress/Notes.md diff --git a/apps/mongoexpress/README.md b/archive/apps/mongoexpress/README.md similarity index 100% rename from apps/mongoexpress/README.md rename to archive/apps/mongoexpress/README.md diff --git a/apps/mongoexpress/docker-compose.yml b/archive/apps/mongoexpress/docker-compose.yml similarity index 100% rename from apps/mongoexpress/docker-compose.yml rename to archive/apps/mongoexpress/docker-compose.yml diff --git a/apps/mongoexpress/src/filelist b/archive/apps/mongoexpress/src/filelist similarity index 100% rename from apps/mongoexpress/src/filelist rename to archive/apps/mongoexpress/src/filelist diff --git a/apps/mongoexpress/variables.json b/archive/apps/mongoexpress/variables.json similarity index 100% rename from apps/mongoexpress/variables.json rename to archive/apps/mongoexpress/variables.json diff --git a/apps/monkeycode/.env b/archive/apps/monkeycode/.env similarity index 100% rename from apps/monkeycode/.env rename to archive/apps/monkeycode/.env diff --git a/apps/monkeycode/CHANGELOG.md b/archive/apps/monkeycode/CHANGELOG.md similarity index 100% rename from apps/monkeycode/CHANGELOG.md rename to archive/apps/monkeycode/CHANGELOG.md diff --git a/apps/monkeycode/Notes.md b/archive/apps/monkeycode/Notes.md similarity index 100% rename from apps/monkeycode/Notes.md rename to archive/apps/monkeycode/Notes.md diff --git a/apps/monkeycode/docker-compose.yml b/archive/apps/monkeycode/docker-compose.yml similarity index 100% rename from apps/monkeycode/docker-compose.yml rename to archive/apps/monkeycode/docker-compose.yml diff --git a/apps/navidrome/src/README.md b/archive/apps/monkeycode/src/README.md similarity index 100% rename from apps/navidrome/src/README.md rename to archive/apps/monkeycode/src/README.md diff --git a/apps/monkeycode/variables.json b/archive/apps/monkeycode/variables.json similarity index 100% rename from apps/monkeycode/variables.json rename to archive/apps/monkeycode/variables.json diff --git a/apps/mosquitto/.env b/archive/apps/mosquitto/.env similarity index 100% rename from apps/mosquitto/.env rename to archive/apps/mosquitto/.env diff --git a/apps/mosquitto/CHANGELOG.md b/archive/apps/mosquitto/CHANGELOG.md similarity index 100% rename from apps/mosquitto/CHANGELOG.md rename to archive/apps/mosquitto/CHANGELOG.md diff --git a/apps/mosquitto/Notes.md b/archive/apps/mosquitto/Notes.md similarity index 100% rename from apps/mosquitto/Notes.md rename to archive/apps/mosquitto/Notes.md diff --git a/apps/mosquitto/README.md b/archive/apps/mosquitto/README.md similarity index 100% rename from apps/mosquitto/README.md rename to archive/apps/mosquitto/README.md diff --git a/apps/mosquitto/docker-compose.yml b/archive/apps/mosquitto/docker-compose.yml similarity index 100% rename from apps/mosquitto/docker-compose.yml rename to archive/apps/mosquitto/docker-compose.yml diff --git a/apps/mosquitto/src/mosquitto.conf b/archive/apps/mosquitto/src/mosquitto.conf similarity index 100% rename from apps/mosquitto/src/mosquitto.conf rename to archive/apps/mosquitto/src/mosquitto.conf diff --git a/apps/mosquitto/variables.json b/archive/apps/mosquitto/variables.json similarity index 100% rename from apps/mosquitto/variables.json rename to archive/apps/mosquitto/variables.json diff --git a/apps/mqttx/.env b/archive/apps/mqttx/.env similarity index 100% rename from apps/mqttx/.env rename to archive/apps/mqttx/.env diff --git a/apps/mqttx/CHANGELOG.md b/archive/apps/mqttx/CHANGELOG.md similarity index 100% rename from apps/mqttx/CHANGELOG.md rename to archive/apps/mqttx/CHANGELOG.md diff --git a/apps/mqttx/Notes.md b/archive/apps/mqttx/Notes.md similarity index 100% rename from apps/mqttx/Notes.md rename to archive/apps/mqttx/Notes.md diff --git a/apps/mqttx/README.md b/archive/apps/mqttx/README.md similarity index 100% rename from apps/mqttx/README.md rename to archive/apps/mqttx/README.md diff --git a/apps/mqttx/docker-compose.yml b/archive/apps/mqttx/docker-compose.yml similarity index 100% rename from apps/mqttx/docker-compose.yml rename to archive/apps/mqttx/docker-compose.yml diff --git a/apps/neko/src/README.md b/archive/apps/mqttx/src/README.md similarity index 100% rename from apps/neko/src/README.md rename to archive/apps/mqttx/src/README.md diff --git a/apps/mqttx/variables.json b/archive/apps/mqttx/variables.json similarity index 100% rename from apps/mqttx/variables.json rename to archive/apps/mqttx/variables.json diff --git a/apps/mysqlworkbench/.env b/archive/apps/mysqlworkbench/.env similarity index 100% rename from apps/mysqlworkbench/.env rename to archive/apps/mysqlworkbench/.env diff --git a/apps/mysqlworkbench/CHANGELOG.md b/archive/apps/mysqlworkbench/CHANGELOG.md similarity index 100% rename from apps/mysqlworkbench/CHANGELOG.md rename to archive/apps/mysqlworkbench/CHANGELOG.md diff --git a/apps/mysqlworkbench/Notes.md b/archive/apps/mysqlworkbench/Notes.md similarity index 100% rename from apps/mysqlworkbench/Notes.md rename to archive/apps/mysqlworkbench/Notes.md diff --git a/apps/mysqlworkbench/README.md b/archive/apps/mysqlworkbench/README.md similarity index 100% rename from apps/mysqlworkbench/README.md rename to archive/apps/mysqlworkbench/README.md diff --git a/apps/mysqlworkbench/docker-compose.yml b/archive/apps/mysqlworkbench/docker-compose.yml similarity index 100% rename from apps/mysqlworkbench/docker-compose.yml rename to archive/apps/mysqlworkbench/docker-compose.yml diff --git a/apps/mysqlworkbench/src/README.md b/archive/apps/mysqlworkbench/src/README.md similarity index 100% rename from apps/mysqlworkbench/src/README.md rename to archive/apps/mysqlworkbench/src/README.md diff --git a/apps/mysqlworkbench/variables.json b/archive/apps/mysqlworkbench/variables.json similarity index 100% rename from apps/mysqlworkbench/variables.json rename to archive/apps/mysqlworkbench/variables.json diff --git a/apps/navidrome/.env b/archive/apps/navidrome/.env similarity index 100% rename from apps/navidrome/.env rename to archive/apps/navidrome/.env diff --git a/apps/navidrome/CHANGELOG.md b/archive/apps/navidrome/CHANGELOG.md similarity index 100% rename from apps/navidrome/CHANGELOG.md rename to archive/apps/navidrome/CHANGELOG.md diff --git a/apps/navidrome/Notes.md b/archive/apps/navidrome/Notes.md similarity index 100% rename from apps/navidrome/Notes.md rename to archive/apps/navidrome/Notes.md diff --git a/apps/navidrome/README.md b/archive/apps/navidrome/README.md similarity index 100% rename from apps/navidrome/README.md rename to archive/apps/navidrome/README.md diff --git a/apps/navidrome/docker-compose.yml b/archive/apps/navidrome/docker-compose.yml similarity index 100% rename from apps/navidrome/docker-compose.yml rename to archive/apps/navidrome/docker-compose.yml diff --git a/apps/nexterm/src/README.md b/archive/apps/navidrome/src/README.md similarity index 100% rename from apps/nexterm/src/README.md rename to archive/apps/navidrome/src/README.md diff --git a/apps/navidrome/variables.json b/archive/apps/navidrome/variables.json similarity index 100% rename from apps/navidrome/variables.json rename to archive/apps/navidrome/variables.json diff --git a/apps/neko/.env b/archive/apps/neko/.env similarity index 100% rename from apps/neko/.env rename to archive/apps/neko/.env diff --git a/apps/neko/CHANGELOG.md b/archive/apps/neko/CHANGELOG.md similarity index 100% rename from apps/neko/CHANGELOG.md rename to archive/apps/neko/CHANGELOG.md diff --git a/apps/neko/Notes.md b/archive/apps/neko/Notes.md similarity index 100% rename from apps/neko/Notes.md rename to archive/apps/neko/Notes.md diff --git a/apps/neko/README.md b/archive/apps/neko/README.md similarity index 100% rename from apps/neko/README.md rename to archive/apps/neko/README.md diff --git a/apps/neko/docker-compose.yml b/archive/apps/neko/docker-compose.yml similarity index 100% rename from apps/neko/docker-compose.yml rename to archive/apps/neko/docker-compose.yml diff --git a/apps/nexus/src/README.md b/archive/apps/neko/src/README.md similarity index 100% rename from apps/nexus/src/README.md rename to archive/apps/neko/src/README.md diff --git a/apps/neko/variables.json b/archive/apps/neko/variables.json similarity index 100% rename from apps/neko/variables.json rename to archive/apps/neko/variables.json diff --git a/apps/netdata/.env b/archive/apps/netdata/.env similarity index 100% rename from apps/netdata/.env rename to archive/apps/netdata/.env diff --git a/apps/netdata/CHANGELOG.md b/archive/apps/netdata/CHANGELOG.md similarity index 100% rename from apps/netdata/CHANGELOG.md rename to archive/apps/netdata/CHANGELOG.md diff --git a/apps/netdata/Notes.md b/archive/apps/netdata/Notes.md similarity index 100% rename from apps/netdata/Notes.md rename to archive/apps/netdata/Notes.md diff --git a/apps/netdata/README.md b/archive/apps/netdata/README.md similarity index 100% rename from apps/netdata/README.md rename to archive/apps/netdata/README.md diff --git a/apps/netdata/docker-compose.yml b/archive/apps/netdata/docker-compose.yml similarity index 100% rename from apps/netdata/docker-compose.yml rename to archive/apps/netdata/docker-compose.yml diff --git a/apps/netdata/variables.json b/archive/apps/netdata/variables.json similarity index 100% rename from apps/netdata/variables.json rename to archive/apps/netdata/variables.json diff --git a/apps/nextchat/.env b/archive/apps/nextchat/.env similarity index 100% rename from apps/nextchat/.env rename to archive/apps/nextchat/.env diff --git a/apps/nextchat/CHANGELOG.md b/archive/apps/nextchat/CHANGELOG.md similarity index 100% rename from apps/nextchat/CHANGELOG.md rename to archive/apps/nextchat/CHANGELOG.md diff --git a/apps/nextchat/Notes.md b/archive/apps/nextchat/Notes.md similarity index 100% rename from apps/nextchat/Notes.md rename to archive/apps/nextchat/Notes.md diff --git a/apps/nextchat/README.md b/archive/apps/nextchat/README.md similarity index 100% rename from apps/nextchat/README.md rename to archive/apps/nextchat/README.md diff --git a/apps/nextchat/docker-compose.yml b/archive/apps/nextchat/docker-compose.yml similarity index 100% rename from apps/nextchat/docker-compose.yml rename to archive/apps/nextchat/docker-compose.yml diff --git a/apps/nextchat/variables.json b/archive/apps/nextchat/variables.json similarity index 100% rename from apps/nextchat/variables.json rename to archive/apps/nextchat/variables.json diff --git a/apps/nexterm/.env b/archive/apps/nexterm/.env similarity index 100% rename from apps/nexterm/.env rename to archive/apps/nexterm/.env diff --git a/apps/nexterm/CHANGELOG.md b/archive/apps/nexterm/CHANGELOG.md similarity index 100% rename from apps/nexterm/CHANGELOG.md rename to archive/apps/nexterm/CHANGELOG.md diff --git a/apps/langfuse/Notes.md b/archive/apps/nexterm/Notes.md similarity index 100% rename from apps/langfuse/Notes.md rename to archive/apps/nexterm/Notes.md diff --git a/apps/nexterm/README.md b/archive/apps/nexterm/README.md similarity index 100% rename from apps/nexterm/README.md rename to archive/apps/nexterm/README.md diff --git a/apps/nexterm/docker-compose.yml b/archive/apps/nexterm/docker-compose.yml similarity index 100% rename from apps/nexterm/docker-compose.yml rename to archive/apps/nexterm/docker-compose.yml diff --git a/apps/nomad/src/README.md b/archive/apps/nexterm/src/README.md similarity index 100% rename from apps/nomad/src/README.md rename to archive/apps/nexterm/src/README.md diff --git a/apps/nexterm/variables.json b/archive/apps/nexterm/variables.json similarity index 100% rename from apps/nexterm/variables.json rename to archive/apps/nexterm/variables.json diff --git a/apps/nextterminal/.env b/archive/apps/nextterminal/.env similarity index 100% rename from apps/nextterminal/.env rename to archive/apps/nextterminal/.env diff --git a/apps/nextterminal/CHANGELOG.md b/archive/apps/nextterminal/CHANGELOG.md similarity index 100% rename from apps/nextterminal/CHANGELOG.md rename to archive/apps/nextterminal/CHANGELOG.md diff --git a/apps/nextterminal/Notes.md b/archive/apps/nextterminal/Notes.md similarity index 100% rename from apps/nextterminal/Notes.md rename to archive/apps/nextterminal/Notes.md diff --git a/apps/nextterminal/README.md b/archive/apps/nextterminal/README.md similarity index 100% rename from apps/nextterminal/README.md rename to archive/apps/nextterminal/README.md diff --git a/apps/nextterminal/docker-compose.yml b/archive/apps/nextterminal/docker-compose.yml similarity index 100% rename from apps/nextterminal/docker-compose.yml rename to archive/apps/nextterminal/docker-compose.yml diff --git a/apps/nextterminal/src/config.yaml b/archive/apps/nextterminal/src/config.yaml similarity index 100% rename from apps/nextterminal/src/config.yaml rename to archive/apps/nextterminal/src/config.yaml diff --git a/apps/nextterminal/variables.json b/archive/apps/nextterminal/variables.json similarity index 100% rename from apps/nextterminal/variables.json rename to archive/apps/nextterminal/variables.json diff --git a/apps/nexus/.env b/archive/apps/nexus/.env similarity index 100% rename from apps/nexus/.env rename to archive/apps/nexus/.env diff --git a/apps/nexus/CHANGELOG.md b/archive/apps/nexus/CHANGELOG.md similarity index 100% rename from apps/nexus/CHANGELOG.md rename to archive/apps/nexus/CHANGELOG.md diff --git a/apps/nexus/Notes.md b/archive/apps/nexus/Notes.md similarity index 100% rename from apps/nexus/Notes.md rename to archive/apps/nexus/Notes.md diff --git a/apps/nexus/README.md b/archive/apps/nexus/README.md similarity index 100% rename from apps/nexus/README.md rename to archive/apps/nexus/README.md diff --git a/apps/nexus/docker-compose.yml b/archive/apps/nexus/docker-compose.yml similarity index 100% rename from apps/nexus/docker-compose.yml rename to archive/apps/nexus/docker-compose.yml diff --git a/apps/php/src/README.md b/archive/apps/nexus/src/README.md similarity index 100% rename from apps/php/src/README.md rename to archive/apps/nexus/src/README.md diff --git a/apps/nexus/variables.json b/archive/apps/nexus/variables.json similarity index 100% rename from apps/nexus/variables.json rename to archive/apps/nexus/variables.json diff --git a/apps/nocobase/.env b/archive/apps/nocobase/.env similarity index 100% rename from apps/nocobase/.env rename to archive/apps/nocobase/.env diff --git a/apps/nocobase/CHANGELOG.md b/archive/apps/nocobase/CHANGELOG.md similarity index 100% rename from apps/nocobase/CHANGELOG.md rename to archive/apps/nocobase/CHANGELOG.md diff --git a/apps/nocobase/Notes.md b/archive/apps/nocobase/Notes.md similarity index 100% rename from apps/nocobase/Notes.md rename to archive/apps/nocobase/Notes.md diff --git a/apps/nocobase/README.md b/archive/apps/nocobase/README.md similarity index 100% rename from apps/nocobase/README.md rename to archive/apps/nocobase/README.md diff --git a/apps/nocobase/docker-compose.yml b/archive/apps/nocobase/docker-compose.yml similarity index 100% rename from apps/nocobase/docker-compose.yml rename to archive/apps/nocobase/docker-compose.yml diff --git a/apps/nocobase/variables.json b/archive/apps/nocobase/variables.json similarity index 100% rename from apps/nocobase/variables.json rename to archive/apps/nocobase/variables.json diff --git a/apps/nocodb/.env b/archive/apps/nocodb/.env similarity index 100% rename from apps/nocodb/.env rename to archive/apps/nocodb/.env diff --git a/apps/nocodb/CHANGELOG.md b/archive/apps/nocodb/CHANGELOG.md similarity index 100% rename from apps/nocodb/CHANGELOG.md rename to archive/apps/nocodb/CHANGELOG.md diff --git a/apps/nocodb/Notes.md b/archive/apps/nocodb/Notes.md similarity index 100% rename from apps/nocodb/Notes.md rename to archive/apps/nocodb/Notes.md diff --git a/apps/nocodb/README.md b/archive/apps/nocodb/README.md similarity index 100% rename from apps/nocodb/README.md rename to archive/apps/nocodb/README.md diff --git a/apps/nocodb/docker-compose.yml b/archive/apps/nocodb/docker-compose.yml similarity index 100% rename from apps/nocodb/docker-compose.yml rename to archive/apps/nocodb/docker-compose.yml diff --git a/apps/nocodb/variables.json b/archive/apps/nocodb/variables.json similarity index 100% rename from apps/nocodb/variables.json rename to archive/apps/nocodb/variables.json diff --git a/apps/nomad/.env b/archive/apps/nomad/.env similarity index 100% rename from apps/nomad/.env rename to archive/apps/nomad/.env diff --git a/apps/nomad/CHANGELOG.md b/archive/apps/nomad/CHANGELOG.md similarity index 100% rename from apps/nomad/CHANGELOG.md rename to archive/apps/nomad/CHANGELOG.md diff --git a/apps/nomad/Dockerfile b/archive/apps/nomad/Dockerfile similarity index 100% rename from apps/nomad/Dockerfile rename to archive/apps/nomad/Dockerfile diff --git a/apps/litellm/Notes.md b/archive/apps/nomad/Notes.md similarity index 100% rename from apps/litellm/Notes.md rename to archive/apps/nomad/Notes.md diff --git a/apps/nomad/README.jinja2 b/archive/apps/nomad/README.jinja2 similarity index 100% rename from apps/nomad/README.jinja2 rename to archive/apps/nomad/README.jinja2 diff --git a/apps/nomad/README.md b/archive/apps/nomad/README.md similarity index 100% rename from apps/nomad/README.md rename to archive/apps/nomad/README.md diff --git a/apps/nomad/docker-compose.yml b/archive/apps/nomad/docker-compose.yml similarity index 100% rename from apps/nomad/docker-compose.yml rename to archive/apps/nomad/docker-compose.yml diff --git a/apps/python/src/README.md b/archive/apps/nomad/src/README.md similarity index 100% rename from apps/python/src/README.md rename to archive/apps/nomad/src/README.md diff --git a/apps/litellm/src/nginx-proxy.conf.template b/archive/apps/nomad/src/nginx-proxy.conf.template similarity index 100% rename from apps/litellm/src/nginx-proxy.conf.template rename to archive/apps/nomad/src/nginx-proxy.conf.template diff --git a/apps/litellm/src/php_exra.ini b/archive/apps/nomad/src/php_exra.ini similarity index 100% rename from apps/litellm/src/php_exra.ini rename to archive/apps/nomad/src/php_exra.ini diff --git a/apps/nomad/variables.json b/archive/apps/nomad/variables.json similarity index 100% rename from apps/nomad/variables.json rename to archive/apps/nomad/variables.json diff --git a/apps/owncloud/.env b/archive/apps/owncloud/.env similarity index 100% rename from apps/owncloud/.env rename to archive/apps/owncloud/.env diff --git a/apps/owncloud/CHANGELOG.md b/archive/apps/owncloud/CHANGELOG.md similarity index 100% rename from apps/owncloud/CHANGELOG.md rename to archive/apps/owncloud/CHANGELOG.md diff --git a/apps/owncloud/Notes.md b/archive/apps/owncloud/Notes.md similarity index 100% rename from apps/owncloud/Notes.md rename to archive/apps/owncloud/Notes.md diff --git a/apps/owncloud/README.md b/archive/apps/owncloud/README.md similarity index 100% rename from apps/owncloud/README.md rename to archive/apps/owncloud/README.md diff --git a/apps/owncloud/docker-compose.yml b/archive/apps/owncloud/docker-compose.yml similarity index 100% rename from apps/owncloud/docker-compose.yml rename to archive/apps/owncloud/docker-compose.yml diff --git a/apps/owncloud/tests/cases.yml b/archive/apps/owncloud/tests/cases.yml similarity index 100% rename from apps/owncloud/tests/cases.yml rename to archive/apps/owncloud/tests/cases.yml diff --git a/apps/owncloud/tests/check.sh b/archive/apps/owncloud/tests/check.sh similarity index 100% rename from apps/owncloud/tests/check.sh rename to archive/apps/owncloud/tests/check.sh diff --git a/apps/owncloud/variables.json b/archive/apps/owncloud/variables.json similarity index 100% rename from apps/owncloud/variables.json rename to archive/apps/owncloud/variables.json diff --git a/apps/php/.env b/archive/apps/php/.env similarity index 100% rename from apps/php/.env rename to archive/apps/php/.env diff --git a/apps/php/CHANGELOG.md b/archive/apps/php/CHANGELOG.md similarity index 100% rename from apps/php/CHANGELOG.md rename to archive/apps/php/CHANGELOG.md diff --git a/apps/php/Dockerfile b/archive/apps/php/Dockerfile similarity index 100% rename from apps/php/Dockerfile rename to archive/apps/php/Dockerfile diff --git a/apps/php/Notes.md b/archive/apps/php/Notes.md similarity index 100% rename from apps/php/Notes.md rename to archive/apps/php/Notes.md diff --git a/apps/php/README.md b/archive/apps/php/README.md similarity index 100% rename from apps/php/README.md rename to archive/apps/php/README.md diff --git a/apps/php/docker-compose.yml b/archive/apps/php/docker-compose.yml similarity index 100% rename from apps/php/docker-compose.yml rename to archive/apps/php/docker-compose.yml diff --git a/apps/php/src/000-default.conf b/archive/apps/php/src/000-default.conf similarity index 100% rename from apps/php/src/000-default.conf rename to archive/apps/php/src/000-default.conf diff --git a/apps/semaphore/src/README.md b/archive/apps/php/src/README.md similarity index 100% rename from apps/semaphore/src/README.md rename to archive/apps/php/src/README.md diff --git a/apps/php/src/apt_install.sh b/archive/apps/php/src/apt_install.sh similarity index 100% rename from apps/php/src/apt_install.sh rename to archive/apps/php/src/apt_install.sh diff --git a/apps/php/src/cmd.sh b/archive/apps/php/src/cmd.sh similarity index 100% rename from apps/php/src/cmd.sh rename to archive/apps/php/src/cmd.sh diff --git a/apps/php/src/extensions.ini b/archive/apps/php/src/extensions.ini similarity index 100% rename from apps/php/src/extensions.ini rename to archive/apps/php/src/extensions.ini diff --git a/apps/php/src/php_extra.ini b/archive/apps/php/src/php_extra.ini similarity index 100% rename from apps/php/src/php_extra.ini rename to archive/apps/php/src/php_extra.ini diff --git a/apps/php/src/php_install.sh b/archive/apps/php/src/php_install.sh similarity index 100% rename from apps/php/src/php_install.sh rename to archive/apps/php/src/php_install.sh diff --git a/apps/php/variables.json b/archive/apps/php/variables.json similarity index 100% rename from apps/php/variables.json rename to archive/apps/php/variables.json diff --git a/apps/pimcore/.env b/archive/apps/pimcore/.env similarity index 100% rename from apps/pimcore/.env rename to archive/apps/pimcore/.env diff --git a/apps/pimcore/CHANGELOG.md b/archive/apps/pimcore/CHANGELOG.md similarity index 100% rename from apps/pimcore/CHANGELOG.md rename to archive/apps/pimcore/CHANGELOG.md diff --git a/apps/pimcore/Notes.md b/archive/apps/pimcore/Notes.md similarity index 100% rename from apps/pimcore/Notes.md rename to archive/apps/pimcore/Notes.md diff --git a/apps/pimcore/README.md b/archive/apps/pimcore/README.md similarity index 100% rename from apps/pimcore/README.md rename to archive/apps/pimcore/README.md diff --git a/apps/pimcore/docker-compose.yml b/archive/apps/pimcore/docker-compose.yml similarity index 100% rename from apps/pimcore/docker-compose.yml rename to archive/apps/pimcore/docker-compose.yml diff --git a/apps/pimcore/src/bootstrap.sh b/archive/apps/pimcore/src/bootstrap.sh similarity index 100% rename from apps/pimcore/src/bootstrap.sh rename to archive/apps/pimcore/src/bootstrap.sh diff --git a/apps/pimcore/src/messenger.yaml b/archive/apps/pimcore/src/messenger.yaml similarity index 100% rename from apps/pimcore/src/messenger.yaml rename to archive/apps/pimcore/src/messenger.yaml diff --git a/apps/pimcore/src/nginx.conf b/archive/apps/pimcore/src/nginx.conf similarity index 100% rename from apps/pimcore/src/nginx.conf rename to archive/apps/pimcore/src/nginx.conf diff --git a/apps/pimcore/tests/cases.yml b/archive/apps/pimcore/tests/cases.yml similarity index 100% rename from apps/pimcore/tests/cases.yml rename to archive/apps/pimcore/tests/cases.yml diff --git a/apps/pimcore/variables.json b/archive/apps/pimcore/variables.json similarity index 100% rename from apps/pimcore/variables.json rename to archive/apps/pimcore/variables.json diff --git a/apps/posthog/.env b/archive/apps/posthog/.env similarity index 94% rename from apps/posthog/.env rename to archive/apps/posthog/.env index fe0c2ba29..c31c30904 100644 --- a/apps/posthog/.env +++ b/archive/apps/posthog/.env @@ -38,7 +38,8 @@ POSTHOG_DB_NAME=posthog POSTHOG_DB_USER=posthog POSTHOG_DB_PASSWORD=${W9_POWER_PASSWORD} POSTHOG_SECRET=change-this-posthog-secret -ENCRYPTION_SALT_KEYS=change-this-salt-key +# Must be exactly 32 characters. Generate one with: openssl rand -hex 16 +ENCRYPTION_SALT_KEYS=0123456789abcdef0123456789abcdef DATABASE_URL=postgres://${POSTHOG_DB_USER}:${POSTHOG_DB_PASSWORD}@db:5432/${POSTHOG_DB_NAME} REDIS_URL=redis://redis7:6379/ diff --git a/archive/apps/posthog/CHANGELOG.md b/archive/apps/posthog/CHANGELOG.md new file mode 100644 index 000000000..bab30d04e --- /dev/null +++ b/archive/apps/posthog/CHANGELOG.md @@ -0,0 +1,14 @@ +# CHANGELOG + +## 2026-10-09 + +- Replaced the placeholder WordPress/Discuz files with a real PostHog self-hosted Compose package. +- Added PostHog upstream metadata, runtime environment wiring, and access metadata. +- Added compose helper scripts for PostHog startup and migration flow. + +## 2026-10-12 + +- Restored PostHog from `archive/apps/` back to active maintenance. +- Switched the package to an upstream-shaped network model: internal services stay on the Compose-private network and only the `proxy` entrypoint joins `websoft9`. +- Removed fixed `container_name` assignments so multi-instance isolation can rely on the Compose project name instead of per-service naming. +- Updated the default `ENCRYPTION_SALT_KEYS` to a valid 32-character value and documented the `openssl rand -hex 16` generation requirement. diff --git a/apps/posthog/Notes.md b/archive/apps/posthog/Notes.md similarity index 53% rename from apps/posthog/Notes.md rename to archive/apps/posthog/Notes.md index aa70045ea..b27982df7 100644 --- a/apps/posthog/Notes.md +++ b/archive/apps/posthog/Notes.md @@ -6,3 +6,6 @@ - Upstream self-hosting is compose-based and tracks floating images rather than stable semver releases. - `W9_VERSION` intentionally remains `latest` unless Websoft9 decides to pin a known-good tag later. - The package keeps the app-local topology smaller than upstream hobby by using published images instead of upstream local builds. +- This package intentionally does not assign `container_name` values so multi-instance isolation can rely on the Compose project name instead. +- Only the `proxy` service joins `${W9_NETWORK}`; the rest of the stack stays on the default Compose network. +- `ENCRYPTION_SALT_KEYS` must be exactly 32 characters for current PostHog builds; generate a replacement with `openssl rand -hex 16`. diff --git a/apps/posthog/README.md b/archive/apps/posthog/README.md similarity index 76% rename from apps/posthog/README.md rename to archive/apps/posthog/README.md index 47f1645d1..aae58cd4d 100644 --- a/apps/posthog/README.md +++ b/archive/apps/posthog/README.md @@ -16,6 +16,8 @@ PostHog recommends a VM roughly equivalent to: - PostHog does not publish stable self-hosted releases in the usual `x.y.z` form. - The upstream project recommends running the latest Docker image for self-hosted deployments. +- This package keeps the upstream multi-service topology instead of forcing a simplified Websoft9-style layout. +- Only the `proxy` entrypoint joins the shared `websoft9` network; internal services stay on the Compose-private network. - This package exposes the PostHog web entrypoint through the internal Caddy proxy on port `80`. ## Install diff --git a/apps/posthog/docker-compose.yml b/archive/apps/posthog/docker-compose.yml similarity index 95% rename from apps/posthog/docker-compose.yml rename to archive/apps/posthog/docker-compose.yml index a09035ec5..3cc1b652e 100644 --- a/apps/posthog/docker-compose.yml +++ b/archive/apps/posthog/docker-compose.yml @@ -9,11 +9,13 @@ x-logging: &default-logging services: proxy: image: caddy:2 - container_name: ${W9_ID} restart: unless-stopped logging: *default-logging ports: - "${W9_HTTP_PORT_SET}:80" # Web Console + networks: + - default + - websoft9 command: - sh - -c @@ -99,7 +101,6 @@ services: db: image: postgres:${W9_DB_VERSION} - container_name: ${W9_ID}-postgresql restart: unless-stopped logging: *default-logging environment: @@ -117,7 +118,6 @@ services: redis7: image: redis:${REDIS_VERSION} - container_name: ${W9_ID}-redis restart: unless-stopped logging: *default-logging command: redis-server --maxmemory-policy allkeys-lru --maxmemory 200mb @@ -131,7 +131,6 @@ services: valkey: image: valkey/valkey:${VALKEY_VERSION} - container_name: ${W9_ID}-valkey restart: unless-stopped logging: *default-logging command: valkey-server --maxmemory-policy allkeys-lru --maxmemory 200mb @@ -143,7 +142,6 @@ services: clickhouse: image: clickhouse/clickhouse-server:${CLICKHOUSE_VERSION} - container_name: ${W9_ID}-clickhouse restart: unless-stopped logging: *default-logging environment: @@ -159,7 +157,6 @@ services: kafka: image: docker.io/redpandadata/redpanda:${KAFKA_VERSION} - container_name: ${W9_ID}-kafka restart: unless-stopped logging: *default-logging command: @@ -206,7 +203,6 @@ services: objectstorage: image: chrislusf/seaweedfs:${OBJECTSTORAGE_VERSION} - container_name: ${W9_ID}-objectstorage restart: unless-stopped logging: *default-logging entrypoint: @@ -244,7 +240,6 @@ services: geoip: image: alpine:3.20 - container_name: ${W9_ID}-geoip restart: "no" logging: *default-logging command: @@ -261,7 +256,6 @@ services: web: image: ${W9_REPO}:${W9_VERSION} - container_name: ${W9_ID}-web restart: unless-stopped logging: *default-logging command: /compose/start @@ -295,7 +289,6 @@ services: worker: image: ${W9_REPO}:${W9_VERSION} - container_name: ${W9_ID}-worker restart: unless-stopped logging: *default-logging command: ./bin/docker-worker-celery --with-scheduler @@ -328,7 +321,6 @@ services: plugins: image: posthog/posthog-node:${POSTHOG_NODE_TAG} - container_name: ${W9_ID}-plugins restart: unless-stopped logging: *default-logging command: node nodejs/dist/index.js @@ -366,7 +358,6 @@ services: ingestion-general: image: posthog/posthog-node:${POSTHOG_NODE_TAG} - container_name: ${W9_ID}-ingestion restart: unless-stopped logging: *default-logging command: node nodejs/dist/index.js @@ -403,7 +394,6 @@ services: ingestion-sessionreplay: image: posthog/posthog-node:${POSTHOG_NODE_TAG} - container_name: ${W9_ID}-sessionreplay restart: unless-stopped logging: *default-logging command: node nodejs/dist/index.js @@ -425,7 +415,6 @@ services: recording-api: image: posthog/posthog-node:${POSTHOG_NODE_TAG} - container_name: ${W9_ID}-recording-api restart: unless-stopped logging: *default-logging command: node nodejs/dist/index.js @@ -449,7 +438,6 @@ services: capture: image: ghcr.io/posthog/posthog/capture:master - container_name: ${W9_ID}-capture restart: unless-stopped logging: *default-logging env_file: @@ -480,7 +468,6 @@ services: replay-capture: image: ghcr.io/posthog/posthog/capture:master - container_name: ${W9_ID}-replay-capture restart: unless-stopped logging: *default-logging env_file: @@ -499,7 +486,6 @@ services: feature-flags: image: ghcr.io/posthog/posthog/feature-flags:master - container_name: ${W9_ID}-feature-flags restart: unless-stopped logging: *default-logging env_file: @@ -538,6 +524,6 @@ volumes: share-data: networks: - default: + websoft9: name: ${W9_NETWORK} external: true diff --git a/apps/posthog/src/compose/start b/archive/apps/posthog/src/compose/start similarity index 100% rename from apps/posthog/src/compose/start rename to archive/apps/posthog/src/compose/start diff --git a/apps/posthog/src/compose/wait b/archive/apps/posthog/src/compose/wait similarity index 100% rename from apps/posthog/src/compose/wait rename to archive/apps/posthog/src/compose/wait diff --git a/apps/posthog/variables.json b/archive/apps/posthog/variables.json similarity index 100% rename from apps/posthog/variables.json rename to archive/apps/posthog/variables.json diff --git a/apps/python/.env b/archive/apps/python/.env similarity index 100% rename from apps/python/.env rename to archive/apps/python/.env diff --git a/apps/python/CHANGELOG.md b/archive/apps/python/CHANGELOG.md similarity index 100% rename from apps/python/CHANGELOG.md rename to archive/apps/python/CHANGELOG.md diff --git a/apps/python/Notes.md b/archive/apps/python/Notes.md similarity index 100% rename from apps/python/Notes.md rename to archive/apps/python/Notes.md diff --git a/apps/python/README.md b/archive/apps/python/README.md similarity index 100% rename from apps/python/README.md rename to archive/apps/python/README.md diff --git a/apps/python/docker-compose.yml b/archive/apps/python/docker-compose.yml similarity index 100% rename from apps/python/docker-compose.yml rename to archive/apps/python/docker-compose.yml diff --git a/archive/apps/xinference/src/README.md b/archive/apps/python/src/README.md similarity index 100% rename from archive/apps/xinference/src/README.md rename to archive/apps/python/src/README.md diff --git a/apps/python/src/cmd.sh b/archive/apps/python/src/cmd.sh similarity index 100% rename from apps/python/src/cmd.sh rename to archive/apps/python/src/cmd.sh diff --git a/apps/python/variables.json b/archive/apps/python/variables.json similarity index 100% rename from apps/python/variables.json rename to archive/apps/python/variables.json diff --git a/apps/signoz/.env b/archive/apps/signoz/.env similarity index 100% rename from apps/signoz/.env rename to archive/apps/signoz/.env diff --git a/apps/signoz/CHANGELOG.md b/archive/apps/signoz/CHANGELOG.md similarity index 100% rename from apps/signoz/CHANGELOG.md rename to archive/apps/signoz/CHANGELOG.md diff --git a/apps/signoz/Notes.md b/archive/apps/signoz/Notes.md similarity index 100% rename from apps/signoz/Notes.md rename to archive/apps/signoz/Notes.md diff --git a/apps/signoz/docker-compose.yml b/archive/apps/signoz/docker-compose.yml similarity index 100% rename from apps/signoz/docker-compose.yml rename to archive/apps/signoz/docker-compose.yml diff --git a/apps/signoz/src/README.md b/archive/apps/signoz/src/README.md similarity index 100% rename from apps/signoz/src/README.md rename to archive/apps/signoz/src/README.md diff --git a/apps/signoz/src/clickhouse/cluster.xml b/archive/apps/signoz/src/clickhouse/cluster.xml similarity index 100% rename from apps/signoz/src/clickhouse/cluster.xml rename to archive/apps/signoz/src/clickhouse/cluster.xml diff --git a/apps/signoz/src/clickhouse/config.xml b/archive/apps/signoz/src/clickhouse/config.xml similarity index 100% rename from apps/signoz/src/clickhouse/config.xml rename to archive/apps/signoz/src/clickhouse/config.xml diff --git a/apps/signoz/src/clickhouse/custom-function.xml b/archive/apps/signoz/src/clickhouse/custom-function.xml similarity index 100% rename from apps/signoz/src/clickhouse/custom-function.xml rename to archive/apps/signoz/src/clickhouse/custom-function.xml diff --git a/apps/signoz/src/clickhouse/users.xml b/archive/apps/signoz/src/clickhouse/users.xml similarity index 100% rename from apps/signoz/src/clickhouse/users.xml rename to archive/apps/signoz/src/clickhouse/users.xml diff --git a/apps/signoz/src/otel-collector-config.yaml b/archive/apps/signoz/src/otel-collector-config.yaml similarity index 100% rename from apps/signoz/src/otel-collector-config.yaml rename to archive/apps/signoz/src/otel-collector-config.yaml diff --git a/apps/signoz/src/signoz/otel-collector-opamp-config.yaml b/archive/apps/signoz/src/signoz/otel-collector-opamp-config.yaml similarity index 100% rename from apps/signoz/src/signoz/otel-collector-opamp-config.yaml rename to archive/apps/signoz/src/signoz/otel-collector-opamp-config.yaml diff --git a/apps/signoz/src/signoz/prometheus.yml b/archive/apps/signoz/src/signoz/prometheus.yml similarity index 100% rename from apps/signoz/src/signoz/prometheus.yml rename to archive/apps/signoz/src/signoz/prometheus.yml diff --git a/apps/signoz/variables.json b/archive/apps/signoz/variables.json similarity index 100% rename from apps/signoz/variables.json rename to archive/apps/signoz/variables.json diff --git a/archive/apps/xinference/.env b/archive/apps/xinference/.env deleted file mode 100644 index edb933432..000000000 --- a/archive/apps/xinference/.env +++ /dev/null @@ -1,53 +0,0 @@ -W9_REPO="wordpress" -W9_DIST=community -W9_VERSION="latest" - -W9_POWER_PASSWORD="1PrMxExC45LsCT" - -# Environments which for user settings when create application -# Named expression: W9_xxx_xxx_SET, xxx refer to file fields -W9_HTTP_PORT_SET=9001 -# W9_HTTPS_PORT_SET=9002 -# W9_DB_PORT_SET=3306 -# W9_SSH_PORT_SET=23 -W9_KEY_SET="dfsjdkjf77xjxcjcj" - -#### -- Not allowed to edit below environments when recreate app based on existing data -- #### - -W9_ID=xinference - -# W9_HTTP_PORT or W9_HTTPS_PORT is need at leaset and used for proxy for web application -# Some container (e.g teleport) need HTTPS access, then need to set this pra -W9_HTTP_PORT=80 -W9_HTTPS_PORT=81 - -W9_LOGIN_USER=admin -# use https://1password.com/zh-cn/password-generator/ to genarate 14 bit password -# this password can also use password file -W9_LOGIN_PASSWORD=$W9_POWER_PASSWORD -W9_ADMIN_PATH="/wp-login" - -# Container name's suffix must use one of the value -W9_DB_EXPOSE="mysql,postgresql,mariadb,mongodb,redis" - -# It is used when the application APP needs to set an external URL, which can be IP(or domain), IP:PORT -# If have protocols, should be set it in the APP's ENV -W9_URL=internet_ip:$W9_HTTP_PORT_SET -# modifies W9_URL on init when it is true -W9_URL_REPLACE=true - -W9_NETWORK=websoft9 - -#### ----------------------------------------------------------------------------------------- #### - - -# Below environment is created by this app - -WORDPRESS_DB_HOST=$W9_ID-mariadb -WORDPRESS_DB_USER=wordpress #if use postgresql, it need set to postgres -WORDPRESS_DB_PASSWORD=$W9_POWER_PASSWORD -WORDPRESS_DB_NAME=wordpress - - -#W9_NAME="" -#W9_RCODE="" \ No newline at end of file diff --git a/archive/apps/xinference/CHANGELOG.md b/archive/apps/xinference/CHANGELOG.md deleted file mode 100644 index 582cf46c5..000000000 --- a/archive/apps/xinference/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# CHANGELOG - -## Release -### Fixes and Enhancements - diff --git a/archive/apps/xinference/Dockerfile b/archive/apps/xinference/Dockerfile deleted file mode 100644 index 4364b46fb..000000000 --- a/archive/apps/xinference/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -# image: https://hub.docker.com/r/websoft9dev/discuzq - -FROM ccr.ccs.tencentyun.com/discuzq/dzq:latest - -LABEL org.opencontainers.image.authors="https://www.websoft9.com" \ - org.opencontainers.image.description="Application packaged by Websoft9" \ - org.opencontainers.image.source="https://github.com/Websoft9/docker-library/tree/main/apps/opencart" \ - org.opencontainers.image.title="OpenCart" \ - org.opencontainers.image.vendor="Websoft9 Inc." \ - org.opencontainers.image.version="4.0.1.1" - -ENV DISCUZQ_MYSQL_HOST=mysql -ENV DISCUZQ_MYSQL_USER=discuzq -ENV DISCUZQ_MYSQL_PASSWORD=discuzq -ENV DISCUZQ_MYSQL_DATABASE=discuzq -ENV DISCUZQ_SITENAME=DiscuzQ - -COPY cmd.sh /tmp -RUN chmod +x /tmp/cmd.sh - -CMD ["/tmp/cmd.sh"] diff --git a/archive/apps/xinference/Notes.md b/archive/apps/xinference/Notes.md deleted file mode 100644 index 1fdbbb29d..000000000 --- a/archive/apps/xinference/Notes.md +++ /dev/null @@ -1,2 +0,0 @@ -# Appname -## FAQ diff --git a/archive/apps/xinference/README.jinja2 b/archive/apps/xinference/README.jinja2 deleted file mode 100644 index 8949cc4e0..000000000 --- a/archive/apps/xinference/README.jinja2 +++ /dev/null @@ -1,26 +0,0 @@ -# {{trademark}} on Docker - -This is an **Docker Compose solution** powered by [Websoft9](https://www.websoft9.com) based on Docker for {{trademark}}: - -{% for ed in edition %} - - {{ed.dist}}: {{ ed.version | join(', ') }} -{% endfor %} - -## System Requirements - -The following are the minimal [recommended requirements]({{requirements.url}}): - -* **RAM**: {{requirements.memory}} GB or more -* **CPU**: {{requirements.cpu}} cores or higher -* **Disk**: at least {{requirements.disk}} GB of free space -* **bandwidth**: more fluent experience over 100M - -## Install - -You can install this {{trademark}} by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). - -If you want use {{trademark}} with **Websoft9 Business Support** free, you can [subscribe {{trademark}}](https://www.websoft9.com/apps) on Cloud platform - -## Documentation - -[{{trademark}} Administrator Guide](https://support.websoft9.com/docs/{{name}}) powered by Websoft9 diff --git a/archive/apps/xinference/README.md b/archive/apps/xinference/README.md deleted file mode 100644 index 5147022bc..000000000 --- a/archive/apps/xinference/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Xinference on Docker - -This is an **[Docker Compose template](https://github.com/Websoft9/docker-library)** powered by [Websoft9](https://www.websoft9.com) based on Docker for Xinference: - - - - community: latest - - -## System Requirements - -The following are the minimal [recommended requirements](https://inference.readthedocs.io): - -* **RAM**: 4 GB or more -* **CPU**: 2 cores or higher -* **Disk**: at least 10 GB of free space -* **bandwidth**: more fluent experience over 100M - -## Install - -You can install this Xinference by [How to use it?](https://github.com/Websoft9/docker-library#how-to-use-it). - -If you want use Xinference with **Websoft9 Business Support** free, you can [subscribe Xinference](https://www.websoft9.com/apps) on Cloud platform - -## Documentation - -[Xinference Administrator Guide](https://support.websoft9.com/docs/xinference) powered by Websoft9 \ No newline at end of file diff --git a/archive/apps/xinference/docker-compose.yml b/archive/apps/xinference/docker-compose.yml deleted file mode 100644 index 1c1948688..000000000 --- a/archive/apps/xinference/docker-compose.yml +++ /dev/null @@ -1,50 +0,0 @@ -# image,docs: https://hub.docker.com/_/wordpress/ - -services: - - wordpress: - image: $W9_REPO:$W9_VERSION - container_name: $W9_ID - restart: unless-stopped - #This is for access host from container - # extra_hosts: ["host.docker.internal:host-gateway"] - # command: | - # /bin/bash -c "ping -c 3 host.docker.internal" - logging: - driver: "json-file" - options: - max-file: "5" - max-size: 10m - deploy: - resources: - limits: - memory: 5g - cpus: '0.7' - ports: - - $W9_HTTP_PORT_SET:80 - env_file: .env - volumes: - - wordpress:/var/www/html - - ./src/php_exra.ini:/usr/local/etc/php/conf.d/php_exra.ini - - mariadb: - image: mariadb:10.4 - container_name: $W9_ID-mariadb - restart: unless-stopped - command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb_log_buffer_size=30M - volumes: - - mysql_data:/var/lib/mysql - environment: - MYSQL_DATABASE: $WORDPRESS_DB_NAME - MYSQL_USER: $WORDPRESS_DB_USER - MYSQL_PASSWORD: $W9_POWER_PASSWORD - MYSQL_ROOT_PASSWORD: $W9_POWER_PASSWORD - -volumes: - wordpress: - mysql_data: - -networks: - default: - name: $W9_NETWORK - external: true diff --git a/archive/apps/xinference/src/nginx-proxy.conf.template b/archive/apps/xinference/src/nginx-proxy.conf.template deleted file mode 100644 index 951364ffe..000000000 --- a/archive/apps/xinference/src/nginx-proxy.conf.template +++ /dev/null @@ -1,57 +0,0 @@ -proxy_busy_buffers_size 512k; -proxy_buffers 4 512k; -proxy_buffer_size 256k; -client_max_body_size 50m; -# override default location / -location / { - add_header X-Served-By $host; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-Scheme $scheme; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Real-IP $remote_addr; - proxy_pass $forward_scheme://$server:$port$request_uri; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection upgrade; - } - -location /console { - proxy_pass http://$server:8080; - proxy_http_version 1.1; - proxy_set_header Host $http_host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; -} - -# for echo some useful information -location / { - default_type text/plain; - return 200 'Hello World'; -} - -location /oida/ { -# this is the address and port of the ORDS installation -proxy_pass http://127.0.0.1:8080/ords/; - -# set Origin to blank to avoid Chrome problems with CORS -proxy_set_header Origin "" ; - -# pass along some header variables with the public host name/port/and so on -proxy_set_header Host $host; -proxy_set_header X-Forwarded-Host $host:$server_port; -proxy_set_header X-Real-IP $remote_addr; -proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; -proxy_set_header X-Forwarded-Proto $scheme; - -# this reverse proxies any "location" headers being passed in the response -proxy_redirect http://$host/ords/ https://$host/oida/; - -# also tell cookies their public path -proxy_cookie_path /ords/ /oida/; - -# reverse proxy links included in response (ie from ORDS webservice) -sub_filter_types application/json ; -sub_filter http://$host/ords/ https://$host/oida/; -sub_filter_once off; -} diff --git a/archive/apps/xinference/src/php_exra.ini b/archive/apps/xinference/src/php_exra.ini deleted file mode 100644 index b253d5718..000000000 --- a/archive/apps/xinference/src/php_exra.ini +++ /dev/null @@ -1,8 +0,0 @@ -file_uploads = On -max_input_time = 800 -max_execution_time = 300 -memory_limit = 600M -upload_max_filesize = 900M -post_max_size = 900M -max_file_uploads = 200 -error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT \ No newline at end of file diff --git a/archive/apps/xinference/variables.json b/archive/apps/xinference/variables.json deleted file mode 100644 index d82424d6a..000000000 --- a/archive/apps/xinference/variables.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "xinference", - "trademark": "Xinference", - "release": false, - "edition": [ - { - "dist": "community", - "version": [ - "latest" - ] - } - ], - "requirements": { - "cpu": "2", - "memory": "4", - "disk": "10" - }, - "upstream": { - "image": "https://hub.docker.com/r/xprobe/xinference" - } -} diff --git a/batch-update-report-m-n-2026-10-13.md b/batch-update-report-m-n-2026-10-13.md new file mode 100644 index 000000000..a85d00c62 --- /dev/null +++ b/batch-update-report-m-n-2026-10-13.md @@ -0,0 +1,255 @@ +## Batch Update Report + +- selector mode: initials +- selector input: `m,n` +- resolved apps: `mariadb, matomo, mattermost, mautic, meilisearch, metabase, milvus, mlflow, mongodb, moodle, mysql, n8n, neo4j, nextcloud, nextjs, nginx, nginxproxymanager, nifi, nodejs, nodered, nopcommerce` +- failure policy: continue +- concurrency used: assessment parallelized; remote deploy validation and appstore sync effectively serialized after environment conflicts +- overall decision: partially-blocked + +## Per-App Results + +- app: `mattermost` + result: updated + skip reason: + current version: `11.11` + target version: `11.11.1` + files changed: `apps/mattermost/.env`, `apps/mattermost/variables.json`, `apps/mattermost/CHANGELOG.md`, `apps/mattermost/README.md` + validation: passed `app-check`, remote deploy, web reachability, and `/api/v4/system/ping` + appstore sync: passed + risks: package still uses shared remote ports `9001/8443`; owner E2E should confirm first-run admin flow and Calls port behavior + owner E2E focus: confirm login, team creation/core chat path, and site URL behavior behind platform proxy + +- app: `n8n` + result: updated + skip reason: + current version: `2.43.4` + target version: `2.43.4` + files changed: existing worktree changes in `apps/n8n/*` plus `apps/n8n/tests/` + validation: passed `app-check`, remote deploy, and web reachability + appstore sync: passed + risks: validation only proved reachability, not authenticated first-run workflow + owner E2E focus: verify first access, workflow editor load, and webhook/base URL behavior + +- app: `neo4j` + result: updated + skip reason: + current version: `2026.07` + target version: `2026.09` + files changed: existing worktree changes in `apps/neo4j/.env`, `CHANGELOG.md`, `README.md`, `variables.json`, `tests/cases.yml` + validation: passed after rerunning sequentially; remote deploy and web reachability OK + appstore sync: passed + risks: release-line jump is calendar-tag based; browser UI passed but Bolt usage was not validated + owner E2E focus: verify browser console, default credentials flow, and Bolt connectivity + +- app: `nextcloud` + result: updated + skip reason: + current version: `34.0` + target version: `35.0` + files changed: existing worktree changes in `apps/nextcloud/.env`, `CHANGELOG.md`, `README.md`, `variables.json`, `tests/cases.yml` + validation: passed `app-check`, remote deploy, and `/login` reachability + appstore sync: passed + risks: only automated login-page reachability checked; upgrade path with real persisted data not exercised + owner E2E focus: verify install/login flow, storage setup, and bundled MySQL behavior + +- app: `nginx` + result: updated + skip reason: + current version: `1.29` + target version: `1.31` + files changed: existing worktree changes in `apps/nginx/.env`, `CHANGELOG.md`, `README.md`, `docker-compose.yml`, `src/cmd.sh`, `variables.json`, `tests/cases.yml` + validation: passed `app-check`, remote deploy, and web reachability + appstore sync: passed + risks: package still validates only the demo/default page path + owner E2E focus: confirm container starts cleanly from appstore and default content renders as expected + +- app: `nginxproxymanager` + result: updated + skip reason: + current version: `2.10.4` + target version: `2.16.0` + files changed: existing worktree changes in `apps/nginxproxymanager/.env`, `CHANGELOG.md`, `README.md`, `docker-compose.yml`, `variables.json`, `tests/cases.yml` + validation: passed after rerunning sequentially; remote deploy and web reachability OK + appstore sync: passed + risks: automated check did not exercise first-login credential rotation flow + owner E2E focus: verify default login, forced credential change, proxy host creation, and HTTPS listener + +- app: `nifi` + result: failed + skip reason: + current version: `latest` / broken legacy package shape before current worktree changes + target version: `2.12.0` + files changed: existing worktree changes in `apps/nifi/.env`, `CHANGELOG.md`, `Notes.md`, `README.md`, `docker-compose.yml`, `variables.json`, deletions under `src/`, `tests/check-https-login.sh` + validation: deploy passed, but custom HTTPS validation still failed; first failure was bad script input, then after fix the script reached `curl: (35) Send failure: Broken pipe` + appstore sync: not run + risks: HTTPS readiness/self-signed bootstrap path is still not reliably covered by current test case + owner E2E focus: after follow-up fix, confirm HTTPS UI load, self-signed warning handling, and single-user login + +- app: `nodejs` + result: updated + skip reason: + current version: `24` + target version: `26` + files changed: existing worktree changes in `apps/nodejs/.env`, `CHANGELOG.md`, `README.md`, `docker-compose.yml`, `src/cmd.sh`, `variables.json`, `tests/cases.yml` + validation: passed `app-check`, remote deploy, and web reachability + appstore sync: passed + risks: package validates only the demo scaffold/runtime template + owner E2E focus: confirm runtime starts from appstore and sample app responds as expected + +- app: `nodered` + result: updated + skip reason: + current version: `4.1` + target version: `5.0` + files changed: existing worktree changes in `apps/nodered/.env`, `CHANGELOG.md`, `README.md`, `docker-compose.yml`, `variables.json`, `tests/cases.yml` + validation: passed after rerunning sequentially; remote deploy and web reachability OK + appstore sync: passed + risks: no auth configured; validation only checked open console reachability + owner E2E focus: verify editor loads, flow persistence, and intended unauthenticated/default access behavior + +- app: `nextjs` + result: failed + skip reason: + current version: `16.3.5` + target version: `16.4.0` + files changed: existing worktree changes in `apps/nextjs/.env`, `CHANGELOG.md`, `README.md`, `variables.json` + validation: deploy passed, but `container-healthy` never reached healthy; healthcheck stayed `starting` + appstore sync: not run + risks: first-run scaffold/install/build inside container is slow and likely needs healthcheck/readiness tuning + owner E2E focus: after follow-up fix, confirm scaffold completes, app becomes healthy, and page loads on first boot + +- app: `mariadb` + result: needs owner decision + skip reason: + current version: `12.0` default with many additional tracks + target version: `13.0` + files changed: + validation: + appstore sync: + risks: major DB track change plus stale version matrix; not a clean blind batch bump + owner E2E focus: decide whether to do a dedicated version-matrix cleanup/update + +- app: `matomo` + result: needs owner decision + skip reason: + current version: `5.6.1` + target version: `5.14` + files changed: + validation: + appstore sync: + risks: package is far behind and likely entangled with old bundled MySQL defaults + owner E2E focus: decide whether to take a dedicated upgrade task instead of batch pass + +- app: `mautic` + result: needs owner decision + skip reason: invalid current packaged version metadata (`6-apache`) blocks deterministic assessment + current version: invalid package metadata + target version: unclear stable target without metadata normalization + files changed: + validation: + appstore sync: + risks: metadata-blocked before safe implementation + owner E2E focus: normalize current versioning model first + +- app: `meilisearch` + result: needs owner decision + skip reason: + current version: `1.16` + target version: `v1.55` + files changed: + validation: + appstore sync: + risks: very large intra-major gap with likely breaking behavior changes + owner E2E focus: assess compatibility and package shape before implementation + +- app: `metabase` + result: needs owner decision + skip reason: wildcard packaged version (`v0.64.x`) blocks deterministic current-to-target comparison + current version: wildcard metadata + target version: likely latest `v0.64.1.x` patch line + files changed: + validation: + appstore sync: + risks: metadata normalization needed first + owner E2E focus: decide whether to fix version declaration first, then update + +- app: `milvus` + result: needs owner decision + skip reason: + current version: `2.6.3` + target version: `v2.6.25` + files changed: + validation: + appstore sync: + risks: bundle compatibility with pinned companion images should be reviewed + owner E2E focus: assess full stack compatibility, not only main image bump + +- app: `mlflow` + result: needs owner decision + skip reason: + current version: `3.1.4` + target version: provisional `v3.17.0` + files changed: + validation: + appstore sync: + risks: upstream source metadata appears ambiguous; target detection confidence is low + owner E2E focus: verify target version source before implementation + +- app: `mongodb` + result: skipped + skip reason: runtime/environment history indicates newer MongoDB lines were previously blocked on current Linux kernel behavior + current version: `7.0` default, additional `8.0`, `8.3` + target version: no safe batch target chosen + files changed: + validation: + appstore sync: + risks: environment/runtime block, not just packaging + owner E2E focus: re-evaluate only when runtime constraint is intentionally revisited + +- app: `moodle` + result: needs owner decision + skip reason: + current version: `5.2.2` + target version: `5.3` + files changed: + validation: + appstore sync: + risks: image/provider and DB compatibility should be reviewed together + owner E2E focus: confirm upstream image and DB support before update + +- app: `mysql` + result: needs owner decision + skip reason: + current version: `9.5` default with many legacy tracks + target version: `9.7` + files changed: + validation: + appstore sync: + risks: update is mixed with stale matrix cleanup and DB policy decisions + owner E2E focus: decide whether to do dedicated matrix rationalization + +- app: `nopcommerce` + result: skipped + skip reason: only newer prerelease candidate detected; no newer stable release than packaged version + current version: `4.90.8` + target version: + files changed: + validation: + appstore sync: + risks: prerelease-only candidate + owner E2E focus: none until a stable upstream release appears + +## Blockers And Exceptions + +- shared-file conflicts: none added by this run; all implemented changes stayed app-local +- environment limits: remote validation must stay serial because all test deployments publish `9001`; early parallel attempts caused false port-allocation failures +- appstore sync handoff blocks: `nextjs` and `nifi` were not synced because automated validation did not pass +- stopped early because of failure policy: no + +## Summary + +- updated apps: `mattermost`, `n8n`, `neo4j`, `nextcloud`, `nginx`, `nginxproxymanager`, `nodejs`, `nodered` +- needs owner decision: `mariadb`, `matomo`, `mautic`, `meilisearch`, `metabase`, `milvus`, `mlflow`, `moodle`, `mysql` +- failed apps: `nifi`, `nextjs` +- skipped apps: `mongodb`, `nopcommerce` diff --git a/ci/READEME.md b/ci/READEME.md new file mode 100644 index 000000000..e69de29bb diff --git a/ci/cloud/aliyun-ecs.json b/ci/cloud/aliyun-ecs.json new file mode 100644 index 000000000..68e87ae6b --- /dev/null +++ b/ci/cloud/aliyun-ecs.json @@ -0,0 +1,32 @@ +{ + "provider": "aliyun", + "region": "cn-hongkong", + "instance": { + "name_prefix": "libs-test", + "type": "ecs.g7.large", + "spot_strategy": "SpotAsPriceGo", + "spot_duration": 0, + "internet_max_bandwidth_out": 100, + "key_pair_name": "websoft9_auto" + }, + "system_disk": { + "category": "cloud_essd", + "min_size_gib": 20, + "max_size_gib": 500, + "default_size_gib": 200 + }, + "release": { + "default_hours": 10, + "min_hours": 1, + "max_hours": 168 + }, + "network": { + "security_group_id": "sg-j6c7epgwcech14ofdt5l", + "vswitch_id": "vsw-j6cpor7vbblzas6ui2pkf" + }, + "image": { + "owner_alias": "marketplace", + "product_code": "cmjj010728", + "select": "latest" + } +} diff --git a/ci/cloud/aliyun.cli b/ci/cloud/aliyun.cli new file mode 100644 index 000000000..70310a7c6 --- /dev/null +++ b/ci/cloud/aliyun.cli @@ -0,0 +1,15 @@ +aliyun ecs RunInstances \ + --region cn-hongkong \ + --InstanceName root-cdl-test-buy1 \ + --ImageId 'm-j6caxlj97mf3l51d0wcz' \ + --SystemDisk.Category cloud_essd \ + --SystemDisk.Size 200 \ + --InstanceType ecs.g7.large \ + --SecurityGroupId 'sg-j6c7epgwcech14ofdt5l' \ + --VSwitchId 'vsw-j6cpor7vbblzas6ui2pkf' \ + --InternetMaxBandwidthOut 100 \ + --KeyPairName 'websoft9_auto' \ + --SpotStrategy SpotAsPriceGo \ + --SpotDuration 0 \ + --AutoReleaseTime '2026-10-13T11:19:00Z' \ + --output cols=InstanceIdSets.InstanceIdSet[0] | sed -n '3p' \ No newline at end of file diff --git a/cli/README.md b/cli/README.md index d021382ff..cee849810 100644 --- a/cli/README.md +++ b/cli/README.md @@ -80,14 +80,19 @@ py -m venv .venv - `libs app-down --app [--ssh-host ] [--progress] [--json]` - tear one app down with `docker compose down -v` - `libs appstore-sync --app --ssh-host [--progress] [--verbose]` - sync one app directory into the remote websoft9 container library and sync `metadata/catalog/.json` into the container catalog directory for appstore testing - `libs appstore-deploy --app --ssh-host [--progress] [--verbose]` - deploy one app into a websoft9 container appstore (not implemented yet; pending the websoft9 container CLI) -- `libs websoft9-upgrade [--container ] [--tag ] [--tag-var ] [--compose-dir ] [--target local|remote] [--ssh-host ] [--progress] [--verbose]` - upgrade the Websoft9 platform container: set the image tag (default `dev`), run `docker compose pull`, then `docker compose up -d`; the compose project is discovered from the container labels unless `--compose-dir` is given -- `libs dns-bind [--domain ] [--target local|remote] [--ip ] [--json]` - point the wildcard record `*.` at the remote host or `127.0.0.1`; it creates the record when missing, updates it when the value differs, and is a no-op (`action = unchanged`) when the IP already matches, so repeated runs never error; `--domain` defaults to `ALIYUN_DNS_DOMAIN`, and `--target` defaults to `TARGET` in `.secrets/remote.env` (add `--ssh-host` to override) - - on success it also runs `websoft9 setconfig --section domain --key wildcard_domain --value ` inside the Websoft9 container to bind the platform domain; the container name comes from `CONTAINER` in `.secrets/remote.env` (default `websoft9`, override with `--container`); if the container is absent or unreachable this step is skipped silently and reported as `container_config.status = skipped`; pass `--no-container` to skip it explicitly -- `libs dns-delete [--domain ] [--json]` - delete the single wildcard record `*.` managed for the domain; errors when it is missing or ambiguous - remote-aware commands suppress the routine `known hosts` add warning from ephemeral SSH targets; real stderr still passes through - `libs proxy` - show, save, or clear the saved proxy - `libs help` - show help, same as `libs --help` +## Make Ops + +These server-side operations are exposed as `make` targets, not `libs` commands. They accept the same options through `ARGS`. + +- `make dns-bind ARGS="[--domain ] [--target local|remote] [--ip ] [--json]"` - point the wildcard record `*.` at the remote host or `127.0.0.1`; it creates the record when missing, updates it when the value differs, and is a no-op (`action = unchanged`) when the IP already matches, so repeated runs never error; `--domain` defaults to `DNS_DOMAIN`, and `--target` defaults to `TARGET` in `.secrets/remote.env` (add `--ssh-host` to override) + - on success it also runs `websoft9 setconfig --section domain --key wildcard_domain --value ` inside the Websoft9 container to bind the platform domain; the container name comes from `CONTAINER` in `.secrets/remote.env` (default `websoft9`, override with `--container`); if the container is absent or unreachable this step is skipped silently and reported as `container_config.status = skipped`; pass `--no-container` to skip it explicitly +- `make dns-delete ARGS="[--domain ] [--json]"` - delete the single wildcard record `*.` managed for the domain; errors when it is missing or ambiguous +- `make websoft9-upgrade ARGS="[--container ] [--tag ] [--tag-var ] [--compose-dir ] [--target local|remote] [--ssh-host ] [--progress] [--verbose]"` - upgrade the Websoft9 platform container: set the image tag (default `dev`), run `docker compose pull`, then `docker compose up -d`; the compose project is discovered from the container labels unless `--compose-dir` is given + Options: `--json`, `--progress`, `--verbose`, `--plan-only`, `--selection`, `--date`, `--include-archived`, `--scope`, `--major-ahead`, `--proxy`, `-h` / `--help`. Shared execution options: @@ -106,8 +111,9 @@ Network behavior: - `cli/proxy.conf` is machine-local and gitignored Credentials: -- provider-specific token files live under `.secrets/`, for example `.secrets/contentful.env`, `.secrets/cloudflare.env`, and `.secrets/aliyun.env` (gitignored) -- each provider file stores the token directly as a standard env var, e.g. `CONTENTFUL_ACCESS_TOKEN=...`, `CLOUDFLARE_API_TOKEN=...`, or `ALIYUN_ACCESS_KEY_ID=...` / `ALIYUN_ACCESS_KEY_SECRET=...` (with an optional `ALIYUN_DNS_DOMAIN=libs.websoft9.cn`) +- provider-specific token files live under `.secrets/`, for example `.secrets/contentful.env`, `.secrets/cloudflare.env`, and `.secrets/dns.env` (gitignored) +- `make connector` also writes cloud-provider credential files (`.secrets/aliyun.env`, `.secrets/aws.env`, `.secrets/azure.env`) for `alibabacloud`, `aws`, and `azure` +- each provider file stores the token directly as a standard env var, e.g. `CONTENTFUL_ACCESS_TOKEN=...`, `CLOUDFLARE_API_TOKEN=...`, or `DNS_PROVIDER=aliyun` / `DNS_KEY_ID=...` / `DNS_KEY_SECRET=...` (with an optional `DNS_DOMAIN=libs.websoft9.cn`); `DNS_PROVIDER` defaults to `aliyun`, the only DNS provider implemented today - a command may accept a per-invocation token flag (e.g. `--token`) and an explicit provider env file path (e.g. `--env-file`) as overrides - resolution order: command flag > explicit `--env-file` > environment variable > default provider file - CI keeps passing secrets as environment variables from GitHub Actions secrets; it does not use `.secrets/` diff --git a/cli/libs/__pycache__/app.cpython-312.pyc b/cli/libs/__pycache__/app.cpython-312.pyc index 9fc6ce212..2c285d575 100644 Binary files a/cli/libs/__pycache__/app.cpython-312.pyc and b/cli/libs/__pycache__/app.cpython-312.pyc differ diff --git a/cli/libs/__pycache__/app_tests.cpython-312.pyc b/cli/libs/__pycache__/app_tests.cpython-312.pyc index 2df3e2d98..796c45fe4 100644 Binary files a/cli/libs/__pycache__/app_tests.cpython-312.pyc and b/cli/libs/__pycache__/app_tests.cpython-312.pyc differ diff --git a/cli/libs/__pycache__/credentials.cpython-312.pyc b/cli/libs/__pycache__/credentials.cpython-312.pyc index 0a8e647d0..9f74485ab 100644 Binary files a/cli/libs/__pycache__/credentials.cpython-312.pyc and b/cli/libs/__pycache__/credentials.cpython-312.pyc differ diff --git a/cli/libs/__pycache__/main.cpython-312.pyc b/cli/libs/__pycache__/main.cpython-312.pyc index f2e4f22f3..d4dbfdf99 100644 Binary files a/cli/libs/__pycache__/main.cpython-312.pyc and b/cli/libs/__pycache__/main.cpython-312.pyc differ diff --git a/cli/libs/aliyun_ecs.py b/cli/libs/aliyun_ecs.py new file mode 100644 index 000000000..ca2179eee --- /dev/null +++ b/cli/libs/aliyun_ecs.py @@ -0,0 +1,313 @@ +from __future__ import annotations + +import json +import random +import re +import time +from datetime import datetime, timedelta, timezone +from pathlib import Path + +from libs import aliyun_rpc, credentials +from libs.repo import repo_path + +ECS_VERSION = "2014-05-26" +ECS_ENDPOINT = "https://ecs.aliyuncs.com/" +DEFAULT_CONFIG = "ci/cloud/aliyun-ecs.json" +DEFAULT_NAME_PREFIX = "libs-test" +DEFAULT_WAIT_TIMEOUT = 180 +POLL_INTERVAL = 5 +PROVIDER = "aliyun" +ACCESS_KEY_ID_ENV = "ALIYUN_ACCESS_KEY_ID" +ACCESS_KEY_SECRET_ENV = "ALIYUN_ACCESS_KEY_SECRET" +PAGE_SIZE = 100 + +_DURATION_RE = re.compile(r"^\s*(\d+)\s*([smhd]?)\s*$", re.IGNORECASE) + + +class EcsError(RuntimeError): + pass + + +def config_path(explicit: str | None = None) -> Path: + if explicit: + path = Path(explicit) + if not path.is_absolute(): + path = repo_path(explicit) + return path + return repo_path(DEFAULT_CONFIG) + + +def load_config(explicit: str | None = None) -> dict: + path = config_path(explicit) + if not path.exists(): + raise EcsError(f"config not found: {path}") + try: + data = json.loads(path.read_text(encoding="utf-8")) + except ValueError as error: + raise EcsError(f"invalid JSON in {path}: {error}") from error + if not isinstance(data, dict): + raise EcsError(f"config must be a JSON object: {path}") + data["_config_path"] = str(path) + return data + + +def resolve_credentials( + access_key_id: str | None = None, + access_key_secret: str | None = None, + env_file: str | None = None, +) -> tuple[str | None, str | None]: + return ( + credentials.resolve_secret(ACCESS_KEY_ID_ENV, PROVIDER, access_key_id, env_file), + credentials.resolve_secret(ACCESS_KEY_SECRET_ENV, PROVIDER, access_key_secret, env_file), + ) + + +def disk_bounds(config: dict, disk_size_gib: int | None = None) -> tuple[int | None, int | None]: + disk = config.get("system_disk") or {} + return disk.get("min_size_gib"), disk.get("max_size_gib") + + +def default_disk_size(config: dict) -> int | None: + return (config.get("system_disk") or {}).get("default_size_gib") + + +def validate_disk_size(config: dict, disk_size_gib: int) -> None: + low, high = disk_bounds(config) + if low is not None and disk_size_gib < int(low): + raise EcsError(f"disk size {disk_size_gib} GiB is below the minimum {low} GiB") + if high is not None and disk_size_gib > int(high): + raise EcsError(f"disk size {disk_size_gib} GiB is above the maximum {high} GiB") + + +def release_hours(config: dict) -> tuple[int, int, int]: + release = config.get("release") or {} + low = int(release.get("min_hours", 1)) + high = int(release.get("max_hours", 168)) + default = int(release.get("default_hours", low)) + return low, high, default + + +def parse_duration(value: str) -> timedelta: + match = _DURATION_RE.match(str(value)) + if not match: + raise EcsError(f"invalid duration {value!r}; use e.g. 90m, 10h, 2d") + amount = int(match.group(1)) + unit = (match.group(2) or "h").lower() + if amount <= 0: + raise EcsError(f"duration must be positive: {value!r}") + factors = {"s": 1, "m": 60, "h": 3600, "d": 86400} + return timedelta(seconds=amount * factors[unit]) + + +def auto_release_iso(duration: timedelta, now: datetime | None = None) -> str: + base = now or datetime.now(timezone.utc) + return (base + duration).astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") + + +def _call(action: str, params: dict, key_id: str, key_secret: str, endpoint: str = ECS_ENDPOINT) -> dict: + try: + return aliyun_rpc.rpc_call( + action, + params, + key_id, + key_secret, + version=ECS_VERSION, + endpoint=endpoint, + label="Aliyun ECS", + ) + except aliyun_rpc.AliyunApiError as error: + raise EcsError(str(error)) from error + + +def list_marketplace_images( + region: str, + key_id: str, + key_secret: str, + *, + owner_alias: str = "marketplace", + name_keyword: str | None = None, + endpoint: str = ECS_ENDPOINT, +) -> list[dict]: + images: list[dict] = [] + page = 1 + while True: + params: dict[str, object] = { + "RegionId": region, + "ImageOwnerAlias": owner_alias, + "PageNumber": page, + "PageSize": PAGE_SIZE, + } + if name_keyword: + params["ImageName"] = name_keyword + payload = _call("DescribeImages", params, key_id, key_secret, endpoint) + chunk = (payload.get("Images") or {}).get("Image") or [] + images.extend(item for item in chunk if isinstance(item, dict)) + total = int(payload.get("TotalCount") or len(images)) + if not chunk or len(images) >= total: + break + page += 1 + return images + + +def select_latest(images: list[dict]) -> dict | None: + if not images: + return None + return max(images, key=lambda item: (str(item.get("CreationTime") or ""), str(item.get("ImageId") or ""))) + + +def resolve_image( + config: dict, + *, + image_id: str | None = None, + key_id: str | None = None, + key_secret: str | None = None, + endpoint: str = ECS_ENDPOINT, +) -> dict: + if image_id: + return {"image_id": image_id, "image_name": None, "product_code": None, "source": "explicit"} + + image_cfg = config.get("image") or {} + product_code = image_cfg.get("product_code") + if not product_code: + raise EcsError("config image.product_code is required unless --image-id is given") + if not key_id or not key_secret: + raise EcsError("missing Aliyun credentials; run `make connector` and choose alibabacloud, or set ALIYUN_ACCESS_KEY_ID / ALIYUN_ACCESS_KEY_SECRET") + + images = list_marketplace_images( + config["region"], + key_id, + key_secret, + owner_alias=image_cfg.get("owner_alias", "marketplace"), + name_keyword=image_cfg.get("name_keyword"), + endpoint=endpoint, + ) + matches = [item for item in images if str(item.get("ProductCode") or "").lower() == str(product_code).lower()] + chosen = select_latest(matches) if image_cfg.get("select", "latest") == "latest" else (matches[0] if matches else None) + if not chosen: + raise EcsError( + f"no available marketplace image found for product {product_code} in {config['region']}" + ) + return { + "image_id": chosen.get("ImageId"), + "image_name": chosen.get("ImageName"), + "product_code": product_code, + "subscribed": chosen.get("IsSubscribed"), + "source": "marketplace", + } + + +def generate_instance_name(prefix: str | None = None) -> str: + return f"{prefix or DEFAULT_NAME_PREFIX}-{random.randint(0, 999999):06d}" + + +def build_run_instances_params( + config: dict, + image: dict, + *, + disk_size_gib: int, + auto_release_time: str | None = None, + name: str | None = None, +) -> dict: + instance = config.get("instance") or {} + disk = config.get("system_disk") or {} + network = config.get("network") or {} + + params: dict[str, object] = { + "RegionId": config["region"], + "InstanceName": name or generate_instance_name(instance.get("name_prefix")), + "ImageId": image["image_id"], + "InstanceType": instance.get("type"), + "SecurityGroupId": network.get("security_group_id"), + "VSwitchId": network.get("vswitch_id"), + "InternetMaxBandwidthOut": instance.get("internet_max_bandwidth_out", 0), + "KeyPairName": instance.get("key_pair_name"), + "SystemDisk.Category": disk.get("category", "cloud_essd"), + "SystemDisk.Size": disk_size_gib, + "Amount": 1, + } + spot_strategy = instance.get("spot_strategy") + if spot_strategy: + params["SpotStrategy"] = spot_strategy + params["SpotDuration"] = instance.get("spot_duration", 0) + if auto_release_time: + params["AutoReleaseTime"] = auto_release_time + return {key: value for key, value in params.items() if value is not None} + + +def run_instances( + params: dict, + key_id: str, + key_secret: str, + endpoint: str = ECS_ENDPOINT, +) -> dict: + payload = _call("RunInstances", params, key_id, key_secret, endpoint) + instance_ids = (payload.get("InstanceIdSets") or {}).get("InstanceIdSet") or [] + return { + "request_id": payload.get("RequestId"), + "instance_ids": instance_ids, + } + + +def describe_instance( + instance_id: str, + key_id: str, + key_secret: str, + region: str, + endpoint: str = ECS_ENDPOINT, +) -> dict | None: + payload = _call( + "DescribeInstances", + {"RegionId": region, "InstanceIds": json.dumps([instance_id])}, + key_id, + key_secret, + endpoint, + ) + instances = (payload.get("Instances") or {}).get("Instance") or [] + return instances[0] if instances else None + + +def public_ips(instance: dict) -> list[str]: + public = (instance.get("PublicIpAddress") or {}).get("IpAddress") or [] + if isinstance(public, str): + public = [public] + ips = [ip for ip in public if ip] + eip = (instance.get("EipAddress") or {}).get("IpAddress") + if eip and eip not in ips: + ips.append(eip) + return ips + + +def wait_for_public_ip( + instance_id: str, + key_id: str, + key_secret: str, + region: str, + *, + timeout: int = DEFAULT_WAIT_TIMEOUT, + interval: int = POLL_INTERVAL, + endpoint: str = ECS_ENDPOINT, +) -> dict: + deadline = time.monotonic() + max(timeout, 0) + last: dict | None = None + while True: + instance = describe_instance(instance_id, key_id, key_secret, region, endpoint) + if instance: + last = instance + ips = public_ips(instance) + if ips: + return { + "instance_id": instance_id, + "public_ip": ips[0], + "public_ips": ips, + "status": instance.get("Status"), + "pending": False, + } + if time.monotonic() >= deadline: + return { + "instance_id": instance_id, + "public_ip": None, + "public_ips": [], + "status": (last or {}).get("Status"), + "pending": True, + } + time.sleep(interval) diff --git a/cli/libs/aliyun_rpc.py b/cli/libs/aliyun_rpc.py new file mode 100644 index 000000000..4ef2d60d2 --- /dev/null +++ b/cli/libs/aliyun_rpc.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import base64 +import hashlib +import hmac +import uuid +from datetime import datetime, timezone +from urllib.parse import quote + +from libs import http + + +class AliyunApiError(RuntimeError): + def __init__( + self, + action: str, + code: object, + message: str, + status_code: int | None = None, + label: str = "Aliyun", + ) -> None: + self.action = action + self.code = code + self.message = message + self.status_code = status_code + super().__init__(f"{label} {action} failed: {code} {message}".strip()) + + +def percent_encode(value: object) -> str: + return quote(str(value), safe="") + + +def sign(params: dict[str, str], access_key_secret: str) -> str: + canonical = "&".join( + f"{percent_encode(key)}={percent_encode(value)}" for key, value in sorted(params.items()) + ) + string_to_sign = "GET&%2F&" + percent_encode(canonical) + digest = hmac.new( + (access_key_secret + "&").encode("utf-8"), + string_to_sign.encode("utf-8"), + hashlib.sha1, + ).digest() + return base64.b64encode(digest).decode("utf-8") + + +def signed_params( + action: str, + params: dict[str, object], + access_key_id: str, + access_key_secret: str, + version: str, +) -> dict[str, str]: + merged: dict[str, str] = { + "Format": "JSON", + "Version": version, + "AccessKeyId": access_key_id, + "SignatureMethod": "HMAC-SHA1", + "SignatureVersion": "1.0", + "SignatureNonce": str(uuid.uuid4()), + "Timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + "Action": action, + } + for key, value in params.items(): + if value is not None: + merged[key] = str(value) + merged["Signature"] = sign(merged, access_key_secret) + return merged + + +def rpc_call( + action: str, + params: dict[str, object], + access_key_id: str, + access_key_secret: str, + *, + version: str, + endpoint: str, + label: str = "Aliyun", +) -> dict: + response = http.get( + endpoint, + params=signed_params(action, params, access_key_id, access_key_secret, version), + ) + try: + payload = response.json() + except ValueError as error: + raise AliyunApiError( + action, + response.status_code, + f"returned a non-JSON response (HTTP {response.status_code})", + response.status_code, + label, + ) from error + if not isinstance(payload, dict): + raise AliyunApiError( + action, + response.status_code, + "returned an unexpected payload", + response.status_code, + label, + ) + if response.status_code >= 400 or payload.get("Code"): + code = payload.get("Code") or response.status_code + message = payload.get("Message") or response.reason + raise AliyunApiError(action, code, message, response.status_code, label) + return payload diff --git a/cli/libs/app.py b/cli/libs/app.py index b2ce9036a..7b0a8a7eb 100644 --- a/cli/libs/app.py +++ b/cli/libs/app.py @@ -1,7 +1,9 @@ from __future__ import annotations +import fcntl import json import shutil +from contextlib import contextmanager from pathlib import Path import typer @@ -113,128 +115,142 @@ def _write_yaml(path: Path, data: dict) -> None: yaml.safe_dump(data, file, sort_keys=False, allow_unicode=True) -def archive_app(app_name: str, reason: str = "owner-retired", dry_run: bool = False) -> dict: - source = app_dir(app_name) - if not source: - raise FileNotFoundError(app_name) +@contextmanager +def _metadata_lock(): + lock_path = repo_path("metadata", ".app-metadata.lock") + lock_path.parent.mkdir(parents=True, exist_ok=True) + with lock_path.open("w", encoding="utf-8") as lock_file: + fcntl.flock(lock_file.fileno(), fcntl.LOCK_EX) + try: + yield + finally: + fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN) - archive_target = repo_path("archive", "apps", app_name) - already_archived = source == archive_target - actions = { - "app": app_name, - "source": relative_repo_path(source), - "target": relative_repo_path(archive_target), - "reason": reason, - "already_archived": already_archived, - "dry_run": dry_run, - } - if already_archived: - return actions - maintenance_path = repo_path("metadata", "maintenance.yaml") - archive_path = repo_path("metadata", "archive.yaml") - maintenance = _read_yaml(maintenance_path) - archive = _read_yaml(archive_path) - - for apps in (maintenance.get("cadence") or {}).values(): - if app_name in (apps or []): - apps.remove(app_name) - for apps in (maintenance.get("update_policy") or {}).values(): - if app_name in (apps or []): - apps.remove(app_name) - frozen = (maintenance.get("lifecycle") or {}).get("frozen") or [] - if app_name in frozen: - frozen.remove(app_name) - - defaults = archive.setdefault("defaults", { - "archive_reason": "owner-retired", - "contentful": {"action": "archive", "production": False}, - }) - archive_apps = archive.setdefault("apps", []) - if app_name not in archive_apps: - archive_apps.append(app_name) - archive_apps.sort() - overrides = archive.setdefault("overrides", {}) - if reason != defaults.get("archive_reason"): - overrides[app_name] = {"archive_reason": reason} - - if dry_run: +def archive_app(app_name: str, reason: str = "owner-retired", dry_run: bool = False) -> dict: + with _metadata_lock(): + source = app_dir(app_name) + if not source: + raise FileNotFoundError(app_name) + + archive_target = repo_path("archive", "apps", app_name) + already_archived = source == archive_target + actions = { + "app": app_name, + "source": relative_repo_path(source), + "target": relative_repo_path(archive_target), + "reason": reason, + "already_archived": already_archived, + "dry_run": dry_run, + } + if already_archived: + return actions + + maintenance_path = repo_path("metadata", "maintenance.yaml") + archive_path = repo_path("metadata", "archive.yaml") + maintenance = _read_yaml(maintenance_path) + archive = _read_yaml(archive_path) + + for apps in (maintenance.get("cadence") or {}).values(): + if app_name in (apps or []): + apps.remove(app_name) + for apps in (maintenance.get("update_policy") or {}).values(): + if app_name in (apps or []): + apps.remove(app_name) + frozen = (maintenance.get("lifecycle") or {}).get("frozen") or [] + if app_name in frozen: + frozen.remove(app_name) + + defaults = archive.setdefault("defaults", { + "archive_reason": "owner-retired", + "contentful": {"action": "archive", "production": False}, + }) + archive_apps = archive.setdefault("apps", []) + if app_name not in archive_apps: + archive_apps.append(app_name) + archive_apps.sort() + overrides = archive.setdefault("overrides", {}) + if reason != defaults.get("archive_reason"): + overrides[app_name] = {"archive_reason": reason} + + if dry_run: + actions["metadata_updated"] = True + return actions + + archive_target.parent.mkdir(parents=True, exist_ok=True) + shutil.move(str(source), str(archive_target)) + _write_yaml(maintenance_path, maintenance) + _write_yaml(archive_path, archive) actions["metadata_updated"] = True return actions - archive_target.parent.mkdir(parents=True, exist_ok=True) - shutil.move(str(source), str(archive_target)) - _write_yaml(maintenance_path, maintenance) - _write_yaml(archive_path, archive) - actions["metadata_updated"] = True - return actions - def restore_app(app_name: str, cadence: str = "monthly", update_policy: str = "patch-minor", dry_run: bool = False) -> dict: - source = repo_path("archive", "apps", app_name) - if not source.exists(): - raise FileNotFoundError(app_name) - target = repo_path("apps", app_name) - if target.exists(): - raise FileExistsError(app_name) - - maintenance_path = repo_path("metadata", "maintenance.yaml") - archive_path = repo_path("metadata", "archive.yaml") - maintenance = _read_yaml(maintenance_path) - archive = _read_yaml(archive_path) - - actions = { - "app": app_name, - "source": relative_repo_path(source), - "target": relative_repo_path(target), - "cadence": cadence, - "update_policy": update_policy, - "dry_run": dry_run, - } + with _metadata_lock(): + source = repo_path("archive", "apps", app_name) + if not source.exists(): + raise FileNotFoundError(app_name) + target = repo_path("apps", app_name) + if target.exists(): + raise FileExistsError(app_name) + + maintenance_path = repo_path("metadata", "maintenance.yaml") + archive_path = repo_path("metadata", "archive.yaml") + maintenance = _read_yaml(maintenance_path) + archive = _read_yaml(archive_path) + + actions = { + "app": app_name, + "source": relative_repo_path(source), + "target": relative_repo_path(target), + "cadence": cadence, + "update_policy": update_policy, + "dry_run": dry_run, + } - archived_apps = archive.get("apps") or [] - overrides = archive.get("overrides") or {} - registered = app_name in archived_apps or app_name in overrides - if not registered: - actions["warning"] = f"{app_name} is not registered in metadata/archive.yaml; directory move only" - else: - archive["apps"] = sorted(a for a in archived_apps if a != app_name) - overrides.pop(app_name, None) - archive["overrides"] = overrides - - cadence_buckets = maintenance.setdefault("cadence", {}) - policy_buckets = maintenance.setdefault("update_policy", {}) - for bucket, apps in cadence_buckets.items(): - if app_name in (apps or []): - apps.remove(app_name) - for bucket, apps in policy_buckets.items(): - if app_name in (apps or []): - apps.remove(app_name) - cadence_buckets.setdefault(cadence, []) - if app_name not in cadence_buckets[cadence]: - cadence_buckets[cadence].append(app_name) - cadence_buckets[cadence].sort() - policy_buckets.setdefault(update_policy, []) - if app_name not in policy_buckets[update_policy]: - policy_buckets[update_policy].append(app_name) - policy_buckets[update_policy].sort() - - lifecycle = maintenance.setdefault("lifecycle", {}) - frozen = lifecycle.get("frozen") or [] - if app_name in frozen: - frozen.remove(app_name) - lifecycle["frozen"] = frozen - - if dry_run: + archived_apps = archive.get("apps") or [] + overrides = archive.get("overrides") or {} + registered = app_name in archived_apps or app_name in overrides + if not registered: + actions["warning"] = f"{app_name} is not registered in metadata/archive.yaml; directory move only" + else: + archive["apps"] = sorted(a for a in archived_apps if a != app_name) + overrides.pop(app_name, None) + archive["overrides"] = overrides + + cadence_buckets = maintenance.setdefault("cadence", {}) + policy_buckets = maintenance.setdefault("update_policy", {}) + for bucket, apps in cadence_buckets.items(): + if app_name in (apps or []): + apps.remove(app_name) + for bucket, apps in policy_buckets.items(): + if app_name in (apps or []): + apps.remove(app_name) + cadence_buckets.setdefault(cadence, []) + if app_name not in cadence_buckets[cadence]: + cadence_buckets[cadence].append(app_name) + cadence_buckets[cadence].sort() + policy_buckets.setdefault(update_policy, []) + if app_name not in policy_buckets[update_policy]: + policy_buckets[update_policy].append(app_name) + policy_buckets[update_policy].sort() + + lifecycle = maintenance.setdefault("lifecycle", {}) + frozen = lifecycle.get("frozen") or [] + if app_name in frozen: + frozen.remove(app_name) + lifecycle["frozen"] = frozen + + if dry_run: + actions["metadata_updated"] = True + return actions + + shutil.move(str(source), str(target)) + _write_yaml(maintenance_path, maintenance) + _write_yaml(archive_path, archive) actions["metadata_updated"] = True return actions - shutil.move(str(source), str(target)) - _write_yaml(maintenance_path, maintenance) - _write_yaml(archive_path, archive) - actions["metadata_updated"] = True - return actions - @app.command("list") def list_apps( diff --git a/cli/libs/app_tests.py b/cli/libs/app_tests.py index d2b58459d..022f3b851 100644 --- a/cli/libs/app_tests.py +++ b/cli/libs/app_tests.py @@ -408,7 +408,9 @@ def run_app_tests( def attempt() -> dict: return run_case(app_name, case, env, resolved_base_url, remote_ctx) - should_retry = case["type"] in {"container-up", "container-healthy", "web-access", "http-basic"} + should_retry = case["type"] in {"container-up", "container-healthy", "web-access", "http-basic"} or ( + remote_ctx is not None and case["type"] == "compose-config" + ) payload = _wait_for( wait_timeout, wait_interval, diff --git a/cli/libs/credentials.py b/cli/libs/credentials.py index 1e198dcfd..95d2ee6fa 100644 --- a/cli/libs/credentials.py +++ b/cli/libs/credentials.py @@ -10,7 +10,10 @@ "contentful": ".secrets/contentful.env", "cloudflare": ".secrets/cloudflare.env", "dockerhub": ".secrets/dockerhub.env", + "dns": ".secrets/dns.env", "aliyun": ".secrets/aliyun.env", + "aws": ".secrets/aws.env", + "azure": ".secrets/azure.env", } diff --git a/cli/libs/dns.py b/cli/libs/dns.py index 6d17dd440..0834c3478 100644 --- a/cli/libs/dns.py +++ b/cli/libs/dns.py @@ -1,18 +1,14 @@ from __future__ import annotations -import base64 -import hashlib -import hmac import shlex -import uuid -from datetime import datetime, timezone from pathlib import Path -from urllib.parse import quote -from libs import credentials, http, remote +from libs import aliyun_rpc, credentials, http, remote +from libs.aliyun_rpc import percent_encode, sign ALIYUN_VERSION = "2015-01-09" -ALIYUN_PRODUCT = "aliyun" +ALIYUN_PROVIDER = "aliyun" +DEFAULT_PROVIDER = ALIYUN_PROVIDER DEFAULT_ENDPOINT = "https://alidns.aliyuncs.com/" DEFAULT_RECORD_TYPE = "A" DEFAULT_TTL = 600 @@ -25,51 +21,18 @@ ContainerContext = tuple[str, str, Path] -ACCESS_KEY_ID_ENV = "ALIYUN_ACCESS_KEY_ID" -ACCESS_KEY_SECRET_ENV = "ALIYUN_ACCESS_KEY_SECRET" -DOMAIN_ENV = "ALIYUN_DNS_DOMAIN" -ENDPOINT_ENV = "ALIYUN_DNS_ENDPOINT" +PROVIDER_KEY = "dns" +PROVIDER_ENV = "DNS_PROVIDER" +ACCESS_KEY_ID_ENV = "DNS_KEY_ID" +ACCESS_KEY_SECRET_ENV = "DNS_KEY_SECRET" +DOMAIN_ENV = "DNS_DOMAIN" +ENDPOINT_ENV = "DNS_ENDPOINT" class DnsError(RuntimeError): pass -def percent_encode(value: object) -> str: - return quote(str(value), safe="") - - -def sign(params: dict[str, str], access_key_secret: str) -> str: - canonical = "&".join( - f"{percent_encode(key)}={percent_encode(value)}" for key, value in sorted(params.items()) - ) - string_to_sign = "GET&%2F&" + percent_encode(canonical) - digest = hmac.new( - (access_key_secret + "&").encode("utf-8"), - string_to_sign.encode("utf-8"), - hashlib.sha1, - ).digest() - return base64.b64encode(digest).decode("utf-8") - - -def signed_params(action: str, params: dict[str, object], access_key_id: str, access_key_secret: str) -> dict[str, str]: - merged: dict[str, str] = { - "Format": "JSON", - "Version": ALIYUN_VERSION, - "AccessKeyId": access_key_id, - "SignatureMethod": "HMAC-SHA1", - "SignatureVersion": "1.0", - "SignatureNonce": str(uuid.uuid4()), - "Timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), - "Action": action, - } - for key, value in params.items(): - if value is not None: - merged[key] = str(value) - merged["Signature"] = sign(merged, access_key_secret) - return merged - - def call( action: str, params: dict[str, object], @@ -79,10 +42,13 @@ def call( ) -> dict: if not access_key_id or not access_key_secret: raise DnsError( - f"missing Aliyun credentials; run `make connector` and choose aliyun, " + f"missing DNS credentials; run `make connector` and choose dns, " f"or set {ACCESS_KEY_ID_ENV} / {ACCESS_KEY_SECRET_ENV}" ) - response = http.get(endpoint or DEFAULT_ENDPOINT, params=signed_params(action, params, access_key_id, access_key_secret)) + response = http.get( + endpoint or DEFAULT_ENDPOINT, + params=aliyun_rpc.signed_params(action, params, access_key_id, access_key_secret, ALIYUN_VERSION), + ) try: payload = response.json() except ValueError as error: @@ -124,7 +90,7 @@ def normalize_domain(value: str) -> str: def wildcard_fqdn(domain: str) -> str: name = normalize_domain(domain) if not name: - raise ValueError("domain is required; pass --domain or set ALIYUN_DNS_DOMAIN") + raise ValueError(f"domain is required; pass --domain or set {DOMAIN_ENV}") if name.startswith("*."): return name return "*." + name @@ -208,17 +174,26 @@ def resolve_credentials( env_file: str | None = None, ) -> tuple[str | None, str | None]: return ( - credentials.resolve_secret(ACCESS_KEY_ID_ENV, ALIYUN_PRODUCT, access_key_id, env_file), - credentials.resolve_secret(ACCESS_KEY_SECRET_ENV, ALIYUN_PRODUCT, access_key_secret, env_file), + credentials.resolve_secret(ACCESS_KEY_ID_ENV, PROVIDER_KEY, access_key_id, env_file), + credentials.resolve_secret(ACCESS_KEY_SECRET_ENV, PROVIDER_KEY, access_key_secret, env_file), ) def resolve_domain(explicit: str | None = None, env_file: str | None = None) -> str | None: - return credentials.resolve_secret(DOMAIN_ENV, ALIYUN_PRODUCT, explicit, env_file) + return credentials.resolve_secret(DOMAIN_ENV, PROVIDER_KEY, explicit, env_file) + + +def resolve_provider(explicit: str | None = None, env_file: str | None = None) -> str: + return credentials.resolve_secret(PROVIDER_ENV, PROVIDER_KEY, explicit, env_file) or DEFAULT_PROVIDER + + +def ensure_supported_provider(provider: str) -> None: + if provider != ALIYUN_PROVIDER: + raise DnsError(f"unsupported DNS provider {provider!r}; only {ALIYUN_PROVIDER} is implemented") def resolve_endpoint(explicit: str | None = None, env_file: str | None = None) -> str: - return credentials.resolve_secret(ENDPOINT_ENV, ALIYUN_PRODUCT, explicit, env_file) or DEFAULT_ENDPOINT + return credentials.resolve_secret(ENDPOINT_ENV, PROVIDER_KEY, explicit, env_file) or DEFAULT_ENDPOINT def resolve_target_ip(target: str | None = None, ip: str | None = None, ssh_host: str | None = None) -> str: @@ -319,9 +294,10 @@ def _bind_payload( action: str, record_id: str | None, previous: str | None, + provider: str = ALIYUN_PROVIDER, ) -> dict: return { - "provider": ALIYUN_PRODUCT, + "provider": provider, "action": action, "domain": normalize_domain(domain or ""), "fqdn": fqdn, @@ -348,10 +324,11 @@ def _bind_existing( key_id: str, key_secret: str, endpoint: str, + provider: str = ALIYUN_PROVIDER, ) -> dict: current = record.get("Value") if current is not None and str(current).strip() == str(value).strip(): - return _bind_payload(domain, fqdn, zone, rr, record_type, ttl, value, "unchanged", record.get("RecordId"), current) + return _bind_payload(domain, fqdn, zone, rr, record_type, ttl, value, "unchanged", record.get("RecordId"), current, provider) try: result = call( @@ -376,12 +353,12 @@ def _bind_existing( for item in find_records(zone, rr, record_type, key_id, key_secret, endpoint=endpoint): if str(item.get("Value", "")).strip() == str(value).strip(): return _bind_payload( - domain, fqdn, zone, rr, record_type, ttl, value, "unchanged", item.get("RecordId"), item.get("Value") + domain, fqdn, zone, rr, record_type, ttl, value, "unchanged", item.get("RecordId"), item.get("Value"), provider ) raise return _bind_payload( - domain, fqdn, zone, rr, record_type, ttl, value, "updated", record.get("RecordId") or result.get("RecordId"), current + domain, fqdn, zone, rr, record_type, ttl, value, "updated", record.get("RecordId") or result.get("RecordId"), current, provider ) @@ -396,6 +373,8 @@ def bind( env_file: str | None = None, ) -> dict: domain = resolve_domain(domain, env_file) + provider = resolve_provider(env_file=env_file) + ensure_supported_provider(provider) fqdn = wildcard_fqdn(domain or "") key_id, key_secret = resolve_credentials(access_key_id, access_key_secret, env_file) api_endpoint = resolve_endpoint(endpoint, env_file) @@ -415,6 +394,7 @@ def bind( "key_id": key_id or "", "key_secret": key_secret or "", "endpoint": api_endpoint, + "provider": provider, } if records: @@ -446,7 +426,7 @@ def bind( return _bind_existing(existing[0], **shared) return _bind_payload( - domain, fqdn, zone, rr, record_type, ttl, value, "created", result.get("RecordId"), None + domain, fqdn, zone, rr, record_type, ttl, value, "created", result.get("RecordId"), None, provider ) @@ -459,6 +439,8 @@ def delete( env_file: str | None = None, ) -> dict: domain = resolve_domain(domain, env_file) + provider = resolve_provider(env_file=env_file) + ensure_supported_provider(provider) fqdn = wildcard_fqdn(domain or "") key_id, key_secret = resolve_credentials(access_key_id, access_key_secret, env_file) api_endpoint = resolve_endpoint(endpoint, env_file) @@ -478,7 +460,7 @@ def delete( endpoint=api_endpoint, ) return { - "provider": ALIYUN_PRODUCT, + "provider": provider, "action": "deleted", "domain": normalize_domain(domain or ""), "fqdn": fqdn, diff --git a/cli/libs/main.py b/cli/libs/main.py index a7a1dcd20..2871c999e 100644 --- a/cli/libs/main.py +++ b/cli/libs/main.py @@ -8,7 +8,7 @@ from rich.table import Table from libs import app as app_ops -from libs import app_build, app_deploy, app_tests, appstore_sync, catalog, contentful, dblifecycle, dns, drift, http, imagestats, maintenance, newapp, readme, remote, validate, versions, websoft9_upgrade +from libs import app_build, app_deploy, app_tests, appstore_sync, catalog, contentful, dblifecycle, drift, http, imagestats, maintenance, newapp, readme, remote, validate, versions from libs.metadata import app_dir from libs.output import print_output @@ -47,7 +47,7 @@ def proxy_command( def help_command(ctx: typer.Context) -> None: """Show help for libs. Same as libs --help.""" typer.echo(ctx.parent.get_help()) - typer.echo("\nLocal by default; remote-aware commands read defaults from .secrets/remote.env (TARGET, SSH_HOST, SSH_USER, SSH_SECRET_PATH, DEPLOY_ROOT, CONTAINER). Current remote-aware commands: app-deploy, app-build, app-down, app-tests, appstore-sync, appstore-deploy, websoft9-upgrade, dns-bind.") + typer.echo("\nLocal by default; remote-aware commands read defaults from .secrets/remote.env (TARGET, SSH_HOST, SSH_USER, SSH_SECRET_PATH, DEPLOY_ROOT, CONTAINER). Current remote-aware commands: app-deploy, app-build, app-down, app-tests, appstore-sync, appstore-deploy.") @app.command("list") @@ -761,135 +761,6 @@ def appstore_deploy_command( raise typer.Exit(code=1) -@app.command("websoft9-upgrade") -def websoft9_upgrade_command( - container: str | None = typer.Option(None, "--container", help="Websoft9 container name (default: CONTAINER in .secrets/remote.env, else websoft9)"), - tag: str = typer.Option(websoft9_upgrade.DEFAULT_TAG, "--tag", help="Image tag to set (default: dev)"), - tag_var: str = typer.Option(websoft9_upgrade.DEFAULT_TAG_VAR, "--tag-var", help="Env variable holding the image tag"), - compose_dir: str | None = typer.Option(None, "--compose-dir", help="Compose project directory; discovered from container labels when omitted"), - target: str | None = typer.Option(None, "--target", help="local | remote"), - ssh_host: str | None = typer.Option(None, "--ssh-host", help="Remote host IP or name"), - ssh_user: str | None = typer.Option(None, "--ssh-user", help="Remote SSH user (default root)"), - ssh_secret_path: str | None = typer.Option(None, "--ssh-secret-path", help="SSH secret path (key or password file)"), - progress: bool = typer.Option(False, "--progress", help="Show step progress on stderr"), - verbose: bool = typer.Option(False, "--verbose", help="Show step progress and raw subprocess output on stderr"), - as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), -) -> None: - """Upgrade the Websoft9 platform container: set its image tag, pull, and recreate it.""" - try: - progress_writer = (lambda message: typer.echo(message, err=True)) if (progress or verbose) else None - payload = websoft9_upgrade.upgrade( - container=container, - tag=tag, - tag_var=tag_var, - compose_dir=compose_dir, - target=target, - ssh_host=ssh_host, - ssh_user=ssh_user, - ssh_secret_path=ssh_secret_path, - progress=progress_writer, - verbose=verbose, - ) - except FileNotFoundError as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=4) - except ValueError as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=2) - except Exception as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=1) - print_output(payload, as_json) - - -@app.command("dns-bind") -def dns_bind_command( - domain: str | None = typer.Option(None, "--domain", help="Wildcard base domain, e.g. libs.websoft9.cn; defaults to ALIYUN_DNS_DOMAIN"), - target: str | None = typer.Option(None, "--target", help="local | remote; defaults to TARGET in .secrets/remote.env"), - ip: str | None = typer.Option(None, "--ip", help="Explicit IPv4 value; overrides target resolution"), - ssh_host: str | None = typer.Option(None, "--ssh-host", help="Remote host; overrides SSH_HOST in .secrets/remote.env"), - ssh_user: str | None = typer.Option(None, "--ssh-user", help="Remote SSH user (default root)"), - ssh_secret_path: str | None = typer.Option(None, "--ssh-secret-path", help="SSH secret path (key or password file)"), - container: str | None = typer.Option(None, "--container", help="Websoft9 container name (default: CONTAINER in .secrets/remote.env, else websoft9)"), - no_container: bool = typer.Option(False, "--no-container", help="Skip the optional Websoft9 container domain binding"), - record_type: str = typer.Option(dns.DEFAULT_RECORD_TYPE, "--type", help="DNS record type"), - ttl: int = typer.Option(dns.DEFAULT_TTL, "--ttl", help="Record TTL in seconds"), - access_key_id: str | None = typer.Option(None, "--access-key-id", help="Aliyun AccessKey ID; overrides connector/env value"), - access_key_secret: str | None = typer.Option(None, "--access-key-secret", help="Aliyun AccessKey Secret; overrides connector/env value"), - endpoint: str | None = typer.Option(None, "--endpoint", help="Aliyun DNS API endpoint; overrides ALIYUN_DNS_ENDPOINT"), - env_file: str | None = typer.Option(None, "--env-file", help="Aliyun env file; overrides default .secrets/aliyun.env"), - as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), -) -> None: - """Point the wildcard record (*.) at the remote host or localhost, updating it when present. - - When the Websoft9 container is reachable it also sets its wildcard_domain config; otherwise it skips silently. - """ - try: - resolved_domain = dns.resolve_domain(domain, env_file) - payload = dns.bind( - domain=resolved_domain, - value=dns.resolve_target_ip(target=target, ip=ip, ssh_host=ssh_host), - access_key_id=access_key_id, - access_key_secret=access_key_secret, - record_type=record_type, - ttl=ttl, - endpoint=endpoint, - env_file=env_file, - ) - except FileNotFoundError as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=4) - except (ValueError, dns.DnsError) as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=2) - except Exception as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=1) - - if not no_container: - payload["container_config"] = dns.configure_container( - resolved_domain, - target=target, - container=container, - ssh_host=ssh_host, - ssh_user=ssh_user, - ssh_secret_path=ssh_secret_path, - ) - print_output(payload, as_json) - - -@app.command("dns-delete") -def dns_delete_command( - domain: str | None = typer.Option(None, "--domain", help="Wildcard base domain, e.g. libs.websoft9.cn; defaults to ALIYUN_DNS_DOMAIN"), - record_type: str = typer.Option(dns.DEFAULT_RECORD_TYPE, "--type", help="DNS record type"), - access_key_id: str | None = typer.Option(None, "--access-key-id", help="Aliyun AccessKey ID; overrides connector/env value"), - access_key_secret: str | None = typer.Option(None, "--access-key-secret", help="Aliyun AccessKey Secret; overrides connector/env value"), - endpoint: str | None = typer.Option(None, "--endpoint", help="Aliyun DNS API endpoint; overrides ALIYUN_DNS_ENDPOINT"), - env_file: str | None = typer.Option(None, "--env-file", help="Aliyun env file; overrides default .secrets/aliyun.env"), - as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), -) -> None: - """Delete the single wildcard record (*.) managed for the domain.""" - try: - payload = dns.delete( - domain=dns.resolve_domain(domain, env_file), - access_key_id=access_key_id, - access_key_secret=access_key_secret, - record_type=record_type, - endpoint=endpoint, - env_file=env_file, - ) - except FileNotFoundError as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=4) - except (ValueError, dns.DnsError) as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=2) - except Exception as error: - typer.echo(str(error), err=True) - raise typer.Exit(code=1) - print_output(payload, as_json) - - @app.command("app-tests") def app_tests_command( app_name: str = typer.Option(..., "--app", help="App name"), diff --git a/cli/libs/ops.py b/cli/libs/ops.py new file mode 100644 index 000000000..96d25edc6 --- /dev/null +++ b/cli/libs/ops.py @@ -0,0 +1,286 @@ +from __future__ import annotations + +from datetime import timedelta + +import typer + +from libs import aliyun_ecs, dns, http, websoft9_upgrade +from libs.output import print_output + +HELP_OPTIONS = {"help_option_names": ["-h", "--help"]} + +app = typer.Typer(name="libs-ops", help="docker-library make-level operations", context_settings=HELP_OPTIONS) + + +@app.callback() +def main_callback( + proxy: str | None = typer.Option(None, "--proxy", help="Proxy URL for network calls, e.g. socks5h://127.0.0.1:1089"), +) -> None: + http.normalize_proxy_env(proxy) + + +@app.command("websoft9-upgrade") +def websoft9_upgrade_command( + container: str | None = typer.Option(None, "--container", help="Websoft9 container name (default: CONTAINER in .secrets/remote.env, else websoft9)"), + tag: str = typer.Option(websoft9_upgrade.DEFAULT_TAG, "--tag", help="Image tag to set (default: dev)"), + tag_var: str = typer.Option(websoft9_upgrade.DEFAULT_TAG_VAR, "--tag-var", help="Env variable holding the image tag"), + compose_dir: str | None = typer.Option(None, "--compose-dir", help="Compose project directory; discovered from container labels when omitted"), + target: str | None = typer.Option(None, "--target", help="local | remote"), + ssh_host: str | None = typer.Option(None, "--ssh-host", help="Remote host IP or name"), + ssh_user: str | None = typer.Option(None, "--ssh-user", help="Remote SSH user (default root)"), + ssh_secret_path: str | None = typer.Option(None, "--ssh-secret-path", help="SSH secret path (key or password file)"), + progress: bool = typer.Option(False, "--progress", help="Show step progress on stderr"), + verbose: bool = typer.Option(False, "--verbose", help="Show step progress and raw subprocess output on stderr"), + as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), +) -> None: + """Upgrade the Websoft9 platform container: set its image tag, pull, and recreate it.""" + try: + progress_writer = (lambda message: typer.echo(message, err=True)) if (progress or verbose) else None + payload = websoft9_upgrade.upgrade( + container=container, + tag=tag, + tag_var=tag_var, + compose_dir=compose_dir, + target=target, + ssh_host=ssh_host, + ssh_user=ssh_user, + ssh_secret_path=ssh_secret_path, + progress=progress_writer, + verbose=verbose, + ) + except FileNotFoundError as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=4) + except ValueError as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=2) + except Exception as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=1) + print_output(payload, as_json) + + +@app.command("dns-bind") +def dns_bind_command( + domain: str | None = typer.Option(None, "--domain", help="Wildcard base domain, e.g. libs.websoft9.cn; defaults to DNS_DOMAIN"), + target: str | None = typer.Option(None, "--target", help="local | remote; defaults to TARGET in .secrets/remote.env"), + ip: str | None = typer.Option(None, "--ip", help="Explicit IPv4 value; overrides target resolution"), + ssh_host: str | None = typer.Option(None, "--ssh-host", help="Remote host; overrides SSH_HOST in .secrets/remote.env"), + ssh_user: str | None = typer.Option(None, "--ssh-user", help="Remote SSH user (default root)"), + ssh_secret_path: str | None = typer.Option(None, "--ssh-secret-path", help="SSH secret path (key or password file)"), + container: str | None = typer.Option(None, "--container", help="Websoft9 container name (default: CONTAINER in .secrets/remote.env, else websoft9)"), + no_container: bool = typer.Option(False, "--no-container", help="Skip the optional Websoft9 container domain binding"), + record_type: str = typer.Option(dns.DEFAULT_RECORD_TYPE, "--type", help="DNS record type"), + ttl: int = typer.Option(dns.DEFAULT_TTL, "--ttl", help="Record TTL in seconds"), + access_key_id: str | None = typer.Option(None, "--access-key-id", "--key-id", help="DNS key id; overrides connector/env value"), + access_key_secret: str | None = typer.Option(None, "--access-key-secret", "--key-secret", help="DNS key secret; overrides connector/env value"), + endpoint: str | None = typer.Option(None, "--endpoint", help="DNS API endpoint; overrides DNS_ENDPOINT"), + env_file: str | None = typer.Option(None, "--env-file", help="DNS env file; overrides default .secrets/dns.env"), + as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), +) -> None: + """Point the wildcard record (*.) at the remote host or localhost, updating it when present. + + When the Websoft9 container is reachable it also sets its wildcard_domain config; otherwise it skips silently. + """ + try: + resolved_domain = dns.resolve_domain(domain, env_file) + payload = dns.bind( + domain=resolved_domain, + value=dns.resolve_target_ip(target=target, ip=ip, ssh_host=ssh_host), + access_key_id=access_key_id, + access_key_secret=access_key_secret, + record_type=record_type, + ttl=ttl, + endpoint=endpoint, + env_file=env_file, + ) + except FileNotFoundError as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=4) + except (ValueError, dns.DnsError) as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=2) + except Exception as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=1) + + if not no_container: + payload["container_config"] = dns.configure_container( + resolved_domain, + target=target, + container=container, + ssh_host=ssh_host, + ssh_user=ssh_user, + ssh_secret_path=ssh_secret_path, + ) + print_output(payload, as_json) + + +@app.command("dns-delete") +def dns_delete_command( + domain: str | None = typer.Option(None, "--domain", help="Wildcard base domain, e.g. libs.websoft9.cn; defaults to DNS_DOMAIN"), + record_type: str = typer.Option(dns.DEFAULT_RECORD_TYPE, "--type", help="DNS record type"), + access_key_id: str | None = typer.Option(None, "--access-key-id", "--key-id", help="DNS key id; overrides connector/env value"), + access_key_secret: str | None = typer.Option(None, "--access-key-secret", "--key-secret", help="DNS key secret; overrides connector/env value"), + endpoint: str | None = typer.Option(None, "--endpoint", help="DNS API endpoint; overrides DNS_ENDPOINT"), + env_file: str | None = typer.Option(None, "--env-file", help="DNS env file; overrides default .secrets/dns.env"), + as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), +) -> None: + """Delete the single wildcard record (*.) managed for the domain.""" + try: + payload = dns.delete( + domain=dns.resolve_domain(domain, env_file), + access_key_id=access_key_id, + access_key_secret=access_key_secret, + record_type=record_type, + endpoint=endpoint, + env_file=env_file, + ) + except FileNotFoundError as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=4) + except (ValueError, dns.DnsError) as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=2) + except Exception as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=1) + print_output(payload, as_json) + + +def _prompt_int_range(prompt: str, *, default: int | None, minimum: int, maximum: int) -> int: + default = minimum if default is None else default + while True: + raw = typer.prompt(prompt, default=default) + try: + value = int(str(raw).strip()) + except ValueError: + typer.echo("Please enter an integer.", err=True) + continue + if value < minimum or value > maximum: + typer.echo(f"Please enter a value between {minimum} and {maximum}.", err=True) + continue + return value + + +@app.command("create-aliyun-ecs") +def create_aliyun_ecs_command( + disk_size: int | None = typer.Option(None, "--disk-size", help="System disk size in GiB; prompted when omitted"), + release_in: str | None = typer.Option(None, "--release-in", help="Auto-release after this duration (e.g. 10h, 90m, 2d)"), + release_at: str | None = typer.Option(None, "--release-at", help="Absolute auto-release time in UTC (e.g. 2026-10-13T11:19:00Z)"), + name: str | None = typer.Option(None, "--name", help="Instance name; defaults to the config value"), + image_id: str | None = typer.Option(None, "--image-id", help="Use a specific image instead of resolving the marketplace product"), + config: str | None = typer.Option(None, "--config", help="Config file; defaults to ci/cloud/aliyun-ecs.json"), + env_file: str | None = typer.Option(None, "--env-file", help="Aliyun env file; defaults to .secrets/aliyun.env"), + assume_yes: bool = typer.Option(False, "--yes", "-y", help="Skip the confirmation prompt"), + wait_timeout: int = typer.Option(aliyun_ecs.DEFAULT_WAIT_TIMEOUT, "--wait-timeout", help="Seconds to wait for the public IP after creation; 0 disables waiting"), + dry_run: bool = typer.Option(False, "--dry-run", help="Resolve the plan and print it without creating the instance"), + as_json: bool = typer.Option(False, "--json", help="Machine-readable output"), +) -> None: + """Create a pay-as-you-go (spot) Aliyun ECS instance using the fixed config plus interactive disk size and release time.""" + try: + cfg = aliyun_ecs.load_config(config) + low, high = aliyun_ecs.disk_bounds(cfg) + if disk_size is None: + disk_size = _prompt_int_range( + f"System disk size GiB ({low}-{high})", + default=aliyun_ecs.default_disk_size(cfg), + minimum=int(low or 1), + maximum=int(high or 32768), + ) + aliyun_ecs.validate_disk_size(cfg, disk_size) + + rel_low, rel_high, rel_default = aliyun_ecs.release_hours(cfg) + auto_release = release_at + if not auto_release: + if release_in: + duration = aliyun_ecs.parse_duration(release_in) + else: + hours = _prompt_int_range( + f"Auto-release after hours ({rel_low}-{rel_high})", + default=rel_default, + minimum=rel_low, + maximum=rel_high, + ) + duration = timedelta(hours=hours) + auto_release = aliyun_ecs.auto_release_iso(duration) + + key_id, key_secret = aliyun_ecs.resolve_credentials(env_file=env_file) + image = aliyun_ecs.resolve_image(cfg, image_id=image_id, key_id=key_id, key_secret=key_secret) + params = aliyun_ecs.build_run_instances_params( + cfg, image, disk_size_gib=disk_size, auto_release_time=auto_release, name=name + ) + + plan = { + "region": cfg["region"], + "instance_name": params.get("InstanceName"), + "instance_type": params.get("InstanceType"), + "image_id": image.get("image_id"), + "image_name": image.get("image_name"), + "disk_size_gib": disk_size, + "disk_category": params.get("SystemDisk.Category"), + "spot_strategy": params.get("SpotStrategy"), + "auto_release_time": auto_release, + } + + if not assume_yes and not dry_run: + typer.echo("Plan:") + for key in ( + "region", + "instance_name", + "instance_type", + "disk_size_gib", + "disk_category", + "spot_strategy", + "auto_release_time", + ): + typer.echo(f" {key}: {plan[key]}") + typer.echo(f" image: {plan['image_id']} ({plan['image_name'] or image.get('source')})") + if not typer.confirm("Create this instance?"): + typer.echo("Aborted.") + raise typer.Exit(code=0) + + if dry_run: + print_output({**plan, "dry_run": True}, as_json) + return + + result = aliyun_ecs.run_instances(params, key_id or "", key_secret or "") + connection: dict = {} + if result.get("instance_ids") and wait_timeout > 0: + connection = aliyun_ecs.wait_for_public_ip( + result["instance_ids"][0], + key_id or "", + key_secret or "", + cfg["region"], + timeout=wait_timeout, + ) + print_output({**plan, "action": "created", **result, **connection}, as_json) + if not as_json: + if connection.get("public_ip"): + typer.echo(f"server public IP: {connection['public_ip']}", err=True) + elif connection.get("pending"): + typer.echo("warning: public IP not assigned yet; check the console shortly", err=True) + except FileNotFoundError as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=4) + except (ValueError, aliyun_ecs.EcsError) as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=2) + except typer.Exit: + raise + except Exception as error: + typer.echo(str(error), err=True) + raise typer.Exit(code=1) + + +def run() -> int | None: + app.registered_commands.sort(key=lambda item: item.name) + try: + app() + except FileNotFoundError as error: + typer.echo(str(error), err=True) + return 4 + + +if __name__ == "__main__": + run() diff --git a/cli/tests/__pycache__/test_app.cpython-312-pytest-9.1.1.pyc b/cli/tests/__pycache__/test_app.cpython-312-pytest-9.1.1.pyc index 3347ca2c6..bdd3dbd3d 100644 Binary files a/cli/tests/__pycache__/test_app.cpython-312-pytest-9.1.1.pyc and b/cli/tests/__pycache__/test_app.cpython-312-pytest-9.1.1.pyc differ diff --git a/cli/tests/__pycache__/test_app_tests.cpython-312-pytest-9.1.1.pyc b/cli/tests/__pycache__/test_app_tests.cpython-312-pytest-9.1.1.pyc index b86beffe8..ad8181fd4 100644 Binary files a/cli/tests/__pycache__/test_app_tests.cpython-312-pytest-9.1.1.pyc and b/cli/tests/__pycache__/test_app_tests.cpython-312-pytest-9.1.1.pyc differ diff --git a/cli/tests/__pycache__/test_credentials.cpython-312-pytest-9.1.1.pyc b/cli/tests/__pycache__/test_credentials.cpython-312-pytest-9.1.1.pyc index e31fdbcd6..d44f36c23 100644 Binary files a/cli/tests/__pycache__/test_credentials.cpython-312-pytest-9.1.1.pyc and b/cli/tests/__pycache__/test_credentials.cpython-312-pytest-9.1.1.pyc differ diff --git a/cli/tests/__pycache__/test_main.cpython-312-pytest-9.1.1.pyc b/cli/tests/__pycache__/test_main.cpython-312-pytest-9.1.1.pyc index fe9178b70..a50dbd3b1 100644 Binary files a/cli/tests/__pycache__/test_main.cpython-312-pytest-9.1.1.pyc and b/cli/tests/__pycache__/test_main.cpython-312-pytest-9.1.1.pyc differ diff --git a/cli/tests/test_aliyun_ecs.py b/cli/tests/test_aliyun_ecs.py new file mode 100644 index 000000000..1735086e0 --- /dev/null +++ b/cli/tests/test_aliyun_ecs.py @@ -0,0 +1,256 @@ +from __future__ import annotations + +import json +import re +from datetime import datetime, timedelta, timezone + +import pytest +from typer.testing import CliRunner + +from libs import aliyun_ecs, ops + + +runner = CliRunner() + + +CONFIG = { + "provider": "aliyun", + "region": "cn-hongkong", + "instance": { + "name_prefix": "libs-test", + "type": "ecs.g7.large", + "spot_strategy": "SpotAsPriceGo", + "spot_duration": 0, + "internet_max_bandwidth_out": 100, + "key_pair_name": "websoft9_auto", + }, + "system_disk": { + "category": "cloud_essd", + "min_size_gib": 20, + "max_size_gib": 500, + "default_size_gib": 200, + }, + "release": {"default_hours": 10, "min_hours": 1, "max_hours": 168}, + "network": { + "security_group_id": "sg-j6c7epgwcech14ofdt5l", + "vswitch_id": "vsw-j6cpor7vbblzas6ui2pkf", + }, + "image": {"owner_alias": "marketplace", "product_code": "cmjj010728", "select": "latest"}, +} + + +def _write_config(repo_fixture) -> None: + (repo_fixture / "ci" / "cloud").mkdir(parents=True) + (repo_fixture / "ci" / "cloud" / "aliyun-ecs.json").write_text( + json.dumps(CONFIG), encoding="utf-8" + ) + + +def test_parse_duration_units(): + assert aliyun_ecs.parse_duration("90m") == timedelta(minutes=90) + assert aliyun_ecs.parse_duration("10h") == timedelta(hours=10) + assert aliyun_ecs.parse_duration("2d") == timedelta(days=2) + assert aliyun_ecs.parse_duration("30") == timedelta(hours=30) + with pytest.raises(aliyun_ecs.EcsError): + aliyun_ecs.parse_duration("soon") + + +def test_auto_release_iso_uses_utc(): + now = datetime(2026, 10, 13, 1, 19, 0, tzinfo=timezone.utc) + assert aliyun_ecs.auto_release_iso(timedelta(hours=10), now=now) == "2026-10-13T11:19:00Z" + + +def test_load_config_reads_repo_default(repo_fixture): + _write_config(repo_fixture) + config = aliyun_ecs.load_config() + assert config["region"] == "cn-hongkong" + assert config["system_disk"]["default_size_gib"] == 200 + + +def test_load_config_rejects_missing(repo_fixture): + with pytest.raises(aliyun_ecs.EcsError, match="config not found"): + aliyun_ecs.load_config() + + +def test_validate_disk_size_bounds(): + aliyun_ecs.validate_disk_size(CONFIG, 200) + with pytest.raises(aliyun_ecs.EcsError, match="below the minimum"): + aliyun_ecs.validate_disk_size(CONFIG, 10) + with pytest.raises(aliyun_ecs.EcsError, match="above the maximum"): + aliyun_ecs.validate_disk_size(CONFIG, 999) + + +def test_resolve_image_selects_latest_product_match(monkeypatch): + images = [ + {"ImageId": "m-old", "ProductCode": "cmjj010728", "ImageName": "old", "CreationTime": "2025-01-01T00:00:00Z"}, + {"ImageId": "m-new", "ProductCode": "cmjj010728", "ImageName": "new", "CreationTime": "2026-10-01T00:00:00Z"}, + {"ImageId": "m-other", "ProductCode": "other0001", "ImageName": "other", "CreationTime": "2027-01-01T00:00:00Z"}, + ] + monkeypatch.setattr(aliyun_ecs, "list_marketplace_images", lambda *args, **kwargs: images) + + image = aliyun_ecs.resolve_image(CONFIG, key_id="id", key_secret="secret") + + assert image["image_id"] == "m-new" + assert image["product_code"] == "cmjj010728" + + +def test_resolve_image_explicit_id_skips_lookup(monkeypatch): + def boom(*args, **kwargs): + raise AssertionError("should not query the API") + + monkeypatch.setattr(aliyun_ecs, "list_marketplace_images", boom) + image = aliyun_ecs.resolve_image(CONFIG, image_id="m-explicit") + assert image == {"image_id": "m-explicit", "image_name": None, "product_code": None, "source": "explicit"} + + +def test_build_run_instances_params_includes_dynamic_fields(): + image = {"image_id": "m-j6caxlj97mf3l51d0wcz", "image_name": "WordPress", "product_code": "cmjj010728", "source": "marketplace"} + params = aliyun_ecs.build_run_instances_params( + CONFIG, image, disk_size_gib=300, auto_release_time="2026-10-13T11:19:00Z" + ) + + assert params["SystemDisk.Size"] == 300 + assert params["AutoReleaseTime"] == "2026-10-13T11:19:00Z" + assert params["ImageId"] == "m-j6caxlj97mf3l51d0wcz" + assert params["SpotStrategy"] == "SpotAsPriceGo" + assert params["SecurityGroupId"] == "sg-j6c7epgwcech14ofdt5l" + assert re.match(r"^libs-test-\d{6}$", params["InstanceName"]) + + named = aliyun_ecs.build_run_instances_params(CONFIG, image, disk_size_gib=300, name="custom-name") + assert named["InstanceName"] == "custom-name" + + +def test_generate_instance_name_uses_prefix(): + assert re.match(r"^libs-test-\d{6}$", aliyun_ecs.generate_instance_name("libs-test")) + assert re.match(r"^libs-test-\d{6}$", aliyun_ecs.generate_instance_name()) + + +def test_public_ips_collects_public_and_eip(): + instance = { + "PublicIpAddress": {"IpAddress": ["1.2.3.4"]}, + "EipAddress": {"IpAddress": "5.6.7.8"}, + } + assert aliyun_ecs.public_ips(instance) == ["1.2.3.4", "5.6.7.8"] + + +def test_wait_for_public_ip_returns_when_ready(monkeypatch): + monkeypatch.setattr( + aliyun_ecs, + "describe_instance", + lambda *args, **kwargs: {"Status": "Running", "PublicIpAddress": {"IpAddress": ["47.1.2.3"]}}, + ) + result = aliyun_ecs.wait_for_public_ip("i-1", "id", "secret", "cn-hongkong", timeout=1) + assert result["public_ip"] == "47.1.2.3" + assert result["pending"] is False + + +def test_wait_for_public_ip_times_out(monkeypatch): + monkeypatch.setattr( + aliyun_ecs, + "describe_instance", + lambda *args, **kwargs: {"Status": "Starting", "PublicIpAddress": {"IpAddress": []}}, + ) + result = aliyun_ecs.wait_for_public_ip("i-1", "id", "secret", "cn-hongkong", timeout=0) + assert result["pending"] is True + assert result["public_ip"] is None + assert result["status"] == "Starting" + + +def test_run_instances_parses_instance_ids(monkeypatch): + monkeypatch.setattr( + aliyun_ecs, + "_call", + lambda *args, **kwargs: {"RequestId": "req-1", "InstanceIdSets": {"InstanceIdSet": ["i-1"]}}, + ) + result = aliyun_ecs.run_instances({"RegionId": "cn-hongkong"}, "id", "secret") + assert result == {"request_id": "req-1", "instance_ids": ["i-1"]} + + +def test_create_command_dry_run_does_not_call_api(repo_fixture, monkeypatch): + _write_config(repo_fixture) + + def boom(*args, **kwargs): + raise AssertionError("should not call the API during --dry-run") + + monkeypatch.setattr(ops.aliyun_ecs, "run_instances", boom) + + result = runner.invoke( + ops.app, + [ + "create-aliyun-ecs", + "--image-id", + "m-explicit", + "--disk-size", + "300", + "--release-in", + "10h", + "--dry-run", + "--json", + ], + ) + + assert result.exit_code == 0, result.output + payload = json.loads(result.output) + assert payload["dry_run"] is True + assert payload["disk_size_gib"] == 300 + assert payload["image_id"] == "m-explicit" + + +def test_create_command_interactive_abort(repo_fixture, monkeypatch): + _write_config(repo_fixture) + monkeypatch.setattr( + ops.aliyun_ecs, + "resolve_image", + lambda *args, **kwargs: {"image_id": "m-x", "image_name": "img", "source": "marketplace"}, + ) + called = [] + monkeypatch.setattr(ops.aliyun_ecs, "run_instances", lambda *args, **kwargs: called.append(True)) + + result = runner.invoke(ops.app, ["create-aliyun-ecs"], input="300\n10\nn\n") + + assert result.exit_code == 0, result.output + assert "Aborted" in result.output + assert called == [] + + +def test_create_command_outputs_public_ip(repo_fixture, monkeypatch): + _write_config(repo_fixture) + monkeypatch.setattr( + ops.aliyun_ecs, + "run_instances", + lambda *args, **kwargs: {"request_id": "req-1", "instance_ids": ["i-1"]}, + ) + monkeypatch.setattr( + ops.aliyun_ecs, + "wait_for_public_ip", + lambda *args, **kwargs: { + "instance_id": "i-1", + "public_ip": "47.9.9.9", + "public_ips": ["47.9.9.9"], + "status": "Running", + "pending": False, + }, + ) + + result = runner.invoke( + ops.app, + ["create-aliyun-ecs", "--image-id", "m-x", "--disk-size", "100", "--release-in", "1h", "--yes", "--json"], + ) + + assert result.exit_code == 0, result.output + payload = json.loads(result.output) + assert payload["public_ip"] == "47.9.9.9" + assert payload["instance_ids"] == ["i-1"] + assert payload["action"] == "created" + + +def test_create_command_rejects_out_of_range_disk(repo_fixture): + _write_config(repo_fixture) + + result = runner.invoke( + ops.app, + ["create-aliyun-ecs", "--image-id", "m-explicit", "--disk-size", "9999", "--release-in", "10h", "--yes", "--json"], + ) + + assert result.exit_code == 2 + assert "above the maximum" in (result.output + (result.stderr or "")) diff --git a/cli/tests/test_app.py b/cli/tests/test_app.py index 41e68b1e9..d9a01f241 100644 --- a/cli/tests/test_app.py +++ b/cli/tests/test_app.py @@ -1,5 +1,11 @@ from __future__ import annotations +import concurrent.futures +import os +import subprocess +import sys +import textwrap + import yaml from libs import app as app_module @@ -104,3 +110,34 @@ def test_archive_app_dry_run_does_not_move_files(repo_fixture, app_factory): assert result["metadata_updated"] is True assert (repo_fixture / "apps" / "nextcloud").exists() assert not (repo_fixture / "archive" / "apps" / "nextcloud").exists() + + +def test_archive_app_concurrent_processes_preserve_all_metadata(repo_fixture, app_factory): + for name in ("owncloud", "posthog", "python", "signoz"): + app_factory(name) + + script = textwrap.dedent( + """ + import os + from libs import app + app.archive_app(os.environ["APP_NAME"], reason="batch-archive", dry_run=False) + """ + ) + commands = [[sys.executable, "-c", script] for _ in ("owncloud", "posthog", "python", "signoz")] + names = ["owncloud", "posthog", "python", "signoz"] + + def run(payload): + command, name = payload + env = {**os.environ, "APP_NAME": name} + return subprocess.run(command, cwd=repo_fixture, check=True, capture_output=True, text=True, env=env) + + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: + results = list(executor.map(run, zip(commands, names, strict=True))) + + updated_archive = yaml.safe_load((repo_fixture / "metadata" / "archive.yaml").read_text(encoding="utf-8")) + archived_apps = set(updated_archive["apps"]) + + assert all(result.returncode == 0 for result in results) + assert {"owncloud", "posthog", "python", "signoz"}.issubset(archived_apps) + for name in ("owncloud", "posthog", "python", "signoz"): + assert updated_archive["overrides"][name] == {"archive_reason": "batch-archive"} diff --git a/cli/tests/test_app_tests.py b/cli/tests/test_app_tests.py index 1138b1887..ac7e2e23d 100644 --- a/cli/tests/test_app_tests.py +++ b/cli/tests/test_app_tests.py @@ -242,6 +242,41 @@ def fake_get(*args, **kwargs): assert payload["results"][2]["id"] == "web-access" +def test_run_app_tests_retries_remote_compose_config(repo_fixture, app_factory, monkeypatch): + app_factory("demo", env="W9_HTTP_PORT_SET=8080\nW9_ID=demo\n") + secret_path = repo_fixture / ".secrets" / "ssh" / "default.pem" + secret_path.parent.mkdir(parents=True, exist_ok=True) + secret_path.write_text("-----BEGIN OPENSSH PRIVATE KEY-----\n", encoding="utf-8") + attempts = {"compose-config": 0} + + monkeypatch.setattr(app_tests.remote, "default_target", lambda: "remote") + monkeypatch.setattr(app_tests.remote, "ssh_host", lambda value=None: value or "1.2.3.4") + monkeypatch.setattr(app_tests.remote, "ssh_user", lambda value=None: value or "root") + monkeypatch.setattr(app_tests.remote, "resolve_secret_path", lambda value=None: secret_path) + monkeypatch.setattr(app_tests.remote, "deploy_root", lambda value=None: value or "/websoft9/library/apps") + monkeypatch.setattr( + app_tests.remote, + "preflight_ssh", + lambda host, user, secret_path: types.SimpleNamespace(returncode=0, stdout="", stderr=""), + ) + + def fake_run_case(app_name, case, env, base_url, remote_ctx): + if case["type"] == "compose-config": + attempts["compose-config"] += 1 + return {"id": case.get("id") or case["type"], "ok": attempts["compose-config"] >= 2, "stdout": "", "stderr": ""} + return {"id": case.get("id") or case["type"], "ok": False, "stdout": "", "stderr": ""} + + monkeypatch.setattr(app_tests, "run_case", fake_run_case) + monkeypatch.setattr(app_tests.time, "sleep", lambda seconds: None) + + payload = app_tests.run_app_tests("demo", wait_timeout=10, wait_interval=1) + + assert payload["ok"] is False + assert attempts["compose-config"] == 2 + assert payload["results"][0]["id"] == "compose-config" + assert payload["results"][0]["ok"] is True + + def test_run_app_tests_container_healthy_reads_inspect_state(repo_fixture, app_factory, monkeypatch): app_factory( "demo", diff --git a/cli/tests/test_credentials.py b/cli/tests/test_credentials.py index 5c3fe6395..1369409b8 100644 --- a/cli/tests/test_credentials.py +++ b/cli/tests/test_credentials.py @@ -47,17 +47,33 @@ def test_load_provider_env_supports_dockerhub(repo_fixture): assert data["DOCKERHUB_TOKEN"] == "token" -def test_load_provider_env_supports_aliyun(repo_fixture): +def test_load_provider_env_supports_dns(repo_fixture): (repo_fixture / ".secrets").mkdir(exist_ok=True) - (repo_fixture / ".secrets" / "aliyun.env").write_text( - "ALIYUN_ACCESS_KEY_ID=id\nALIYUN_ACCESS_KEY_SECRET=secret\nALIYUN_DNS_DOMAIN=libs.websoft9.cn\n", + (repo_fixture / ".secrets" / "dns.env").write_text( + "DNS_PROVIDER=aliyun\nDNS_KEY_ID=id\nDNS_KEY_SECRET=secret\nDNS_DOMAIN=libs.websoft9.cn\n", encoding="utf-8", ) - data = credentials.load_provider_env("aliyun") + data = credentials.load_provider_env("dns") - assert data["ALIYUN_DNS_DOMAIN"] == "libs.websoft9.cn" + assert data["DNS_DOMAIN"] == "libs.websoft9.cn" + assert data["DNS_PROVIDER"] == "aliyun" + assert credentials.provider_env_path("dns").name == "dns.env" + + +def test_load_provider_env_supports_cloud_providers(repo_fixture): + (repo_fixture / ".secrets").mkdir(exist_ok=True) + (repo_fixture / ".secrets" / "aws.env").write_text( + "AWS_ACCESS_KEY_ID=id\nAWS_SECRET_ACCESS_KEY=secret\nAWS_REGION=us-east-1\n", + encoding="utf-8", + ) + + data = credentials.load_provider_env("aws") + + assert data["AWS_REGION"] == "us-east-1" + assert credentials.provider_env_path("aws").name == "aws.env" assert credentials.provider_env_path("aliyun").name == "aliyun.env" + assert credentials.provider_env_path("azure").name == "azure.env" def test_resolve_secret_precedence(repo_fixture, monkeypatch): diff --git a/cli/tests/test_dns.py b/cli/tests/test_dns.py index e41bc9151..f538c6fa8 100644 --- a/cli/tests/test_dns.py +++ b/cli/tests/test_dns.py @@ -5,7 +5,7 @@ import pytest from typer.testing import CliRunner -from libs import dns, main +from libs import dns, ops runner = CliRunner() @@ -176,10 +176,24 @@ def test_delete_rejects_missing_and_multiple(monkeypatch): def test_call_rejects_missing_credentials(): - with pytest.raises(dns.DnsError, match="missing Aliyun credentials"): + with pytest.raises(dns.DnsError, match="missing DNS credentials"): dns.call("DescribeDomains", {}, "", "") +def test_resolve_provider_defaults_and_reads_env(monkeypatch): + monkeypatch.delenv("DNS_PROVIDER", raising=False) + assert dns.resolve_provider() == dns.DEFAULT_PROVIDER + + monkeypatch.setenv("DNS_PROVIDER", "cloudflare") + assert dns.resolve_provider() == "cloudflare" + + +def test_ensure_supported_provider_accepts_only_aliyun(): + dns.ensure_supported_provider(dns.ALIYUN_PROVIDER) + with pytest.raises(dns.DnsError, match="unsupported DNS provider"): + dns.ensure_supported_provider("cloudflare") + + def test_call_raises_on_api_error(monkeypatch): class Response: status_code = 400 @@ -294,11 +308,11 @@ def fake_configure(domain, **kwargs): container["kwargs"] = kwargs return {"status": "updated", "container": "websoft9"} - monkeypatch.setattr(main.dns, "bind", fake_bind) - monkeypatch.setattr(main.dns, "configure_container", fake_configure) + monkeypatch.setattr(ops.dns, "bind", fake_bind) + monkeypatch.setattr(ops.dns, "configure_container", fake_configure) result = runner.invoke( - main.app, + ops.app, ["dns-bind", "--domain", "libs.websoft9.cn", "--ip", "1.2.3.4", "--json"], ) @@ -312,11 +326,11 @@ def fake_configure(domain, **kwargs): def test_dns_bind_command_skips_container_when_disabled(repo_fixture, monkeypatch): called = [] - monkeypatch.setattr(main.dns, "bind", lambda **kwargs: {"action": "created"}) - monkeypatch.setattr(main.dns, "configure_container", lambda *args, **kwargs: called.append(True) or {}) + monkeypatch.setattr(ops.dns, "bind", lambda **kwargs: {"action": "created"}) + monkeypatch.setattr(ops.dns, "configure_container", lambda *args, **kwargs: called.append(True) or {}) result = runner.invoke( - main.app, + ops.app, ["dns-bind", "--domain", "libs.websoft9.cn", "--ip", "1.2.3.4", "--no-container", "--json"], ) @@ -326,7 +340,7 @@ def test_dns_bind_command_skips_container_when_disabled(repo_fixture, monkeypatc def test_dns_delete_command_requires_domain(repo_fixture): - result = runner.invoke(main.app, ["dns-delete", "--json"]) + result = runner.invoke(ops.app, ["dns-delete", "--json"]) assert result.exit_code == 2 assert "domain is required" in (result.stdout + result.stderr) diff --git a/cli/tests/test_main.py b/cli/tests/test_main.py index 4689f26dd..17bb46c52 100644 --- a/cli/tests/test_main.py +++ b/cli/tests/test_main.py @@ -30,7 +30,7 @@ def test_help_command_prints_parent_help(monkeypatch): assert output == [ ("HELP TEXT", False), - ("\nLocal by default; remote-aware commands read defaults from .secrets/remote.env (TARGET, SSH_HOST, SSH_USER, SSH_SECRET_PATH, DEPLOY_ROOT, CONTAINER). Current remote-aware commands: app-deploy, app-build, app-down, app-tests, appstore-sync, appstore-deploy, websoft9-upgrade, dns-bind.", False), + ("\nLocal by default; remote-aware commands read defaults from .secrets/remote.env (TARGET, SSH_HOST, SSH_USER, SSH_SECRET_PATH, DEPLOY_ROOT, CONTAINER). Current remote-aware commands: app-deploy, app-build, app-down, app-tests, appstore-sync, appstore-deploy.", False), ] diff --git a/cli/tests/test_websoft9_upgrade.py b/cli/tests/test_websoft9_upgrade.py index cc41e45dc..0317d0a72 100644 --- a/cli/tests/test_websoft9_upgrade.py +++ b/cli/tests/test_websoft9_upgrade.py @@ -6,7 +6,7 @@ import typer -from libs import main, websoft9_upgrade +from libs import ops, websoft9_upgrade def _ok(stdout: str = "ok"): @@ -26,7 +26,7 @@ def fake_upgrade(**kwargs): monkeypatch.setattr(websoft9_upgrade, "upgrade", fake_upgrade) monkeypatch.setattr(typer, "echo", lambda message, err=False: output.append((message, err))) - main.websoft9_upgrade_command( + ops.websoft9_upgrade_command( container=None, tag="dev", tag_var="IMAGE_TAG", diff --git a/docs/ai-sdlc/02-maintenance-policy.md b/docs/ai-sdlc/02-maintenance-policy.md index c97f42473..bd2f9d77e 100644 --- a/docs/ai-sdlc/02-maintenance-policy.md +++ b/docs/ai-sdlc/02-maintenance-policy.md @@ -26,7 +26,7 @@ Worth update decisions: Default rules: - patch: prefer `auto-update` - minor: `auto-update` if compatible, otherwise `review-first` -- major: default `review-first` +- major: prefer `auto-update` when the package-side change is clear; use `review-first` for `manual-major` or materially unclear/risky package changes - prerelease, beta, rc: default `skip` - security fix: may bypass cadence diff --git a/docs/ai-sdlc/10-update-assessment-workflow.md b/docs/ai-sdlc/10-update-assessment-workflow.md index 1b94483a3..2e3c8408d 100644 --- a/docs/ai-sdlc/10-update-assessment-workflow.md +++ b/docs/ai-sdlc/10-update-assessment-workflow.md @@ -51,13 +51,15 @@ Rules: - `review-first` means stop after assessment and wait for owner approval - `defer` means record the candidate and check again in the next cadence - `skip` means no update work should start for this candidate +- a major version jump by itself is not a reason to choose `review-first`, because this repository updates packaging and validation artifacts rather than migrating a live instance +- use `review-first` for major updates only when the app policy is `manual-major`, or when package-side facts are ambiguous or materially risky - when recommending a target image tag, prefer `x.x` over `x.x.x` unless upstream does not provide the `x.x` tag or exact patch pinning is required - if `libs app-drift` returns `not-declared` or `source-error`, AI may research missing upstream sources, but should not repeat local dependency inventory already produced by CLI Decision hints: - patch: prefer `auto-update` - minor: `auto-update` if compatible, otherwise `review-first` -- major: default `review-first` +- major: prefer `auto-update` when the package-side change is clear; use `review-first` for `manual-major` or materially unclear/risky package changes - prerelease, beta, rc: default `skip` - security update: may bypass normal cadence diff --git a/docs/app-delivery-spec.md b/docs/app-delivery-spec.md new file mode 100644 index 000000000..fb66753f5 --- /dev/null +++ b/docs/app-delivery-spec.md @@ -0,0 +1,52 @@ +# App Delivery Spec + +| Property | Value | +|---|---| +| Status | Draft | +| Applies to | all app packages | +| Purpose | classify apps by delivery and maintenance model | + +## Models + +### 1. Compose-First + +Use when the upstream app is naturally expressed as `docker-compose.yml` and routine lifecycle work stays simple. + +Primary artifact: +- app package + +Primary operations: +- install with `docker compose up` +- maintain by editing package files and redeploying + +### 2. Compose + Skill + +Use when the app can run from Compose, but correct install or maintenance also needs app-specific operational knowledge. + +Primary artifacts: +- app package +- app-specific skill + +Primary operations: +- install from Compose +- maintain through guided skill actions such as upgrade, repair, migration, or recovery + +### 3. Skill-First + +Use when the official upstream delivery model is not fundamentally Compose-first, or when correctness depends on upstream-specific bootstrap and rebuild workflows. + +Primary artifact: +- app-specific skill + +Secondary artifact: +- optional package or derived Compose files when useful + +Primary operations: +- install through the skill +- maintain through the skill + +## Decision Rule + +- choose `Compose-First` when Compose is the upstream-native and maintainable path +- choose `Compose + Skill` when Compose is viable but incomplete for lifecycle operations +- choose `Skill-First` when forcing a plain Compose model would lose important upstream behavior diff --git a/docs/app-lifecycle-ux-spec.md b/docs/app-lifecycle-ux-spec.md new file mode 100644 index 000000000..20ad32578 --- /dev/null +++ b/docs/app-lifecycle-ux-spec.md @@ -0,0 +1,39 @@ +# App Lifecycle UX Spec + +| Property | Value | +|---|---| +| Status | Draft | +| Applies to | platform app install and maintenance UX | +| Purpose | define minimal UX rules for dynamic app lifecycle problems | + +## Core Rules + +### 1. Entry First + +- every app must expose one primary access entry +- default UI should show the entry, not raw ports + +### 2. Ports Are Secondary + +- ports are advanced details, not the default interaction surface +- when an app has multiple exposed ports, label them by purpose: primary, admin, auxiliary, internal + +### 3. Running Is Not Installed + +- app state must distinguish between runtime health and setup completion +- minimum states: `not_ready`, `running_uninitialized`, `running_ready` + +### 4. Account Mode Must Be Declared + +- each app should declare how the first admin identity is obtained +- minimum modes: `package-managed`, `runtime-generated`, `first-login-created`, `external-auth` + +### 5. Domain Change Is A Workflow + +- changing domain must not be treated as a plain field edit +- the platform should handle it as an action with validation, rewrite, restart or rebuild, and verification + +### 6. App-Specific Logic Belongs In Skills + +- when correct install or maintenance depends on app-specific behavior, the platform should use an app-specific skill +- do not force all lifecycle operations into one generic form diff --git a/docs/devops-spec.md b/docs/devops-spec.md index 81c716d11..8124679e8 100644 --- a/docs/devops-spec.md +++ b/docs/devops-spec.md @@ -198,7 +198,7 @@ Current commands expected to support these shared options: - `libs app-down` - `libs appstore-sync` - `libs appstore-deploy` (currently a stub; it still exposes the shared options in help) -- `libs websoft9-upgrade` +- `make websoft9-upgrade` Business inputs SHOULD be passed as arguments, not hidden in environment variables. diff --git a/docs/local-secrets.md b/docs/local-secrets.md index 6c072b70b..c8ccaa089 100644 --- a/docs/local-secrets.md +++ b/docs/local-secrets.md @@ -13,7 +13,10 @@ This repository keeps local secrets and remote execution defaults outside git. | `.secrets/contentful.env` | Contentful token file for `libs catalog-push --apply` (`CONTENTFUL_ACCESS_TOKEN=...`) | | `.secrets/cloudflare.env` | Cloudflare token file for CLI or publish operations (`CLOUDFLARE_API_TOKEN=...`) | | `.secrets/dockerhub.env` | Docker Hub credentials for the controlled `libs app-build --push` backdoor (`DOCKERHUB_USERNAME=...` and `DOCKERHUB_TOKEN=...`, optional `DOCKERHUB_ORG=...` default push namespace) | -| `.secrets/aliyun.env` | Aliyun DNS credentials for `libs dns-bind` / `libs dns-delete` (`ALIYUN_ACCESS_KEY_ID=...`, `ALIYUN_ACCESS_KEY_SECRET=...`, optional `ALIYUN_DNS_DOMAIN=...` wildcard base such as `libs.websoft9.cn`) | +| `.secrets/dns.env` | DNS credentials for `make dns-bind` / `make dns-delete` (`DNS_PROVIDER=...` such as `aliyun`, `DNS_KEY_ID=...`, `DNS_KEY_SECRET=...`, optional `DNS_DOMAIN=...` wildcard base such as `libs.websoft9.cn`) | +| `.secrets/aliyun.env` | Alibaba Cloud credentials written by `make connector` → `alibabacloud` (`ALIYUN_ACCESS_KEY_ID=...`, `ALIYUN_ACCESS_KEY_SECRET=...`, optional `ALIYUN_REGION=...`) | +| `.secrets/aws.env` | AWS credentials written by `make connector` → `aws` (`AWS_ACCESS_KEY_ID=...`, `AWS_SECRET_ACCESS_KEY=...`, optional `AWS_REGION=...`) | +| `.secrets/azure.env` | Azure credentials written by `make connector` → `azure` (`AZURE_SUBSCRIPTION_ID=...`, `AZURE_TENANT_ID=...`, `AZURE_CLIENT_ID=...`, `AZURE_CLIENT_SECRET=...`) | ## Manual vs CI @@ -26,9 +29,9 @@ This repository keeps local secrets and remote execution defaults outside git. - Never commit secrets; keep files under `.secrets/` outside git. - Keep `.secrets/ssh/default.pem` with permissions `600`. - Run `make remote` to regenerate `.secrets/remote.env` interactively; the default deploy root is `/websoft9/library/apps`. -- Run `make connector` to create or update provider token files such as `.secrets/contentful.env`, `.secrets/cloudflare.env`, `.secrets/dockerhub.env`, and `.secrets/aliyun.env` interactively. +- Run `make connector` to create or update provider files interactively: `contentful`, `cloudflare`, `dockerhub`, `dns` (`.secrets/dns.env`, asks for a `DNS_PROVIDER` defaulting to `aliyun`, key id, key secret, and the wildcard base domain), and the cloud providers `alibabacloud` (`.secrets/aliyun.env`), `aws` (`.secrets/aws.env`), and `azure` (`.secrets/azure.env`). - Provider env files store the token directly as standard environment variables; no extra file indirection is used. -- `libs dns-bind` points the wildcard record (`*.`) at the remote host or `127.0.0.1`; `libs dns-delete` removes that single record. They read `TARGET`/`SSH_HOST` from `.secrets/remote.env` unless `--target`, `--ip`, or `--ssh-host` is given. -- After a successful bind, `libs dns-bind` also sets the platform domain by running `websoft9 setconfig --section domain --key wildcard_domain` inside the Websoft9 container. The container name is the shared CLI default (`CONTAINER` in `.secrets/remote.env`, else `websoft9`), not hardcoded. This step is best-effort: it is skipped without error when the container is missing or unreachable, and `--no-container` disables it. +- `make dns-bind` points the wildcard record (`*.`) at the remote host or `127.0.0.1`; `make dns-delete` removes that single record. They read `TARGET`/`SSH_HOST` from `.secrets/remote.env` unless `--target`, `--ip`, or `--ssh-host` is given. Only `DNS_PROVIDER=aliyun` is implemented today; other providers are rejected with a clear error. +- After a successful bind, `make dns-bind` also sets the platform domain by running `websoft9 setconfig --section domain --key wildcard_domain` inside the Websoft9 container. The container name is the shared CLI default (`CONTAINER` in `.secrets/remote.env`, else `websoft9`), not hardcoded. This step is best-effort: it is skipped without error when the container is missing or unreachable, and `--no-container` disables it. - `DOCKERHUB_ORG` is the default namespace for publishing: a bare `W9_REPO` (e.g. `wordpress`) becomes `/wordpress`, while an already-namespaced `W9_REPO` (e.g. `websoft9dev/akeneo`) is kept as-is. Override per run with `--org`; it never affects deploy builds (only push targets). - `libs app-build --push` is a controlled backdoor: outside CI, pushing stable tags requires `--confirm-stable`. diff --git a/docs/official-installer-adoption-spec.md b/docs/official-installer-adoption-spec.md new file mode 100644 index 000000000..114a83b36 --- /dev/null +++ b/docs/official-installer-adoption-spec.md @@ -0,0 +1,316 @@ +# Official Installer Adoption Spec + +| Property | Value | +|---|---| +| Status | Draft | +| Applies to | Websoft9 platform integrators, `docker-library` maintainers, AI workers | +| Purpose | Define how Websoft9 adopts and manages an upstream installer-managed deployment without owning the upstream `docker-compose.yml` | + +## 1. Scope + +This spec defines a second integration model for complex upstream applications whose official deployment is produced by an installer script or installer binary. + +Examples: + +- PostHog hobby self-host deployment +- other upstreams that generate a Docker Compose project at install time + +This spec covers: + +- install-time execution ownership +- post-install discovery and registration +- runtime management after adoption +- upgrade and re-adoption flow + +This spec does not cover: + +- replacing the upstream installer +- rewriting the upstream topology into a repository-managed app package +- owner final E2E judgment +- downstream UI design details + +## 2. Problem Statement + +Some upstream applications are no longer practical to maintain as a normal repository-managed app package under `apps/`. + +Typical reasons: + +- the upstream deploy shape changes quickly +- install and upgrade logic include generated files, helper scripts, and migration orchestration beyond a static `docker-compose.yml` +- the upstream deployment is multi-service and tightly coupled to its own boot and migration process + +For these applications, Websoft9 should manage the resulting deployment after install rather than own the upstream deployment files as a primary source of truth. + +## 3. Integration Model + +This spec introduces the `official-installer-adopted` integration model. + +Definition: + +- upstream installer owns deployment creation +- upstream-generated files are the runtime source of truth +- Websoft9 owns install invocation, discovery, registration, lifecycle actions, and re-adoption after upgrade + +This differs from the normal repository app contract: + +- repository-managed app: this repository owns `.env`, `docker-compose.yml`, `variables.json`, and app-local support files +- official-installer-adopted app: upstream owns the generated deployment files; Websoft9 stores only adoption metadata and optional thin adapters + +## 4. Goals + +- allow Websoft9 to support complex upstream stacks without maintaining a drifting copy of the upstream compose topology +- keep lifecycle actions consistent for the operator +- make adopted deployments discoverable and re-adoptable after upgrade +- isolate platform-owned metadata from upstream-owned deployment files + +## 5. Non-Goals + +- full normalization of installer-managed deployments into repository conventions +- guaranteed multi-instance support when the upstream installer does not support it +- forcing all internal dependency containers onto the shared `websoft9` network +- deep app-specific self-healing beyond the upstream installer and runtime model + +## 6. Source Of Truth + +For an `official-installer-adopted` deployment: + +- upstream-generated deployment files are the runtime source of truth +- Websoft9 adoption metadata is a management cache, not the runtime source of truth +- repository docs or templates may describe the integration, but do not replace the upstream-generated deployment files + +Implication: + +- if platform metadata and runtime state disagree, the platform must re-discover from runtime state and upstream-owned files + +## 7. Minimum Adoption Contract + +An upstream deployment is adoptable only when all of the following are true: + +1. the installer can be invoked in a controlled working directory +2. the resulting deployment is identifiable as a Docker Compose project or equivalent multi-container unit +3. the install directory can be persisted and revisited later +4. the platform can determine a main entrypoint for user access +5. the platform can execute start, stop, restart, status, and logs against the adopted unit +6. the platform can identify key stateful volumes or storage locations +7. the platform can re-run or invoke the upstream upgrade path +8. the platform can re-discover metadata after upgrade + +If any of these are missing, the app is not a good candidate for this model. + +## 8. Install Execution Responsibilities + +Websoft9 owns the installer execution wrapper. + +The wrapper must: + +- create or select the target install directory +- inject installer inputs such as domain, version tag, and optional feature keys +- capture install logs +- detect install success or first blocking failure +- record the effective working directory used for installation + +Rules: + +- the wrapper should prefer non-interactive invocation when upstream supports it +- the wrapper must not assume the upstream installer supports explicit path parameters +- when the installer is directory-sensitive, the wrapper must control the working directory before invocation + +## 9. Adoption Discovery + +After a successful install, Websoft9 must discover the deployed unit instead of assuming fixed names. + +Minimum discovery fields: + +- app type +- integration model: `official-installer-adopted` +- install root directory +- primary compose file path +- effective env file path if present +- compose project name +- compose working directory +- main entrypoint service name +- main access surface: scheme, host, port, path +- service inventory +- stateful volumes or storage paths +- primary database service if any +- object storage service if any +- upstream upgrade command or upgrade entrypoint + +Preferred discovery sources: + +- generated files in the install root +- `docker inspect` labels +- `docker compose config` +- runtime container inventory + +## 10. Registration Model + +The platform should register adopted deployments in machine-readable metadata. + +Recommended registration fields: + +```json +{ + "app": "posthog", + "integration_model": "official-installer-adopted", + "instance_id": "posthog-001", + "install_root": "/opt/websoft9/adopted/posthog/posthog-001", + "project_type": "compose", + "project_name": "posthog_001", + "compose_file": "/opt/websoft9/adopted/posthog/posthog-001/docker-compose.yml", + "env_file": "/opt/websoft9/adopted/posthog/posthog-001/.env", + "entry_service": "proxy", + "access": { + "scheme": "https", + "host": "posthog.example.com", + "port": 443, + "path": "/" + }, + "services": ["proxy", "web", "worker", "db"], + "volumes": ["postgres-data", "clickhouse-data"], + "database": { + "service": "db", + "type": "postgresql" + }, + "upgrade": { + "command": "./posthog/bin/upgrade-hobby" + } +} +``` + +Rules: + +- registration metadata must be rebuildable from discovery +- registration must not be the only place where critical runtime facts exist + +## 11. Runtime Management Responsibilities + +After adoption, Websoft9 must manage the deployment as a project unit, not as a single fixed container name. + +Minimum supported actions: + +- status +- start +- stop +- restart +- logs +- open main entrypoint +- inspect current service list + +Rules: + +- runtime actions should target the compose project or equivalent unit +- platform logic must not require a fixed `container_name` +- platform logic should prefer project-scoped commands over raw container-scoped commands + +## 12. Network Model + +Installer-managed deployments may keep their internal dependencies on private project networks. + +Rules: + +- the platform must not require every service to join `websoft9` +- only the adopted deployment's main entrypoint needs a platform-visible access path +- platform access may be achieved by host port binding, reverse proxy, or a thin adapter +- internal databases and dependency services may remain on private networks + +## 13. Upgrade And Re-Adoption + +Upgrade is a first-class part of this model. + +Rules: + +- the platform should invoke the upstream-supported upgrade path instead of reimplementing it +- after upgrade, the platform must run discovery again +- changes in service inventory, volume inventory, or access shape must refresh registration metadata +- if re-discovery fails, the deployment remains installed but adoption status becomes degraded or blocked + +Minimum post-upgrade checks: + +- compose project still resolvable +- entry service still reachable +- access surface still valid +- stateful services still present + +## 14. Thin Adapter Layer + +The platform may apply a thin adapter layer when necessary. + +Examples: + +- attach only the public entrypoint to the `websoft9` network +- add a reverse-proxy or management sidecar +- add labels or metadata files needed for platform discovery + +Rules: + +- adapters must be minimal +- adapters must not replace the upstream deployment as the primary source of truth +- adapters should be re-applicable after upgrade +- adapters must avoid deep rewrites of upstream service topology + +## 15. Multi-Instance Expectations + +This model does not guarantee multi-instance support by default. + +Rules: + +- instance isolation is supported only when the upstream installer can be safely run in separate directories and with non-conflicting ports or domains +- path isolation, port planning, and domain planning are platform responsibilities +- if the upstream installer is effectively single-instance, the platform must treat the app as single-instance unless an adapter layer adds safe isolation + +## 16. Validation Requirements + +An adopted deployment should still pass a minimal validation workflow. + +Minimum checks: + +- installer exited successfully or reached the documented success state +- compose project exists +- expected services are running or healthy +- main entrypoint is reachable +- logs show no blocking startup error +- upgrade path can be identified + +These checks are different from the standard repository `apps/` package validation and should be implemented separately. + +## 17. Failure States + +The platform should model at least these adoption states: + +- `installing`: upstream installer still running +- `adopted`: install succeeded and discovery metadata is valid +- `degraded`: deployment exists but some discovery or runtime facts are stale or partially invalid +- `upgrade_in_progress`: upstream upgrade running +- `blocked`: install or re-adoption failed with a first blocking error + +## 18. Security Boundaries + +Rules: + +- the platform must not expose internal dependency services by default only for convenience +- secrets generated by the upstream installer remain upstream-owned runtime secrets +- any platform-side registry of adopted metadata must store only what is required for management +- installer logs may contain sensitive values and must be handled as operational secrets + +## 19. PostHog Application Note + +PostHog hobby self-hosting is a reference candidate for this model because: + +- the official deployment is installer-managed +- the upstream deploy shape includes generated files, helper scripts, and migration orchestration beyond a static compose file +- direct repository maintenance of a drift-free local compose copy is high-cost + +Expected PostHog-specific adoption concerns: + +- installer working directory controls install path +- installer does not automatically avoid host port conflicts +- runtime shape may change across upgrades +- clickhouse, storage, and migration boot order are installer-coupled + +## 20. Open Questions + +- should adopted deployments have a repository descriptor file for operator docs only +- how much of the registration metadata should also be rendered into appstore artifacts +- whether the platform should provide a generic adopted-compose inspector command +- whether a generic database GUI sidecar should be attachable to adopted private networks on demand diff --git a/i18n/translation.json b/i18n/translation.json index 0ad027aaf..eb0e803b8 100644 --- a/i18n/translation.json +++ b/i18n/translation.json @@ -347,10 +347,6 @@ "KAFKA BROKERS", "KAFKA BROKERS" ], - "W9_LOGIN_GET_Kibaba_TOKEN": [ - "ES GET KIBANA TOKEN METHOD", - "ES 获取 KIBANA TOKEN 方法" - ], "W9_WS_PORT_SET": [ "WEB SOCKET PORT", "WEB SOCKET 端口" diff --git a/make.ps1 b/make.ps1 index a843a49a6..5cf00a40e 100644 --- a/make.ps1 +++ b/make.ps1 @@ -71,6 +71,11 @@ switch ($Target) { Write-HelpEntry "opencode-clear" "list opencode sessions, confirm, then delete them (ARGS: --all/--dry-run)" Write-HelpEntry "cli" "open a PowerShell with the libs CLI activated" Write-HelpEntry "libs" "run one libs command, e.g. .\make.ps1 libs scan --app wordpress --json" + Write-HelpHeader "Server Ops" + Write-HelpEntry "dns-bind" "point the wildcard record (*.) at the remote host or localhost (ARGS: --domain/--ip/--json)" + Write-HelpEntry "dns-delete" "delete the single wildcard record (*.) for the domain (ARGS: --domain/--json)" + Write-HelpEntry "websoft9-upgrade" "upgrade the Websoft9 platform container: set image tag, pull, recreate (ARGS: --tag/--target)" + Write-HelpEntry "create-aliyun-ecs" "create a spot Aliyun ECS instance from ci/cloud/aliyun-ecs.json (ARGS: --disk-size/--release-in)" Write-HelpHeader "Testing & Quality" Write-HelpEntry "test" "run the full repo machine-system test suite" Write-HelpEntry "test-cli" "run cli unit and contract tests" @@ -80,7 +85,7 @@ switch ($Target) { Write-HelpEntry "help" "show this help" Write-HelpEntry "install" "create .venv and install the libs CLI" Write-HelpEntry "remote" "interactively write .secrets/remote.env for remote-aware commands" - Write-HelpEntry "connector" "interactively write .secrets/.env for external API tokens" + Write-HelpEntry "connector" "interactively write .secrets/.env for API tokens, DNS and cloud credentials" Write-Host "" } "install" { @@ -93,6 +98,22 @@ switch ($Target) { Set-ProxyEnvironment & .\.venv\Scripts\libs.exe @Args } + "dns-bind" { + Set-ProxyEnvironment + & .\.venv\Scripts\python.exe -m libs.ops dns-bind @Args + } + "dns-delete" { + Set-ProxyEnvironment + & .\.venv\Scripts\python.exe -m libs.ops dns-delete @Args + } + "websoft9-upgrade" { + Set-ProxyEnvironment + & .\.venv\Scripts\python.exe -m libs.ops websoft9-upgrade @Args + } + "create-aliyun-ecs" { + Set-ProxyEnvironment + & .\.venv\Scripts\python.exe -m libs.ops create-aliyun-ecs @Args + } "cli" { $pwsh = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" } $command = "& '.\.venv\Scripts\Activate.ps1'; libs -h" @@ -150,18 +171,27 @@ switch ($Target) { "contentful" { $currentChoice = "1" } "cloudflare" { $currentChoice = "2" } "dockerhub" { $currentChoice = "3" } - "aliyun" { $currentChoice = "4" } + "dns" { $currentChoice = "4" } + "alibabacloud" { $currentChoice = "5" } + "aws" { $currentChoice = "6" } + "azure" { $currentChoice = "7" } "1" { $currentChoice = "1" } "2" { $currentChoice = "2" } "3" { $currentChoice = "3" } "4" { $currentChoice = "4" } + "5" { $currentChoice = "5" } + "6" { $currentChoice = "6" } + "7" { $currentChoice = "7" } } } Write-Host "Available providers:" Write-Host " 1) contentful" Write-Host " 2) cloudflare" Write-Host " 3) dockerhub" - Write-Host " 4) aliyun (DNS)" + Write-Host " 4) dns" + Write-Host " 5) alibabacloud" + Write-Host " 6) aws" + Write-Host " 7) azure" $provider = Read-Host "provider [$currentChoice]" if (-not $provider) { $provider = $currentChoice @@ -171,7 +201,10 @@ switch ($Target) { "1" { $provider = "contentful" } "2" { $provider = "cloudflare" } "3" { $provider = "dockerhub" } - "4" { $provider = "aliyun" } + "4" { $provider = "dns" } + "5" { $provider = "alibabacloud" } + "6" { $provider = "aws" } + "7" { $provider = "azure" } } if ($provider -eq "contentful") { @@ -183,9 +216,14 @@ switch ($Target) { } elseif ($provider -eq "dockerhub") { $file = ".secrets/dockerhub.env" $key = "DOCKERHUB_TOKEN" - } elseif ($provider -eq "aliyun") { + } elseif ($provider -eq "dns") { + $file = ".secrets/dns.env" + } elseif ($provider -eq "alibabacloud") { $file = ".secrets/aliyun.env" - $key = "ALIYUN_ACCESS_KEY_SECRET" + } elseif ($provider -eq "aws") { + $file = ".secrets/aws.env" + } elseif ($provider -eq "azure") { + $file = ".secrets/azure.env" } else { throw "Unsupported provider: $provider" } @@ -229,19 +267,67 @@ switch ($Target) { $lines = @("DOCKERHUB_USERNAME=$inputUser", "DOCKERHUB_TOKEN=$inputToken") if ($inputOrg) { $lines += "DOCKERHUB_ORG=$inputOrg" } Set-Content -Encoding UTF8 -Path $file -Value $lines - } elseif ($provider -eq "aliyun") { + } elseif ($provider -eq "dns") { + $curDns = $existing["DNS_PROVIDER"] + if (-not $curDns) { $curDns = "aliyun" } + $curId = $existing["DNS_KEY_ID"] + $curSecret = $existing["DNS_KEY_SECRET"] + $curDomain = $existing["DNS_DOMAIN"] + $inputDns = Read-Host "DNS_PROVIDER (e.g. aliyun) [$curDns]" + if (-not $inputDns) { $inputDns = $curDns } + $inputId = Read-Host "DNS_KEY_ID [$curId]" + if (-not $inputId) { $inputId = $curId } + $inputSecret = Read-SecretValue "DNS_KEY_SECRET [keep existing]" + if (-not $inputSecret) { $inputSecret = $curSecret } + $inputDomain = Read-Host "DNS_DOMAIN (wildcard base, e.g. libs.websoft9.cn) [$curDomain]" + if (-not $inputDomain) { $inputDomain = $curDomain } + if (-not $inputDns -or -not $inputId -or -not $inputSecret) { throw "provider, key id and secret are required" } + $lines = @("DNS_PROVIDER=$inputDns", "DNS_KEY_ID=$inputId", "DNS_KEY_SECRET=$inputSecret") + if ($inputDomain) { $lines += "DNS_DOMAIN=$inputDomain" } + Set-Content -Encoding UTF8 -Path $file -Value $lines + } elseif ($provider -eq "alibabacloud") { $curId = $existing["ALIYUN_ACCESS_KEY_ID"] $curSecret = $existing["ALIYUN_ACCESS_KEY_SECRET"] - $curDomain = $existing["ALIYUN_DNS_DOMAIN"] + $curRegion = $existing["ALIYUN_REGION"] $inputId = Read-Host "ALIYUN_ACCESS_KEY_ID [$curId]" if (-not $inputId) { $inputId = $curId } $inputSecret = Read-SecretValue "ALIYUN_ACCESS_KEY_SECRET [keep existing]" if (-not $inputSecret) { $inputSecret = $curSecret } - $inputDomain = Read-Host "ALIYUN_DNS_DOMAIN (wildcard base, e.g. libs.websoft9.cn) [$curDomain]" - if (-not $inputDomain) { $inputDomain = $curDomain } + $inputRegion = Read-Host "ALIYUN_REGION (optional, e.g. cn-hongkong) [$curRegion]" + if (-not $inputRegion) { $inputRegion = $curRegion } if (-not $inputId -or -not $inputSecret) { throw "access key id and secret are required" } $lines = @("ALIYUN_ACCESS_KEY_ID=$inputId", "ALIYUN_ACCESS_KEY_SECRET=$inputSecret") - if ($inputDomain) { $lines += "ALIYUN_DNS_DOMAIN=$inputDomain" } + if ($inputRegion) { $lines += "ALIYUN_REGION=$inputRegion" } + Set-Content -Encoding UTF8 -Path $file -Value $lines + } elseif ($provider -eq "aws") { + $curId = $existing["AWS_ACCESS_KEY_ID"] + $curSecret = $existing["AWS_SECRET_ACCESS_KEY"] + $curRegion = $existing["AWS_REGION"] + $inputId = Read-Host "AWS_ACCESS_KEY_ID [$curId]" + if (-not $inputId) { $inputId = $curId } + $inputSecret = Read-SecretValue "AWS_SECRET_ACCESS_KEY [keep existing]" + if (-not $inputSecret) { $inputSecret = $curSecret } + $inputRegion = Read-Host "AWS_REGION (optional, e.g. us-east-1) [$curRegion]" + if (-not $inputRegion) { $inputRegion = $curRegion } + if (-not $inputId -or -not $inputSecret) { throw "access key id and secret are required" } + $lines = @("AWS_ACCESS_KEY_ID=$inputId", "AWS_SECRET_ACCESS_KEY=$inputSecret") + if ($inputRegion) { $lines += "AWS_REGION=$inputRegion" } + Set-Content -Encoding UTF8 -Path $file -Value $lines + } elseif ($provider -eq "azure") { + $curSub = $existing["AZURE_SUBSCRIPTION_ID"] + $curTenant = $existing["AZURE_TENANT_ID"] + $curClient = $existing["AZURE_CLIENT_ID"] + $curSecret = $existing["AZURE_CLIENT_SECRET"] + $inputSub = Read-Host "AZURE_SUBSCRIPTION_ID [$curSub]" + if (-not $inputSub) { $inputSub = $curSub } + $inputTenant = Read-Host "AZURE_TENANT_ID [$curTenant]" + if (-not $inputTenant) { $inputTenant = $curTenant } + $inputClient = Read-Host "AZURE_CLIENT_ID [$curClient]" + if (-not $inputClient) { $inputClient = $curClient } + $inputSecret = Read-SecretValue "AZURE_CLIENT_SECRET [keep existing]" + if (-not $inputSecret) { $inputSecret = $curSecret } + if (-not $inputSub -or -not $inputTenant -or -not $inputClient -or -not $inputSecret) { throw "subscription id, tenant id, client id and client secret are required" } + $lines = @("AZURE_SUBSCRIPTION_ID=$inputSub", "AZURE_TENANT_ID=$inputTenant", "AZURE_CLIENT_ID=$inputClient", "AZURE_CLIENT_SECRET=$inputSecret") Set-Content -Encoding UTF8 -Path $file -Value $lines } else { $token = Read-SecretValue $key diff --git a/metadata/.app-metadata.lock b/metadata/.app-metadata.lock new file mode 100644 index 000000000..e69de29bb diff --git a/metadata/archive.yaml b/metadata/archive.yaml index b65173be9..48ac66b50 100644 --- a/metadata/archive.yaml +++ b/metadata/archive.yaml @@ -11,46 +11,149 @@ apps: - alfresco - ansible - answer +- apache - apex +- apisix +- appsmith - appwrite - aria2 - automatisch - awx - azimutt - bigagi +- bigbluebutton +- bitwarden +- bookstack +- browserless +- bunkerweb +- bytebase - cadvisor - calcom - chat2db +- checkmate - chronograf +- clamav +- cloudreve +- cmak +- collabora - comentario +- commafeed +- compreface +- coredns +- countly +- coze +- crowdsec +- dashy +- databasus +- datahub +- ddnsgo +- debezium +- dgraph +- discourse - discuz +- docker +- dockermailserver +- docusaurus +- docuseal +- doris +- dotnet +- drawio +- duplicati +- ejbca +- emqx +- excalidraw +- falcon +- filepizza +- filerun +- firecrawl +- flowise +- fluentbit +- fluentd +- focalboard +- formbricks +- frappe +- freshrss +- frigate +- frp - g4f - gitness - gladys - glance +- go - gogs - gopeed - gotify - graphite - guacamole +- headscale - heyform - huggingchat - huginn - humhub - hyperswitch +- immich - inngest - istio - jetty - joomla - jumpserver +- k0s +- kasmweb - kaspersky +- kavita +- keep +- keila +- kener +- keploy +- kestra +- khoj +- killbill +- knowage +- kodbox +- koishi +- komga +- kopia - krakend +- lago +- langflow +- langfuse +- lemmy +- linkwarden +- listmonk +- mage - magento - mailpit +- mailu +- manageiq - mastodon +- mathesar +- matlab +- maven - mediawiki +- memadmin +- memcached - mingdao +- miniflux +- minio +- mixpost +- modsecurity +- mongocompass +- mongoexpress +- monkeycode +- mosquitto +- mqttx +- mysqlworkbench +- navidrome +- neko +- netdata +- nextchat +- nexterm +- nextterminal +- nexus +- nocobase +- nocodb - nodebb +- nomad - oneapi - onlyoffice - onyx @@ -61,6 +164,7 @@ apps: - openproject - opentelemetry - outline +- owncloud - palworld - pangolin - paperlessngx @@ -68,9 +172,10 @@ apps: - passbolt - penpot - photoprism +- php - phpfpmapache - phpfpmnginx -- pydio +- pimcore - plane - plausible - plex @@ -78,7 +183,10 @@ apps: - portkey - posteio - postgrest +- posthog - puter +- pydio +- python - ragflow - rainbond - rclone @@ -97,6 +205,7 @@ apps: - scmmanager - scratch - screego +- signoz - snipeit - squid - srs @@ -125,7 +234,6 @@ apps: - wikijs - windmill - wireguard -- xinference - zabbix - zerotier - zitadel @@ -149,6 +257,10 @@ overrides: archive_reason: Low user demand bigagi: archive_reason: Low user demand + bigbluebutton: + archive_reason: 下架,并更新 contentful + bitwarden: + archive_reason: 下架,并更新 contentful cadvisor: archive_reason: Low user demand chat2db: @@ -165,6 +277,12 @@ overrides: archive_reason: Low user demand chronograf: archive_reason: Low user demand + datahub: + archive_reason: 下架,并更新 contentful + discourse: + archive_reason: 下架,并更新 contentful + docusaurus: + archive_reason: 下架,并更新 contentful huginn: archive_reason: Low user demand calcom: @@ -175,8 +293,6 @@ overrides: archive_reason: Low user demand gitness: archive_reason: Low user demand - xinference: - archive_reason: Low user demand rainbond: archive_reason: Low user demand heyform: @@ -335,3 +451,13 @@ overrides: archive_reason: Low user demand posteio: archive_reason: Low user demand + signoz: + archive_reason: 下架,并更新 contentful + python: + archive_reason: 下架,并更新 contentful + owncloud: + archive_reason: 下架,并更新 contentful + posthog: + archive_reason: 暂缓讨论,后续再做 + pimcore: + archive_reason: 下架,并更新 contentful diff --git a/metadata/catalog/ckan.json b/metadata/catalog/ckan.json new file mode 100644 index 000000000..2b8b326f3 --- /dev/null +++ b/metadata/catalog/ckan.json @@ -0,0 +1,20 @@ +{ + "trademark": "CKAN", + "summary": "A tool for making open data websites", + "overview": "CKAN is an open-source DMS (data management system) for powering data hubs and data portals. CKAN makes it easy to publish, share and use data. It powers hundreds of data portals worldwide.", + "description": "CKAN is a tool for making open data websites. (Think of a content management system like WordPress - but for data, instead of pages and blog posts.) It helps you manage and publish collections of data. It is used by national and local governments, research institutions, and other organizations who collect a lot of data.\n\nOnce your data is published, users can use its faceted search features to browse and find the data they need, and preview it using maps, graphs and tables - whether they are developers, journalists, researchers, NGOs, citizens, or even your own staff.", + "websiteurl": "https://ckan.org/", + "screenshots": [ + "https://libs.websoft9.com/Websoft9/DocsPicture/zh/ckan/ckan-gui-websoft9.png" + ], + "catalogBindings": [ + { + "parentKey": "analytics", + "childKey": "dinsights" + }, + { + "parentKey": "analytics", + "childKey": "data-catalog" + } + ] +} diff --git a/metadata/catalog/geoserver.json b/metadata/catalog/geoserver.json new file mode 100644 index 000000000..975da83e0 --- /dev/null +++ b/metadata/catalog/geoserver.json @@ -0,0 +1,13 @@ +{ + "trademark": "GeoServer", + "catalogBindings": [ + { + "parentKey": "architecture", + "childKey": "gis" + } + ], + "summary": "Open-source geospatial data server.", + "overview": "Publishes maps and geospatial data through standard OGC services, with a browser-based admin console for configuration and data sharing.", + "description": "GeoServer is an open-source server for sharing geospatial data. It publishes data from major spatial sources through open standards such as WMS, WFS, WCS, and WMTS, making it a common choice for GIS portals, mapping services, and interoperable spatial data infrastructure.\n\nThis package deploys the official OSGeo GeoServer image as a single service with persistent data stored in the `geoserver_data` volume mounted at `/opt/geoserver_data`. The web console is exposed under `/geoserver/web`, and the package keeps the bundled demo data enabled so the UI and OGC endpoints are usable immediately after deployment.\n\nTypical use cases include publishing map layers, exposing geospatial APIs, serving raster and vector datasets, and building self-hosted GIS platforms that need standards-based interoperability.", + "websiteurl": "https://geoserver.org" +} diff --git a/metadata/catalog/jfrog.json b/metadata/catalog/jfrog.json new file mode 100644 index 000000000..b62ee0d7e --- /dev/null +++ b/metadata/catalog/jfrog.json @@ -0,0 +1,16 @@ +{ + "trademark": "JFrog Artifactory", + "catalogBindings": [ + { + "parentKey": "itdeveloper", + "childKey": "artifact-repository" + } + ], + "summary": "Universal artifact repository manager", + "overview": "Store, secure, and manage binary artifacts and container images for every package type from a single repository manager.", + "description": "JFrog Artifactory is a universal binary repository manager. It stores and manages build artifacts for all major package types — Maven, Gradle, npm, PyPI, NuGet, Go, Helm, Docker/OCI, and more — and serves as the single source of truth for binaries across the software supply chain.\n\nThis package runs the official JFrog Artifactory Pro image with the bundled embedded database, so no external database service is required to get started. The JFrog Platform web console is published on port 8082 and persists all configuration, metadata, and stored artifacts in the jfrog_data volume. The first sign-in uses the built-in admin account and Artifactory then requires a new administrator password; a license is needed to unlock the full product.\n\nTypical use cases include a private Docker/OCI registry, a caching proxy for public repositories, and a central artifact store for CI/CD pipelines. Repositories, users, permissions, and remote/virtual repository layouts are all configured from the platform administration UI.", + "websiteurl": "https://jfrog.com/artifactory/", + "screenshots": [ + "https://www.jfrogchina.com/wp-content/uploads/2024/09/4-1.jpg" + ] +} diff --git a/metadata/catalog/litellm.json b/metadata/catalog/litellm.json new file mode 100644 index 000000000..3deaa93bb --- /dev/null +++ b/metadata/catalog/litellm.json @@ -0,0 +1,17 @@ +{ + "trademark": "LiteLLM", + "catalogBindings": [ + { + "parentKey": "ai", + "childKey": "aiui" + }, + { + "parentKey": "ai", + "childKey": "ai-agent-chat" + } + ], + "summary": "OpenAI-compatible LLM gateway and model proxy.", + "overview": "LiteLLM provides a self-hosted OpenAI-compatible gateway for routing requests to multiple model providers through one API and admin console.", + "description": "LiteLLM is an open-source LLM gateway and proxy server. It exposes an OpenAI-compatible API, centralizes provider credentials, and adds features such as model routing, unified auth, spend tracking, and an admin UI.\n\nThis package deploys the official LiteLLM proxy with a bundled PostgreSQL database, following the upstream DB-backed Docker quickstart topology so the `/ui` admin console and model/key management features are available.\n\nTypical use cases include unifying multiple LLM providers behind one endpoint, centralizing API access for internal tools, testing OpenAI-compatible clients against other model backends, and running a self-hosted AI gateway for teams.", + "websiteurl": "https://www.litellm.ai" +} diff --git a/metadata/catalog/nifi.json b/metadata/catalog/nifi.json new file mode 100644 index 000000000..03e60c67f --- /dev/null +++ b/metadata/catalog/nifi.json @@ -0,0 +1,13 @@ +{ + "trademark": "Apache NiFi", + "catalogBindings": [ + { + "parentKey": "analytics", + "childKey": "dintegration" + } + ], + "summary": "Dataflow automation and integration platform.", + "overview": "Designs, runs, and monitors secure dataflows for ingest, routing, transformation, and distribution through a browser-based interface.", + "description": "Apache NiFi is an open-source dataflow automation platform. It provides a browser-based interface for designing, controlling, and monitoring flows that move, route, transform, and track data between systems, with built-in provenance, back pressure, and secure communication support.\n\nThis package deploys the official Apache NiFi container with HTTPS enabled and the upstream single-user authentication model. Persistent volumes are provided for configuration, logs, state, and the main repositories so flows and operational data survive container recreation.\n\nTypical use cases include ETL and ELT pipelines, system-to-system data integration, event and log routing, API and file ingestion, and managed data distribution across internal or external services.", + "websiteurl": "https://nifi.apache.org" +} diff --git a/metadata/catalog/qwenpaw.json b/metadata/catalog/qwenpaw.json new file mode 100644 index 000000000..349b63fe7 --- /dev/null +++ b/metadata/catalog/qwenpaw.json @@ -0,0 +1,17 @@ +{ + "trademark": "QwenPaw", + "catalogBindings": [ + { + "parentKey": "ai", + "childKey": "ai-agent-chat" + } + ], + "summary": "Self-hosted multi-user AI assistant hub", + "overview": "Run a shared QwenPaw Hub with per-user runtimes, isolated workspaces, skills, channels, and local or cloud models.", + "description": "QwenPaw (Qwen Personal Agent Workstation) is an open-source personal AI assistant from the AgentScope team. QwenPaw Hub is its multi-user control plane: team members sign in at one address, and each person gets a separate QwenPaw with its own workspace, settings, credentials, and conversations.\n\nThis package deploys QwenPaw Hub as a single control-plane container with the Local runtime backend. The Hub console is published on port 8088 and is seeded with a package-managed administrator account. The control database and every user runtime persist in the qwenpaw_data volume, and administrators can create accounts, manage runtimes, and control registration mode.\n\nQwenPaw supports cloud model providers (DashScope/Qwen, OpenAI, Anthropic, Gemini, DeepSeek, and more) as well as local models through the built-in QwenPaw Local runtime, Ollama, or LM Studio. Extend it with Skills, Plugins, and MCP tools, and automate recurring work with built-in cron scheduling.", + "websiteurl": "https://qwenpaw.agentscope.io", + "screenshots": [ + "https://img.alicdn.com/imgextra/i2/O1CN01hhIGAbMm89B6lBsc_!!6000000006867-2-tps-3330-1772.png", + "https://img.alicdn.com/imgextra/i2/O1CN01EP1ra01iOAcBvF0TC_!!6000000004402-2-tps-3822-2070.png" + ] +} diff --git a/metadata/catalog/semaphoreui.json b/metadata/catalog/semaphoreui.json new file mode 100644 index 000000000..24112e3c8 --- /dev/null +++ b/metadata/catalog/semaphoreui.json @@ -0,0 +1,28 @@ +{ + "trademark": "Semaphore UI", + "catalogBindings": [ + { + "parentKey": "itdeveloper", + "childKey": "orchestration" + }, + { + "parentKey": "itdeveloper", + "childKey": "pipeline" + }, + { + "parentKey": "automation", + "childKey": "opsauto" + }, + { + "parentKey": "itdevops", + "childKey": "opsauto" + } + ], + "summary": "Modern web UI for DevOps automation.", + "overview": "Self-hosted web interface for running Ansible playbooks, Terraform/OpenTofu code, and Bash or PowerShell scripts with projects, schedules, inventories, and access control.", + "description": "Semaphore UI is an open-source, self-hosted web interface for managing DevOps automation. It runs Ansible playbooks and Terraform, OpenTofu, and Terragrunt code, executes Bash and PowerShell scripts, and organizes work into projects, task templates, tasks, schedules, inventories, and variable groups. Failed tasks can trigger notifications, and access to the automation system is controlled with users, teams, and roles.\n\nThis Websoft9 package deploys the official semaphoreui/semaphore image together with a bundled MySQL 8.0 database. The web console is published on port 3000, an initial administrator account is created from the package environment on first start, and an access-key encryption key is generated so secrets stored in the database survive restarts. Application data is persisted in the semaphore volume and database data in the mysql volume.\n\nTypical use cases include running and scheduling Ansible automation, managing Terraform and OpenTofu infrastructure changes, centralizing DevOps scripts behind a web UI, and giving teams controlled access to deployment workflows from a browser.", + "websiteurl": "https://semaphoreui.com", + "screenshots": [ + "https://libs.websoft9.com/Websoft9/DocsPicture/zh/semaphore/semaphore-gui-websoft9.png" + ] +} diff --git a/metadata/catalog/xinference.json b/metadata/catalog/xinference.json new file mode 100644 index 000000000..9a91bb0b0 --- /dev/null +++ b/metadata/catalog/xinference.json @@ -0,0 +1,13 @@ +{ + "trademark": "Xinference", + "catalogBindings": [ + { + "parentKey": "ai", + "childKey": "open-llm" + } + ], + "summary": "Open-source AI model inference platform.", + "overview": "Xinference runs, manages, and serves open-source LLMs, speech, and vision models behind a unified OpenAI-compatible API.", + "description": "Xinference is an open-source platform for running and serving large language, speech, and multimodal models. It exposes an OpenAI-compatible RESTful API and a web UI, so applications can switch models and inference backends without changing code.\n\nThis package deploys the official xprobe/xinference image. The Web UI and API are published on port 9997, and model data is persisted in named volumes for the Xinference home, Hugging Face, and ModelScope caches. Authentication is enabled by default since v3.0, so the first visit creates the administrator account. The GPU image variant needs an NVIDIA GPU with CUDA 13.0 and driver 580+; a CPU image variant is available for CPU-only hosts.\n\nTypical use cases include self-hosted LLM inference, embeddings, reranking, speech recognition, and multimodal generation behind one endpoint.", + "websiteurl": "https://github.com/xorbitsai/inference" +} diff --git a/metadata/maintenance.yaml b/metadata/maintenance.yaml index 6fac13012..be6020bba 100644 --- a/metadata/maintenance.yaml +++ b/metadata/maintenance.yaml @@ -23,7 +23,6 @@ cadence: - neo4j - nextcloud - onlyofficedocs - - owncloud - portainer - postgresql - timescaledb @@ -35,6 +34,14 @@ cadence: - wordpress - wordpresspro - dsh -update_policy: {} + monthly: + - jfrog + - qwenpaw + - xinference +update_policy: + patch-minor: + - jfrog + - qwenpaw + - xinference lifecycle: frozen: [] diff --git a/skills/README.md b/skills/README.md index 5ba0106f9..febdbf769 100644 --- a/skills/README.md +++ b/skills/README.md @@ -26,6 +26,7 @@ Shared skills: - `catalog-seed` - `update-assessment` - `app-update` +- `batch-app-update` - `new-app` - `archive-app` - `restore-app` diff --git a/skills/app-update/SKILL.md b/skills/app-update/SKILL.md index 0aa8c17e6..f30803c69 100644 --- a/skills/app-update/SKILL.md +++ b/skills/app-update/SKILL.md @@ -7,7 +7,7 @@ description: Use when the user wants to implement an approved app update after a Implement one approved app update with minimal app-local changes. -When the caller provides only an app name, first detect the best candidate stable target version and gather upstream references. Continue implementation automatically when the candidate is clear and fits the maintenance policy. Stop and obtain owner confirmation only when the candidate is ambiguous, risky, `review-first`, or multiple reasonable targets exist. +When the caller provides only an app name, first detect the best candidate stable target version and gather upstream references. Continue implementation automatically when the candidate is clear and fits the maintenance policy. A major version jump by itself does not require owner confirmation in this workflow, because the task is to update repository packaging rather than migrate a user's live instance. Stop and obtain owner confirmation only when the candidate is ambiguous, risky for the package itself, `review-first`, or multiple reasonable targets exist. This skill follows `docs/ai-sdlc/03-update-pipeline.md`, `docs/ai-sdlc/05-quality-gates.md`, and `docs/ai-sdlc/06-test-report-format.md`. @@ -26,7 +26,7 @@ Supporting files in this skill: ## Steps 1. Read repository facts from `apps//`, `metadata/maintenance.yaml`, and the app notes when relevant. -2. If the caller did not provide a target version, detect the best candidate stable target version first by checking the current package version, the upstream image tags, and the upstream release notes or changelog. Prefer the newest stable version that matches the app's maintenance policy and image-tag policy. If one candidate is clearly correct, proceed with implementation and report the chosen target version. Stop and obtain owner confirmation only when the candidate is ambiguous, risky, `review-first`, or not clearly better than alternatives. +2. If the caller did not provide a target version, detect the best candidate stable target version first by checking the current package version, the upstream image tags, and the upstream release notes or changelog. Prefer the newest stable version that matches the app's maintenance policy and image-tag policy. If one candidate is clearly correct, proceed with implementation and report the chosen target version. A major version jump alone is not a reason to stop. Stop and obtain owner confirmation only when the candidate is ambiguous, risky for the package itself, `review-first`, or not clearly better than alternatives. 3. Read `docs/w9-env-spec.md` before touching `.env` or `docker-compose.yml`; use it as the canonical `W9_*` reference, then mirror `metadata/templates/new-app/.env.tmpl` for layout. 4. Read the approved assessment result, if one exists. 5. Read upstream release notes, upgrade notes, image tags, and requirements. @@ -59,7 +59,8 @@ Supporting files in this skill: ## Rules - Do not start implementation for a `review-first` candidate unless the owner has approved continuation. -- When only an app name is provided, the workflow should normally detect the best stable target version and continue automatically. Ask the owner before editing only when the detected target is ambiguous, risky, `review-first`, or otherwise needs judgment beyond the documented maintenance policy. +- When only an app name is provided, the workflow should normally detect the best stable target version and continue automatically. Ask the owner before editing only when the detected target is ambiguous, risky for the package itself, `review-first`, or otherwise needs judgment beyond the documented maintenance policy. +- A major version jump such as `3.x -> 4.x` is not by itself a reason to pause for owner confirmation. This workflow updates repository packaging and validation artifacts, not a live-instance migration. - Keep the smallest correct change. - The update is not a blind version bump. The changed app must still pass the current quality gates after the work is complete. - Do not perform broad cosmetic template re-alignment. Fix only the app-local conformance items that are blocking, directly relevant to the update, or required by current gates and generators. diff --git a/skills/batch-app-update/SKILL.md b/skills/batch-app-update/SKILL.md new file mode 100644 index 000000000..a54430fee --- /dev/null +++ b/skills/batch-app-update/SKILL.md @@ -0,0 +1,94 @@ +--- +name: batch-app-update +description: Use when the user wants to update a batch of apps in one run, using either an explicit app list or one or more starting letters such as n,m to target all apps whose names start with those letters. Orchestrates per-app updates through the existing app-update workflow, supports controlled concurrency, and returns a batch summary. Trigger phrases: batch app update, bulk update apps, 批量更新应用, update apps starting with n,m. +--- + +# Batch App Update + +Implement a batch of approved app updates by orchestrating repeated single-app `app-update` runs. + +This skill is a thin wrapper over `app-update`. It does not replace the single-app workflow or redefine update rules. + +## Inputs + +- app selector (required) +- selector mode: `app-list`, `initials`, or `auto` (default `auto`) +- target version policy (optional: per-app auto-detect by default) +- concurrency (optional: default `2`) +- failure policy (optional: `continue` by default; alternative `stop-on-first-failure`) +- complexity skip policy (default `skip-complex-install`) + +## Selector Rules + +1. `app-list` means an explicit list of app names such as `n8n, nocodb, netdata`. +2. `initials` means one or more starting letters such as `n,m`; resolve them to all `apps/` directories whose app name starts with any listed letter. +3. Initial matching is case-insensitive. +4. Deduplicate the resolved app list and sort it alphabetically before execution. +5. If a selector resolves to zero apps, stop and report the unmatched selector. +6. Mixed input is allowed when the caller is clear, for example explicit apps plus initials. Resolve everything into one final app list before execution. + +## Steps + +1. Resolve the selector into a concrete app list from `apps/*`. +2. Report the resolved app list before making edits when the selector came from initials or mixed input. +3. Run a quick packaging-feasibility screen for each app before deep update work. +4. If the app passes the screen, run the `app-update` workflow as one independent unit. +5. After the app finishes automated validation successfully, run `.venv/bin/libs appstore-sync --app ` using the remote-aware defaults from `.secrets/remote.env` or explicit remote arguments when provided. +6. If the app fails the screen under the default complexity skip policy, mark it as `skipped-complex-install`, record the reason, and continue. +7. Keep app-local scope. Do not merge unrelated fixes across apps. +8. Collect per-app results: target version, changed files, validation result, appstore sync result, risks, and owner E2E focus. +9. Produce one batch summary after all apps finish or after the configured stop condition is reached. + +## Complexity Skip Rules + +1. Perform only a short feasibility check before spending time on an app with unclear upstream packaging. +2. If the official upstream provides a clear Docker Compose example, container manifest, or equivalent deployment spec, proceed normally. +3. If the official upstream does not provide a clear Docker Compose specification and the package would need to be inferred mainly from an official `install.sh` script, do not spend much time reverse-engineering it. +4. If the expected runtime shape is more than `5` containers or services and there is no clear official Docker Compose specification, mark the app as `skipped-complex-install`. +5. For a skipped complex install app, record brief evidence only: estimated container count, the missing official compose fact, and the install script or doc source that forced inference. +6. Skipped complex install apps stay in the batch summary for later manual follow-up; they are not treated as update failures. + +## Concurrency Rules + +1. Batch execution may run concurrently, but only with controlled fan-out. +2. Default concurrency is `2` apps at a time. +3. Use concurrency `1` when the batch is small, when the apps are likely to touch shared files, or when remote validation capacity is limited. +4. Do not run more than `3` apps at once unless the caller explicitly requests more and the environment is known to tolerate it. +5. If multiple apps may edit the same shared file, do not edit them in parallel. Typical shared-file risks include `i18n/translation.json`, repository metadata, or any root-level generated artifact. +6. Upstream research and candidate detection may happen in parallel. +7. File edits and validation may run in parallel only when the active apps are not expected to touch the same shared files and the deploy target capacity is sufficient. +8. Remote deployment validation should usually stay at concurrency `1` unless the owner explicitly confirms enough remote capacity and isolation. +9. `appstore-sync` should usually stay at concurrency `1` on a shared remote target unless the owner explicitly confirms enough isolation. +10. When any app introduces a new translatable env key or another shared-file change, finish that app first, refresh the worktree facts, then continue with the remaining apps. + +## Failure Handling + +1. Under `continue`, record the failure and continue with the remaining apps. +2. Under `stop-on-first-failure`, stop scheduling new apps after the first blocking failure, but still report results for apps already in progress. +3. A `review-first` or ambiguous target for one app does not block the whole batch under `continue`; mark that app as `needs owner decision` and continue. +4. Validation environment failures must be reported separately from app defects. +5. If `appstore-sync` fails after tests pass, keep the app result distinct from update validation failure: record it as an appstore handoff block for manual E2E preparation. + +## Output + +Return a batch report in the same language as the user: + +- resolved app list +- execution order and concurrency used +- per-app target version +- per-app result: `updated`, `needs owner decision`, `failed`, `skipped` +- per-app skip reason when applicable, including `skipped-complex-install` +- per-app validation result +- per-app appstore sync result +- per-app risks +- apps blocked by shared-file conflicts or environment limits +- apps blocked at appstore sync handoff +- owner E2E focus for the successful apps + +## Rules + +- Reuse `app-update` as the source of truth for single-app update behavior. +- Do not weaken any `app-update` requirement just because the work is batched. +- Prefer small independent batches over one very large unbounded run. +- Keep reports explicit per app; do not collapse multiple app outcomes into one generic summary. +- When the caller does not provide a concurrency value, choose the smallest value that preserves throughput without increasing shared-file conflict risk. diff --git a/skills/batch-app-update/checklist.md b/skills/batch-app-update/checklist.md new file mode 100644 index 000000000..bf6929de6 --- /dev/null +++ b/skills/batch-app-update/checklist.md @@ -0,0 +1,20 @@ +# Batch App Update Checklist + +- [ ] Confirm the batch scope is approved for implementation +- [ ] Resolve the selector into a concrete app list from `apps/` +- [ ] If initials or mixed selectors were used, show the resolved app list before editing +- [ ] Deduplicate and alphabetize the final app list +- [ ] Choose the failure policy: `continue` or `stop-on-first-failure` +- [ ] Choose the smallest safe concurrency for this batch +- [ ] Run a short feasibility screen before deep work on each app +- [ ] Skip quickly when the app appears to require inference from an official `install.sh` and the expected runtime is more than 5 containers without a clear official Compose spec +- [ ] Check whether any target apps are likely to touch shared files such as `i18n/translation.json` or repository metadata +- [ ] Run each app as an independent `app-update` unit +- [ ] Keep changes app-local for each app +- [ ] Do not run remote deploy validation concurrently unless capacity and isolation are confirmed +- [ ] After each app passes automated validation, run `.venv/bin/libs appstore-sync --app ` +- [ ] Do not run `appstore-sync` concurrently on a shared remote target unless isolation is confirmed +- [ ] Record per-app target version, changed files, validation result, appstore sync result, risks, and owner E2E focus +- [ ] Record skip evidence for any `skipped-complex-install` app +- [ ] Separate environment failures from app defects in the final summary +- [ ] Produce one explicit batch summary with per-app outcomes diff --git a/skills/batch-app-update/report-template.md b/skills/batch-app-update/report-template.md new file mode 100644 index 000000000..b514d4dd5 --- /dev/null +++ b/skills/batch-app-update/report-template.md @@ -0,0 +1,46 @@ +## Batch Update Report + +- selector mode: +- selector input: +- resolved apps: +- failure policy: +- concurrency used: +- overall decision: ready-for-e2e | partially-blocked | blocked + +## Per-App Results + +- app: + result: updated | needs-owner-decision | failed | skipped + skip reason: + current version: + target version: + files changed: + validation: + appstore sync: + risks: + owner E2E focus: + +- app: + result: updated | needs-owner-decision | failed | skipped + skip reason: + current version: + target version: + files changed: + validation: + appstore sync: + risks: + owner E2E focus: + +## Blockers And Exceptions + +- shared-file conflicts: +- environment limits: +- appstore sync handoff blocks: +- stopped early because of failure policy: + +## Summary + +- updated apps: +- needs owner decision: +- failed apps: +- skipped apps: diff --git a/skills/update-assessment/SKILL.md b/skills/update-assessment/SKILL.md index f928b60dd..e52424e91 100644 --- a/skills/update-assessment/SKILL.md +++ b/skills/update-assessment/SKILL.md @@ -65,6 +65,8 @@ A short assessment report: - `review-first` means stop after assessment and wait for owner approval. - `defer` means record the candidate and check again in the next cadence. - `skip` means no update work should start for this candidate. +- A major version jump by itself is not a reason to choose `review-first`. This repository updates packaging and validation artifacts, not a user's live-instance migration. +- Use `review-first` for major updates only when the app's maintenance policy is `manual-major`, or when the package-side facts are ambiguous or materially risky. - Prefer `x.x` image tags. Use `x.x.x` only when upstream has no usable `x.x` tag or exact patch pinning is required (see `docs/devops-spec.md`). - Report in the same language the user used. - Use `report-template.md` when the user asks for a formal assessment report, or when the adapter layer explicitly requests formal output. diff --git a/skills/update-assessment/facts-to-collect.md b/skills/update-assessment/facts-to-collect.md index 73ed01b01..7347ca783 100644 --- a/skills/update-assessment/facts-to-collect.md +++ b/skills/update-assessment/facts-to-collect.md @@ -26,5 +26,5 @@ Assessment focus: - whether the repo already floats on `x.x` - whether a patch release requires any repo change at all -- whether a major update should stop at `review-first` +- whether a major update is package-clear enough for `auto-update`, or needs `review-first` because of `manual-major` policy or package-side ambiguity - whether the current DB version is EOL'd or below the best LTS candidate diff --git a/skills/update-assessment/prompt-fragments.md b/skills/update-assessment/prompt-fragments.md index 4ddb57e94..9743125ab 100644 --- a/skills/update-assessment/prompt-fragments.md +++ b/skills/update-assessment/prompt-fragments.md @@ -24,6 +24,8 @@ Choose one result only: - `defer`: track and revisit in the next cadence - `skip`: no update work should start for this candidate +A major version jump alone is not enough to choose `review-first`. For this repository, prefer `auto-update` when the package-side changes are clear. Reserve `review-first` for `manual-major` policy, ambiguous upstream packaging facts, or materially risky package changes. + ## DB Decision Rule Candidates = alive tracks from `metadata/db-lifecycle.json` with version >= the app's `externalDB` min. LTS/stable tracks outrank innovation/short-term tracks. A DB major above the vendor-tested upper bound is not eligible. diff --git a/test.md b/test.md deleted file mode 100644 index 9daeafb98..000000000 --- a/test.md +++ /dev/null @@ -1 +0,0 @@ -test