Ctrl K
ComunidadGuías…

CHANGELOG.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Changelog

## [Unreleased]

## [1.18.2] - 2026-10-27

### Fixed
- **cAdvisor** - On small hosts with many Docker images (for example 4 vCPU / 6 GiB RAM with 30 GB of images) cAdvisor sat at its 1 GiB memory limit and swapped continuously, using up to a full CPU core and pushing the host's CPU usage high enough to trigger hosting providers' CPU alerts. It came mainly from its `disk` metrics, which measure every container's layers on disk, together with a 10s housekeeping interval. cAdvisor now runs with `--housekeeping_interval=30s` and with the `disk` and `diskIO` metrics disabled; the `container_fs_*` and `container_blkio_*` metrics are gone, and none of the bundled dashboards or alerts use them. To get them back, copy the cAdvisor `command:` from `docker-compose.yml` into `docker-compose.override.yml` and remove `disk,diskIO` from its `--disable_metrics`. If you applied the workaround from the issue, remove its `command:` from `docker-compose.override.yml`: its `--disable_metrics=disk,diskIO` replaces cAdvisor's own list of disabled metrics and turns back on the costly ones cAdvisor keeps off by default (per-process, TCP/UDP, referenced memory and others). Its `mem_limit: 2g` and `mem_reservation: 512m` should not be needed either: with the workaround, which collects more than the new defaults, cAdvisor dropped from 1 GiB to 45 MiB on the reporting host (issue #150).

## [1.18.1] - 2026-10-19

### Fixed
- **Installer** - `make update`, `make restart` and the installer stopped in 1.18.0 with `could not check for a leftover supabase-kong container: error: no such object: supabase-kong` on hosts whose Docker words a missing container in lower case (as Docker 29.2.1 does), also without the `supabase` profile. The leftover Kong check parsed Docker's error message; it now lists containers with `docker ps -a` and decides by the exit code and the exact container name, so a missing container is no longer mistaken for a Docker error and an unreachable Docker is no longer mistaken for a missing container. The failed run exited before taking anything down: on an existing install the stack kept running, so just run `make update` (or the installer) again.

## [1.18.0] - 2026-10-19

### Added
- **`make doctor`** - Warns about every running container that publishes a port on all interfaces (`0.0.0.0` / `[::]`), apart from Caddy's 80/443 and Bolt 7687 while `neo4j` is active. Docker-published ports bypass ufw, so these are reachable from the internet on a public-IP host; before, only the Supabase API gateway was checked and doctor reported HEALTHY with the Supabase pooler on `0.0.0.0:5432` and `0.0.0.0:6543`. With the `supabase` profile the pooler warning is expected on every install (Supabase's upstream compose publishes it), and with `dify` so are nginx 8080/9443 and the plugin daemon's 5003: restrict them at your cloud provider's firewall, as `docs/security.md` describes, which now also covers the Dify ports. The Supabase API gateway keeps its own check (issue #146).

### Fixed
- **Supabase** - `make update` failed with `Bind for 0.0.0.0:8000 failed: port is already allocated` on the first update after Supabase replaced its Kong gateway with Envoy: the old `supabase-kong` container was no longer in the pulled compose file, so `down` left it running on port 8000. Install, `make update` and `make restart` now remove it before Supabase starts; Envoy keeps the `kong` network alias, so Caddy is unaffected (issue #142).
- **Supabase** - Every `make update` and install handed the whole project directory to the host user, including `supabase/docker/volumes/db/data`, which must belong to the container's `postgres` user: auth, REST and Realtime then failed with `could not open file "global/pg_filenode.map": Permission denied` while `supabase-db` still reported healthy. `08_fix_permissions.sh` now skips the data directories Supabase (`db/data`, `storage`) and Dify (database, Redis, storage, plugin daemon, sandbox dependencies and the data of each optional vector store) keep under their `docker/volumes`; the git-tracked files next to them, such as Supabase edge functions, still go to the user. Affected installs recover on the next `make update`: recreating `supabase-db` gives its files back to `postgres`, and 08 no longer takes them away afterwards. If `supabase-db` keeps running with files it does not own, 08 restores them to the container's `postgres` user, and reports an error if it cannot (issue #143).
- **Supabase** - `IMGPROXY_ENABLE_WEBP_DETECTION` in `.env.example` is renamed to `IMGPROXY_AUTO_WEBP`, the name Supabase's compose file now reads; every Supabase compose call warned that the variable was unset and imgproxy ran without WebP. An existing value is carried over to the new name on `make update` (issue #145).
- **RAGFlow** - Broken since `infiniflow/ragflow:latest` moved to `v1.0.0-rc2`, which needs a kvrocks service the stack does not provide: the backend restarted in a loop, so the UI loaded but every API call failed with a 502. The image is now pinned to `v0.27.2`, the last stable release. If your RAGFlow already started on the release candidate, it migrated its MySQL schema to the 1.0 format and 0.27.2 may not start on it. Resetting RAGFlow deletes all its knowledge bases and uploaded documents; run it after the `make update` to 1.18.0, so the pinned image is already pulled: `docker rm -f ragflow ragflow-mysql ragflow-elasticsearch ragflow-minio ragflow-redis && docker volume rm localai_ragflow_mysql_data localai_ragflow_elasticsearch_data localai_ragflow_minio_data localai_ragflow_redis_data`, then `make restart` (issue #144).
- **Open WebUI** - `WEBUI_SECRET_KEY` changed on every `make update` and `make restart`: Open WebUI generated it into the container layer, outside its volume, so every recreate signed all users out and, with MFA enabled (Open WebUI 0.12), the container stopped starting with `Stored MFA secrets cannot be decrypted`. The key is now generated into `.env` and passed to the container. The `make update` that installs 1.18.0 copies the key the existing container uses into `.env`, so sessions and enrolled MFA keep working; if the container exists but its key cannot be read, or Docker is not reachable, the update stops before anything is restarted and says how to set the key by hand. Until that update has run, `make restart` refuses to run with `open-webui` enabled, because its `down` would lose the key once more. If the key was already lost (the container is crash-looping after an earlier update), clear the stored MFA secrets; with MFA enforced the accounts enroll again on their next sign-in, otherwise they sign in without MFA and re-enable it themselves. With `OPEN_WEBUI_DATABASE=postgres`: `docker exec postgres psql -U postgres -d openwebui -c "UPDATE auth SET mfa = NULL WHERE mfa IS NOT NULL;" && docker restart open-webui`. With SQLite: `docker stop open-webui && docker run --rm -v localai_open-webui:/data alpine sh -c "apk add -q sqlite && sqlite3 /data/webui.db 'UPDATE auth SET mfa = NULL WHERE mfa IS NOT NULL;'" && docker start open-webui` (issue #147).

## [1.17.0] - 2026-10-14

### Added
- **`make pull`** - Pulls the latest images for the selected services without the git sync, package upgrade, `.env` update and wizard of `make update`; run `make restart` afterwards to recreate the containers. Locally built services (n8n, its runners, OpenClaw) are skipped; `make update` rebuilds them.

### Fixed
- **Installer** - `make update` aborted on a transient registry timeout during the image pull, after the git sync, the package upgrade and the `.env` rewrite but before any container was recreated, leaving the install half-updated. A failed pooled pull is now retried one service at a time (3 attempts with backoff; finished layers are cached). If a service still cannot be pulled but its configured image is present locally, the update continues on that image and lists the service at the end with `make pull && make restart`; if the image is not present at all, the update stops before restarting anything. The local n8n/OpenClaw images are now built (with the same retries) before the stack is stopped, so a registry failure there also stops the update with the old stack running. Supabase and Dify still update their repositories and pull changed images during the restart, without retries (issue #140).

## [1.16.4] - 2026-10-10

### Fixed
- **Installer** - `make update` and re-running the installer on an existing host aborted with `402 Payment Required`: `03_generate_secrets.sh` installed the `caddy` package from Caddy's Cloudsmith apt repository on every run just to hash basic-auth passwords, and that repository no longer serves packages or its index. Hashes now come from `caddy hash-password` in the `caddy:2-alpine` image the stack already runs (`docker run --rm`, password over stdin), so no Caddy package is installed on the host. The output is checked to be a bcrypt hash, and hashes are computed before `.env` is rewritten, so a Docker failure leaves `.env` untouched. The leftover Cloudsmith apt source and key are removed before `apt update` runs. The `make update` that installs 1.16.4 still runs the previous `update.sh`: its `apt-get update` prints the 402 errors once and skips the OS package upgrade for that run, while the update itself continues; the next `make update` upgrades packages as usual, and a failed package update is now reported as a warning instead of "updated successfully". A `caddy` package an aborted older run left installed on the host (its `caddy.service` can hold port 80) is reported with `apt purge caddy`, not removed. Existing hashes in `.env` are kept as they are.

## [1.16.3] - 2026-10-10

### Fixed
- **Crawl4AI (security)** - The `crawl4ai` service loaded the whole `.env` via `env_file`, so the crawler container received every variable of the stack, including all secrets (Postgres, JWT/Supabase, n8n, Open Terminal, Qdrant/Weaviate, OpenClaw, Cloudflare Tunnel, the GOST upstream proxy and more). It now gets only `CRAWL4AI_API_TOKEN`, `OPENAI_API_KEY` and the proxy variables; the next `make update` or `make restart` recreates it without the rest. If you added other Crawl4AI settings to `.env` (another LLM provider key, `LLM_PROVIDER`, `CRAWL4AI_*`), move them to `crawl4ai.environment` in `docker-compose.override.yml`. If you have been running the `crawl4ai` profile, treat those values as exposed: rotate external credentials (Cloudflare Tunnel token, OpenRouter and other API keys, bot tokens, SMTP) at the provider; to rotate `OPEN_TERMINAL_API_KEY`, empty it in `.env`, run `make update` (it generates a new key) and re-enter it in Open WebUI under Admin Settings → Integrations → Open Terminal. `POSTGRES_PASSWORD`, `JWT_SECRET` and `N8N_ENCRYPTION_KEY` cannot be rotated by just editing `.env`: Postgres keeps its password in the data volume, `ANON_KEY`/`SERVICE_ROLE_KEY` are signed with `JWT_SECRET`, and a new `N8N_ENCRYPTION_KEY` makes stored n8n credentials unreadable (issue #137).

## [1.16.2] - 2026-10-05

### Fixed
- **Langfuse / RAGFlow** - `make update` aborted with `401 UNAUTHORIZED` for `quay.io/minio/minio` whenever the `langfuse` or `ragflow` profile was active: that repository no longer allows anonymous pulls (MinIO stopped publishing images), and Docker Hub no longer serves `minio/minio` either. The `minio` and `ragflow-minio` services now run `pgsty/silo`, a maintained MinIO fork (also used by RAGFlow upstream) that keeps the data format, so existing buckets are picked up as they are (issue #135).
- **Caddy (security)** - Port `7687` (Neo4j Bolt) was published on `0.0.0.0` on every install, also without the `neo4j` profile, and Docker-published ports bypass ufw. It is now published only while `neo4j` is active (`docker-compose.neo4j.yml`); the next `make update` or `make restart` closes it on installs without Neo4j (issue #134).

## [1.16.1] - 2026-10-02

### Fixed
- **n8n (security)** - `https://<N8N_HOSTNAME>/metrics` was publicly reachable without authentication on every release so far: it exposed the n8n version and process metrics, and since 1.10.0 also every workflow name and ID. Caddy now answers 404 for `/metrics` on the n8n host; Prometheus scrapes n8n over the Docker network, so Grafana dashboards and alerts are unaffected. `make doctor` reports an error if Caddy serves the endpoint, and with the `cloudflare-tunnel` profile also if it is public through the tunnel. The documented tunnel route (`http://n8n:5678`) bypasses Caddy, so `cloudflare-instructions.md` now has a WAF expression to block it (issue #132).

## [1.16.0] - 2026-09-28

### Added
- **Keelflow** - New optional `keelflow` profile: a maintained continuation of Flowise, which is archived upstream and gets no more security fixes. It runs next to Flowise with its own `keelflow_data` volume; `docs/keelflow.md` shows how to move Flowise data over (issue #129).

### Fixed
- **Flowise** - Crash-looped after any install or update that pulled `latest` (3.1.4, image built 2026-07-29): it fails at startup with the default SQLite database (`TypeError: this.db.exec is not a function`) and runs as the non-root `node` user, which ignores the `~/.flowise:/root/.flowise` mount. The image is now pinned to `3.1.3`; flows and credentials in `~/.flowise` are picked up again after `make update`.

## [1.15.1] - 2026-09-23

### Fixed
- **n8n workers** - Lowering `N8N_WORKER_COUNT` now removes the extra `n8n-worker-N` / `n8n-runner-N` containers on install, `make update` or `bash scripts/generate_n8n_workers.sh`; each is stopped gracefully first (up to 30s to finish running executions). Before, the regenerated compose file no longer listed them, so `down` left them running as orphans that kept processing queue jobs. `make doctor` warns about a worker above the configured count.

### Removed
- **scripts/download_top_workflows.sh** - Maintainer-only script that downloaded popular templates from n8n.io; nothing in the installer or Makefile called it. The bundled workflows in `n8n/backup/workflows/` stay.

## [1.15.0] - 2026-09-23

### Added
- **OpenClaw** - Install and `make update` ask for an optional OpenRouter API key (`OPENCLAW_OPENROUTER_API_KEY`, passed to the gateway as `OPENROUTER_API_KEY`; asked again on each `make update` while it is empty; surrounding whitespace is trimmed and a value with characters a key cannot have, such as pasted quotes or inner spaces, is rejected instead of breaking `.env`), so OpenRouter needs no provider or sign-in setup in the dashboard; only the model is picked there (Settings → Models → Defaults for all agents). The dashboard's OpenRouter OAuth cannot complete behind the domain because OpenClaw fixes its callback to `localhost:3000`; `docs/openclaw.md` explains this, shows where the model is picked and warns about the "OpenRouter API key" choice under Arcee AI, which installs a separate plugin whose setup check failed in testing even with a valid key.

## [1.14.2] - 2026-09-23

### Changed
- **Documentation** - README restructured: quick start near the top, services grouped into category tables with their URLs (replacing the separate service list and URL list), and a single Makefile table. Detailed guides moved to `docs/` (`n8n.md`, `n8n-assistant-sandbox.md`, `openclaw.md`, `open-terminal.md`, `ollama-multi-gpu.md`, `open-webui-postgres.md`, `security.md`), content unchanged apart from headings and short intros; installer messages and `.env.example` now point there.

### Fixed
- **make doctor** - The DNS check now covers the hostname of every active profile that has a Caddy site (plus the Welcome Page), instead of a fixed n8n / Grafana / Portainer / Welcome list that was checked whether or not those services were selected. An active service whose hostname is empty or still `*.yourdomain.com` is now a warning instead of being skipped silently, and a missing `host` binary skips the DNS checks with one warning instead of reporting every hostname as unresolvable.

## [1.14.1] - 2026-09-23

### Changed
- **OpenClaw** - The dashboard opens right after the Caddy basic-auth login: no second (gateway) password and no browser approval with `make openclaw a="devices approve ..."` any more. The gateway now runs in OpenClaw's trusted-proxy mode. Caddy passes the authenticated user in `X-Forwarded-User` over a new private `openclaw-proxy` Docker network that only Caddy and OpenClaw join. `openclaw-init` sets `gateway.trustedProxies` to exactly that network's subnet, so containers on the stack's default network cannot forge the header; any process on the host itself (the subnet's gateway address) is trusted too, so do not enable the profile on a server shared with untrusted local users. If the subnet cannot be determined, the trusted-proxy settings are rejected or a stale pre-1.14.1 `openclaw-init` container is reused, `openclaw-init` tries to fall back to the previous password login with no trusted proxy; `make doctor`, `make restart` and the final report of install / `make update` show it. Only `OPENCLAW_USERNAME` is accepted, and new browsers are auto-approved with admin scope. The basic-auth password is now the only key to the agent, and through it to the server. `OPENCLAW_GATEWAY_PASSWORD` remains for the local CLI (`make openclaw a="..."`) and the password-login fallback, and is no longer shown on the Welcome Page. **Upgrading**: `make update` or `make restart` recreate the containers, which attaches Caddy to the new network (with `make start` the dashboard returns 502 until `make restart`); no browser needs approving again.

## [1.14.0] - 2026-09-23

### Added
- **OpenClaw** - New optional `openclaw` profile that adds [OpenClaw](https://docs.openclaw.ai), a personal AI agent with a web dashboard (`OPENCLAW_HOSTNAME`) and a Telegram bot. The dashboard is behind Caddy basic auth (`OPENCLAW_USERNAME` / `OPENCLAW_PASSWORD`) and OpenClaw's own gateway password (`OPENCLAW_GATEWAY_PASSWORD`), all generated by the installer. OpenClaw's device pairing cannot be turned off, so every new browser is approved once with the new `make openclaw a="devices approve <requestId>"` passthrough. The installer asks for an optional Telegram bot token (`OPENCLAW_TELEGRAM_BOT_TOKEN`); DMs keep OpenClaw's pairing policy (`make openclaw a="pairing approve telegram <CODE>"`). A one-shot `openclaw-init` container runs on every `docker compose up` (install, `make update`, `make restart`): it copies the SSH key into a volume owned by the container user and enforces the gateway settings the stack depends on (local mode, LAN bind, password auth, allowed origin, private-range trusted proxies, and Telegram on while a token is set); the rest of the config is left to the dashboard. A failed config update does not stop the rest of the stack. The agent gets full server access by design: the image adds the Docker CLI, the Docker socket is mounted with the socket's group, and `05_configure_services.sh` authorizes a generated SSH key for the installing user (`ssh host` inside the container, using the port sshd really listens on). The key moves with the detected user and is removed from `authorized_keys` by the next install or `make update` with the profile off; the key files stay in `openclaw/ssh/`. A failed `openclaw-init` config update is reported by `make doctor`. The LLM provider is configured in the dashboard.

## [1.13.0] - 2026-09-18

### Added
- **n8n-MCP** - Optional `N8N_MCP_ACCESS_TOKEN` in `.env`, passed to n8n-MCP next to the existing `N8N_API_KEY`. It is the access token of n8n's own MCP server (Settings → Instance-level MCP → Enable MCP access → Connect → API key tab; n8n 2.34 or later, native workflow diff needs 2.36; shown once) and unlocks the tools that the Public API cannot serve: n8n Agents, dynamic node resources (`loadOptions` / `listSearch`), workflow version history, diff and rollback, datatable columns and, on instances without the Enterprise projects licence, team-project discovery. It is a separate secret from the Public API key, which the token's tools still need; the MCP endpoint is derived from `N8N_API_URL` and the stack's `N8N_MCP_WEBHOOK_SECURITY_MODE=permissive` already allows the private origin. Blank keeps the previous Public-API behaviour; set it and run `make restart`. The final report prints the hint while the token is empty (#120).
- **Ollama** - Extra per-instance environment through optional env files. `ollama.env` next to `.env` applies to every instance, `ollama<N>.env` to one instance and overrides `ollama.env`; both are gitignored and applied on the next `make restart` with no regeneration. This is how to set llama.cpp variables such as `LLAMA_ARG_FIT_TARGET` (free-VRAM margin per device, lower it on a GPU dedicated to one instance) or `LLAMA_ARG_CACHE_TYPE_K`, and ROCm knobs like `HSA_OVERRIDE_GFX_VERSION`, per instance. They deliberately do not go through `environment:` with the `${OLLAMA<N>_X:-}` pattern of the other knobs: that hands llama-server an empty value, and an empty `LLAMA_ARG_FIT_TARGET` makes it exit at startup, whereas a missing env file adds nothing. Only llama-server-backed models read `LLAMA_ARG_*`; models on Ollama's own engine ignore them. The `OLLAMA_*` knobs that compose already sets stay in `.env`, whose values win over the files; any other `OLLAMA_*` variable belongs in the files (#121).
- **ComfyUI** - `COMFYUI_GPU_COUNT` and `COMFYUI_GPU_DEVICES` in `.env`, with the same semantics as the InvokeAI and Ollama variables: a GPU count for the NVIDIA variant, or an explicit list of GPU IDs applied through `docker-compose.comfyui-gpu-devices.yml` that the scripts include automatically while the variable is set (#122).

### Changed
- **ComfyUI** - Hardware is now selected in the wizard, like InvokeAI: the single `comfyui` profile is replaced by the mutually exclusive `comfyui-nvidia` (`yanwk/comfyui-boot:cu126-slim`, CUDA 12.6 - the previously used `cu128-slim` is archived upstream), `comfyui-amd` (`yanwk/comfyui-boot:rocm`, `/dev/kfd` + `/dev/dri`) and `comfyui-cpu` (`yanwk/comfyui-boot:cpu`) profiles; the container is still named `comfyui`, so the Caddy route is unchanged. **Upgrading**: `make update` runs the wizard, which pre-selects ComfyUI for the old `comfyui` profile and defaults the hardware prompt to CPU (the previous behaviour) - pick NVIDIA or AMD there - and removes the old `comfyui` container, which `docker compose down` would otherwise leave behind as an orphan that blocks the renamed service with `container name "/comfyui" is already in use`. Installations that pull without the wizard must set one of the `comfyui-*` profiles in `COMPOSE_PROFILES` by hand, otherwise no ComfyUI container starts (#122).

### Fixed
- **Langfuse / RAGFlow** - `make update` failed at the image pull with `pull access denied for minio/minio, repository does not exist`: MinIO removed its Docker Hub repositories in September 2026 (the community edition is now source-only). Both `minio` and `ragflow-minio` now pull `quay.io/minio/minio:latest`, which currently resolves to the last published community image, `RELEASE.2025-09-07T16-13-09Z`; the community edition is no longer published as an image, so MinIO will not receive further updates from upstream unless that tag moves. Existing data volumes are untouched (#119).
- **ComfyUI** - Ran on the CPU and lost everything on recreate. The CUDA image was started with `--cpu` and without a GPU reservation, and the persistent volume was mounted on `/home/runner`, the non-root layout of the archived `cu121` image that this stack never used; every tag shipped here (`cu124-slim`, `cu128-slim`) runs as root, copies the bundled ComfyUI to `/root/ComfyUI` on first start and keeps models, custom nodes and user data under `/root`, so every `docker compose down` / `up` started from a fresh bundle. The volume is now mounted on `/root`, the NVIDIA variant reserves a GPU, and `CLI_ARGS` is no longer set in compose: each image ships the right default (`--cpu` baked into the CPU image, empty on the GPU images) and the entrypoint already adds `--listen`. The old volume never received data, so nothing needs migrating. Because ComfyUI's own code now lives in the volume, it is updated through ComfyUI-Manager rather than by pulling the image; the final report says so (#122).

## [1.12.0] - 2026-09-11

### Added
- **Open Terminal** - New optional `open-terminal` profile (requires `open-webui`) that adds [Open Terminal](https://github.com/open-webui/open-terminal), an execution environment for Open WebUI agents: a Linux shell with a persistent home, runtime apt/pip/npm installs, local services with port proxying and Jupyter kernels, so an agent can produce an artifact instead of describing how to. Internal only (`http://open-terminal:8000`, no Caddy route); the admin connects it once under Admin Settings → Integrations → Open Terminal with the generated `OPEN_TERMINAL_API_KEY`, and grants access to users or groups there. Multi-user mode is on by default (one unprivileged Linux account per Open WebUI user, volume on `/home`; the installer refuses a `slim`/`alpine`/`openshift` tag in that mode because those images ignore it), CPU/memory limits are tunable via `OPEN_TERMINAL_CPU_LIMIT` / `OPEN_TERMINAL_MEMORY_LIMIT`. Egress filtering is left to `docker-compose.override.yml` because the image reads an empty `OPEN_TERMINAL_ALLOWED_DOMAINS` as "block everything" and needs `NET_ADMIN`. (#117)

## [1.11.0] - 2026-09-09

### Added
- **n8n Assistant sandbox** - New optional `n8n-sandbox` profile that adds n8n's own code-execution sandbox (`sandbox-certs`, `sandbox-api`, `sandbox-runner-1` from n8n-sandbox-service) so the built-in AI Assistant works on self-hosted n8n (and the Agents preview, except its knowledge base, which needs Daytona); until now the Instance AI settings page showed `Code sandbox: Not set`. The installer wires `N8N_INSTANCE_AI_SANDBOX_ENABLED`, the sandbox URL and key into n8n, generates the three shared secrets, and points `N8N_INSTANCE_AI_SEARXNG_URL` at the bundled SearXNG while that profile is active; the model API key is added in the n8n UI (Settings → Instance AI). The Docker-in-Docker runner is isolated with Sysbox: `scripts/setup_sysbox.sh` installs `sysbox-ce` non-interactively without restarting Docker (it pre-seeds `bip`/`default-address-pools` in `daemon.json` with Docker's current values) and the runner gets `runtime: sysbox-runc`. When Sysbox cannot be installed the installer asks before falling back to a privileged runner, records the choice in `N8N_SANDBOX_RUNNER_RUNTIME` / `N8N_SANDBOX_RUNNER_PRIVILEGED`, and `make doctor` warns while the runner is privileged. `N8N_ENABLED_MODULES` is exposed (empty by default) for the Agents preview. (#114)

## [1.10.1] - 2026-09-02

### Fixed
- **Monitoring** - Upgrading an existing installation to 1.10.0 left Grafana in a restart loop with `Datasource provisioning error: data source not found`. The Prometheus data source already existed with a random uid, and Grafana cannot change the uid of an existing data source when provisioning pins one. The provisioning file now deletes the data source by name before recreating it with the fixed uid `Prometheus`; dashboards and alert rules reference the uid, so nothing is lost. Fresh installations were not affected.

## [1.10.0] - 2026-09-02

### Added
- **Monitoring** - The n8n Grafana dashboard now shows whether workflows actually run, not just whether the n8n process is healthy. n8n is started with `N8N_METRICS_INCLUDE_MESSAGE_EVENT_BUS_METRICS`, `N8N_METRICS_INCLUDE_WORKFLOW_ID_LABEL`, `N8N_METRICS_INCLUDE_WORKFLOW_NAME_LABEL` and `N8N_METRICS_INCLUDE_WORKFLOW_INFO`, which expose `n8n_workflow_started/success/failed/cancelled_total` counters labelled per workflow plus id-to-name gauges, and a new "Workflow Executions" section adds three panels: executions by outcome over time, executions per workflow, and time since each active workflow's last successful execution. The last one is backed by Prometheus recording rules in `prometheus/rules/n8n-workflows.yml` that remember the last non-manual success per workflow for 30 days and follow renames. Four Grafana-managed alert rules are provisioned from `grafana/provisioning/alerting/n8n-workflows.yml`: "n8n workflow failed" (a non-manual execution failed in the last 15 minutes - runs from the editor are excluded), "n8n workflow stalled" (an active workflow has had no success for 24 hours), "n8n workflow has no recorded success" (active for 24 hours without ever succeeding since monitoring started - catches workflows that were already broken at upgrade time) and "n8n metrics target down" (Prometheus cannot scrape n8n or a worker). The 24-hour thresholds are global and tunable in that file; provisioned rules are read-only in the UI. Alerts follow Grafana's default notification policy, whose built-in email contact point delivers nothing without SMTP - create a contact point and select it under Alerting > Notification policies. The Prometheus data source now has the fixed uid `Prometheus` that the dashboards and rules reference (#110).

### Fixed
- **Monitoring** - Prometheus never scraped the n8n workers: the `n8n-worker` job targeted a hostname that does not exist (containers are `n8n-worker-1`, `n8n-worker-2`, ...) on the task-broker port 5679 instead of the metrics port 5678. `scripts/generate_n8n_workers.sh` now writes `prometheus/targets/n8n.json` with the n8n main target and one target per worker, read by Prometheus via `file_sd_configs`, so the target list follows `N8N_WORKER_COUNT` automatically. The generator runs on every install and update and removes the file when n8n is deselected, so a monitoring-only install no longer carries a permanently-down `n8n:5678` target. `make doctor` reports a missing or outdated targets file and a failing recording rule (#110).
- **Doctor** - `make doctor` could never report Grafana or Prometheus as down: the check was gated on a profile named after the container, but both belong to the `monitoring` profile. The check now takes the enabling profile explicitly.
- **n8n** - `docker compose build` failed on `n8n/Dockerfile.runner` with `/bin/sh: pnpm: Permission denied` (exit code 126). The upstream `n8nio/runners:stable` image rebuilt on 2026-09-02 ships `pnpm.cjs` without the execute bit (pnpm 11.22.0), so the `pnpm add cheerio axios moment lodash` step could not start even as root. The Dockerfile now restores the bit on the symlink target before running pnpm; the fix is a no-op once upstream republishes a correct image (#111).

## [1.9.0] - 2026-08-27

### Added
- **n8n-MCP** - New optional service (`n8n-mcp` profile): a Model Context Protocol server that exposes n8n's full node catalogue, property schemas and workflow templates to AI coding assistants, plus workflow-management tools once an n8n API key is configured. Served at `n8n-mcp.<domain>` behind a generated `N8N_MCP_AUTH_TOKEN` Bearer token. Caddy gates on the same token the service itself validates, because HTTP carries a single `Authorization` header and MCP clients send only a Bearer token - basic auth would make the endpoint unusable for every client. Ships in documentation-only mode; create an API key in n8n under Settings > n8n API, set `N8N_API_KEY` in `.env` and run `make restart` to unlock workflow management. Connect with `npx -y mcp-remote https://n8n-mcp.<domain>/mcp --header "Authorization: Bearer <token>"`. Note that outside n8n Enterprise an API key grants full account access (#104).
- **Ollama** - Optional multiple instances for multi-GPU hosts. Set `OLLAMA_INSTANCE_COUNT` in `.env` (1-8) to run `ollama2`, `ollama3`, ... alongside the existing `ollama` container, each pinnable to its own GPU so a large model stays resident instead of being swapped out. The runtime tuning variables (`KEEP_ALIVE`, `NUM_PARALLEL`, `MAX_LOADED_MODELS`, `CONTEXT_LENGTH`, `KV_CACHE_TYPE`, `GPU_OVERHEAD`, `SCHED_SPREAD`) can be set per instance with an `OLLAMA<N>_` prefix (e.g. `OLLAMA2_KEEP_ALIVE=-1`) and fall back to the global value when unset, taking effect on the next `make restart`. `OLLAMA<N>_GPU_DEVICES` is the exception: it selects that instance's GPU, defaults to GPU N-1, and does not read the global `OLLAMA_GPU_DEVICES`. All instances share one model store, so each model is downloaded once. Extra instances are internal only (`http://ollama2:11434`) with no published ports, matching the rest of the stack; use `caddy-addon/site-*.conf` to expose one externally. The default of `1` generates nothing, so existing installs are unchanged. Set `OLLAMA_GPU_DEVICES` as well when running several instances, otherwise the first one is unpinned and may collide with `ollama2` - `make doctor` warns about this (#107).

### Changed
- **Open WebUI** - New installations now store chats, users and settings in the stack's shared PostgreSQL instead of SQLite, removing the `sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) database is locked` failures that appear with several tabs or devices open, and placing the data in the same backup as the rest of the stack. **Existing installations are deliberately left on SQLite**: Open WebUI does not migrate data between backends, so switching would present an empty interface while the old chats stayed in `webui.db`. To opt in, set `OPEN_WEBUI_DATABASE=postgres` in `.env` and run `make restart`; see the README for the required volume backup and the migration tooling. Uploaded files and the vector store stay in the `open-webui` volume in both modes (#105).

### Fixed
- **NocoDB** - Fix "Connection to internal hosts is not allowed" (older builds: "Forbidden host name or IP address") when adding the stack's own PostgreSQL, or any container, as an external data source. NocoDB 2026.05.2 added SSRF protection that rejects any data-source host resolving to a private IP range, which covers every hostname on the Docker network, so this broke silently for anyone who updated after that release. `NC_ALLOW_LOCAL_EXTERNAL_DBS=true` is now set for the nocodb service; its webhook and data-import SSRF protections are deliberately left enabled. Connect with host `postgres`, port `5432`, user `postgres` and the `POSTGRES_PASSWORD` from `.env` (#106).

### Security
- **Supabase** - The API gateway host port is now bound to loopback by default (`API_GW_HTTP_PORT=127.0.0.1:8000`) instead of `0.0.0.0:8000`, where it attracted continuous internet-wide scanning for no functional benefit. External access already went through Caddy, which reaches the gateway over the Docker network via the `kong` alias upstream kept after switching from Kong to Envoy, and host-local tooling on `http://localhost:8000` is unaffected. Existing installs are migrated automatically on the next `make update` or `make restart`: the new key is force-synced into `supabase/docker/.env`, which is the file Compose actually interpolates from, and the legacy `KONG_HTTP_PORT`/`KONG_HTTPS_PORT` keys are rewritten only when still on their insecure defaults. Set `API_GW_HTTP_PORT` to a plain port or a LAN address to expose it deliberately. `make doctor` gains an Exposed Ports section that warns when the gateway binds to all interfaces. Note that Supabase's upstream compose still publishes `0.0.0.0:5432` and `0.0.0.0:6543` for Postgres and the Supavisor pooler, and that Docker's published ports bypass `ufw` entirely - restrict those at your cloud provider's firewall; see the new Security Notes section in the README (#108).

## [1.8.2] - 2026-07-24

### Added
- **Ollama** - Two more runtime knobs are now configurable via `.env`: `OLLAMA_SCHED_SPREAD` (set to `1` to spread every model across all GPUs instead of packing each onto one GPU - packing can strand free VRAM on a multi-GPU host until a model fits nowhere and falls back to slow CPU/GPU hybrid execution) and `OLLAMA_KEEP_ALIVE` (how long an idle model stays in VRAM, e.g. `20m`, for faster switching between frequently used models). Both default to empty, so Ollama's stock behavior (spread off, keep-alive 5m) is unchanged for existing installs (#102).

## [1.8.1] - 2026-07-23

### Added
- **Ollama** - Runtime tuning via `.env`: `OLLAMA_MAX_LOADED_MODELS`, `OLLAMA_NUM_PARALLEL`, `OLLAMA_GPU_OVERHEAD` (in bytes), `OLLAMA_CONTEXT_LENGTH` and `OLLAMA_KV_CACHE_TYPE` were hardcoded (or unavailable) in `docker-compose.yml` and are now configurable, so multi-GPU hosts can keep more models resident and reserve VRAM for other tools sharing a GPU. The previously hardcoded values stay as the stack's defaults, and the two new variables are unset/zero by default so Ollama's stock behavior applies — existing installs are unaffected (#99).
- **Caddy** - `host.docker.internal` now resolves from the Caddy container (via `extra_hosts: host-gateway`), so custom `caddy-addon/site-*.conf` entries can reverse-proxy services running on the host machine.

### Changed
- **Docs** - README now documents the update-safe extension points (`caddy-addon/site-*.conf`, `docker-compose.override.yml`, `.env`), and `caddy-addon/README.md` gained a reverse-proxy example for stack-external services. The persistent-Caddy-entries mechanism requested in #100 already existed but was easy to miss (#100).

## [1.8.0] - 2026-07-20

### Added
- **Ollama / InvokeAI** - Optional GPU pinning for multi-GPU hosts. Set `OLLAMA_GPU_DEVICES` / `INVOKEAI_GPU_DEVICES` in `.env` (e.g. `OLLAMA_GPU_DEVICES=1,2`) to restrict a service to specific NVIDIA GPU IDs, so different workloads can own different GPUs. When the variable is empty (default), the existing count-based `*_GPU_COUNT` behavior is unchanged. NVIDIA profiles only (AMD variants use full `/dev/kfd`/`/dev/dri` passthrough); requires Docker Compose v2.24.4+ (#83).

### Removed
- **Hermes Agent** - **Breaking:** removed from the stack. An infrastructure-management agent should not run inside the environment it manages: it blurs the security boundary, couples the management layer to the workloads it controls, and creates a circular dependency (Hermes managing the Docker stack it lives in). On the next `make update`, the `hermes` profile is dropped from `COMPOSE_PROFILES` and the container is removed automatically; the data directory `./hermes` is left untouched so you can redeploy Hermes standalone with your own security model, and existing `HERMES_*` values in `.env` are kept under the preserved-variables section in case the standalone deployment needs them (delete them manually if not). If your `docker-compose.override.yml` still has a `hermes:` block, the updater warns you to delete it (#88).

### Fixed
- **Installer** - `make update` no longer silently deletes `.env` variables that are missing from `.env.example`. Custom user variables, uncommented opt-ins (e.g. `SCARF_ANALYTICS=false`), and the telemetry `INSTALLATION_ID` (which previously churned on every update) now survive updates: after the template pass, any variable found only in the old `.env` is re-appended under a `# --- Preserved user variables (not in template) ---` section, idempotently across repeated updates (#90).
- **Crawl4AI** - Fix the service being unreachable from other containers (n8n got `ECONNREFUSED` on `http://crawl4ai:11235`). Crawl4AI 0.9+ binds to `127.0.0.1` unless an API token is set, and upstream offers no bind-only override. A `CRAWL4AI_API_TOKEN` is now auto-generated and passed to the container, so it listens on the Docker network again; clients must send `Authorization: Bearer <token>` (token shown on the Welcome Page). Existing installs get the token generated on the next `make update` (#84).
- **Healthchecks** - Fix six services being reported `unhealthy` while running fine. LightRAG, ComfyUI, Appsmith, Gotenberg and Databasus used `wget`, which does not exist in their images; each now probes with a tool the image actually ships (curl for Appsmith/Gotenberg, python for ComfyUI/LightRAG, the native `databasus healthcheck` command for Databasus - verified against each upstream Dockerfile). PaddleOCR probed `/` (returns 404) and now probes `/health` (#85).
- **RagFlow** - Fix startup crash-loop (`nginx: [emerg] open() "/etc/nginx/conf.d/ragflow.conf" failed`). The real cause: the `ragflow_data:/ragflow` named volume masked the whole application directory with files from an older image, including a stale entrypoint. The volume and the obsolete custom nginx config are removed; the image now manages its own nginx config, and RagFlow state lives in its MySQL/Elasticsearch/MinIO/Redis services as upstream intends. The old `localai_ragflow_data` volume is left on disk (harmless; reclaim with `docker volume rm localai_ragflow_data` after a successful start) (#86).
- **python-runner** - Fix the default container restart-looping forever: the stock `main.py` printed one line and exited, and `restart: unless-stopped` kept restarting it, tripping `make doctor` warnings. The default script now stays alive with an idle loop, and the service uses `init: true` + `exec` so SIGTERM reaches Python directly and stops/updates are immediate instead of hanging until SIGKILL. Custom `main.py` files are preserved across updates as before (#87).

## [1.7.2] - 2026-07-13

### Fixed
- **Ollama / InvokeAI** - Fix `make update` resetting custom multi-GPU setups back to a single GPU. The NVIDIA GPU count was hardcoded as `count: 1` in `docker-compose.yml`, so any manual edit was wiped by the update's git reset. The count is now read from `.env` (`OLLAMA_GPU_COUNT` and `INVOKEAI_GPU_COUNT`, default `1`; set a number or `all`), which survives updates - the variables are added to existing `.env` files automatically on the next `make update` (#81).

## [1.7.1] - 2026-07-09

### Changed
- **Project renamed to Selfhost AI** - The repository moved from `kossakovsky/n8n-install` to [`kossakovsky/selfhost-ai`](https://github.com/kossakovsky/selfhost-ai) to reflect that the stack has grown well beyond n8n. GitHub redirects all old links and git remotes automatically, so existing installations keep working without changes. On the next `make update`, remotes still pointing at an old URL are repointed to the new one automatically (protocol preserved; fork remotes are never touched - only remotes targeting the canonical `kossakovsky/n8n-install` or the project's original name `kossakovsky/n8n-installer` are rewritten). The installer handles clones under all three directory names. Prefer updating in place (`make update`); if you migrate to a fresh clone instead, copy `.env` and the `supabase/`/`dify/` directories from the old checkout - Docker volumes are reused automatically, but secrets and external-stack data live in those files.

### Fixed
- **Installer** - The nested-clone cleanup in `install.sh` now verifies that the parent directory is actually a copy of this repository before removing anything. Previously, cloning into a same-named plain folder (e.g. `~/selfhost-ai/selfhost-ai`) made the installer delete the fresh clone (including `.env` with generated secrets on re-runs) and exit silently. The unreachable re-exec probe was replaced with an unconditional restart from the surviving outer copy.

## [1.7.0] - 2026-07-09

### Added
- **InvokeAI** - Professional Stable Diffusion studio with web UI, workflow editor, and REST API. Selectable NVIDIA/AMD/CPU hardware profiles (`invokeai-nvidia`, `invokeai-amd`, `invokeai-cpu`), protected by Caddy basic auth; models and outputs stored in `./invokeai` (#72)
- **Hermes Agent** - Autonomous AI agent platform by Nous Research (skills, persistent memory, MCP, multi-agent workflows) as an optional `hermes` profile. Web dashboard at `HERMES_HOSTNAME` (protected by Hermes's built-in basic auth with generated credentials) and OpenAI-compatible API at `HERMES_API_HOSTNAME` / `http://hermes:8642/v1` (Bearer `HERMES_API_SERVER_KEY`), so n8n workflows can call it like any OpenAI endpoint. Persistent data lives in `./hermes` (gitignored) for direct editing of `.env`, `config.yaml`, skills, and memories; configure an LLM provider via `docker compose -p localai run --rm hermes setup` (#71).
- **Cloudflare Tunnel** - Configurable transport protocol via `CLOUDFLARE_TUNNEL_PROTOCOL` in `.env`: `auto` (default, prefers QUIC with HTTP/2 fallback), `quic`, or `http2`. Set `http2` if your ISP or firewall blocks UDP and the tunnel is unstable (#69).

### Changed
- **Docker Compose** - Wrap all `${VARIABLE}` interpolations in double quotes to guard against YAML parsing issues with special characters in inline default values and keep the quoting style consistent across the file. No functional change: the rendered `docker compose config` output is identical (#70).

### Fixed
- **Installer** - Fail fast with a clear error when bcrypt hash generation fails during secret generation (affects all services behind Caddy basic auth). Previously an empty hash was written silently, which either broke Caddy config parsing on startup (taking down every service) or left the service behind a deny-all basic auth with no error surfaced.
- **Hermes Agent** - Add the missing `make update-preview` entry and Cloudflare Tunnel routing rows for the Hermes hostnames; `make doctor` now reports an error when the `hermes` profile is active but `HERMES_API_SERVER_KEY` is empty (the API server refuses to start without it, leaving the container half-dead).

## [1.6.0] - 2026-07-01

### Added
- **Ollama** - Optionally expose the Ollama API through Caddy under `OLLAMA_HOSTNAME`, protected by a generated Bearer token (`OLLAMA_CADDY_API_TOKEN`). Lets external tools reach locally-hosted models (native `/api/*` and OpenAI-compatible `/v1/*` endpoints); point DNS at the hostname to activate. Requests must send `Authorization: Bearer <token>`; unauthorized requests get `401`. A leaked token grants full control (including pulling/deleting models), so `make doctor` now reports an error if the hostname is set but the token is empty (#67).

## [1.5.2] - 2026-06-27

### Fixed
- **n8n** - Fix `ERR_ERL_UNEXPECTED_X_FORWARDED_FOR` thrown by `express-rate-limit` behind the Caddy reverse proxy. The compose file set `N8N_TRUST_PROXY: true`, which n8n does not recognize, so Express `trust proxy` stayed `false`. Replaced it with the correct `N8N_PROXY_HOPS` (number of reverse proxy hops, default `1`, overridable via `.env` for multi-proxy setups) (#65).

## [1.5.1] - 2026-06-17

### Fixed
- **Supabase** - Fix `make update` breaking existing databases by silently upgrading Postgres across major versions (e.g. `15.8.1.085` → `17.6.1.136`), which left `supabase-db` `unhealthy` and aborted the update. The installer now detects the major version of the data already on disk and pins `supabase/postgres` to a compatible tag after pulling upstream changes. Fresh installs continue to follow upstream (PG17); existing PG15 volumes stay on PG15 until you migrate manually (#64).

## [1.5.0] - 2026-05-17

### Fixed
- **cAdvisor** - Fix memory leak and uncontrolled CPU growth (up to ~3.5 GB RAM / 168% CPU on hosts with ~40+ containers) by pinning image to `v0.55.1`, adding resource limits (`mem_limit: 1g`, `cpus: "1.0"`), and tuning runtime flags (`--housekeeping_interval=10s`, `--docker_only=true`).
- **NocoDB** - Fix `Missing process handler for job type job` errors in n8n queue caused by NocoDB sharing the default Bull queue `jobs` with n8n in Redis db0. NocoDB is now isolated to Redis db1 via `NC_REDIS_URL=redis://redis:6379/1`.
- **Dify** - Fix install never starting (`could not translate host name "db_postgres"`) by activating Dify's bundled compose profiles (`postgresql`, `weaviate`) when starting the stack, and passing all Dify profiles when tearing it down so containers like `db_postgres` and `weaviate` get stopped cleanly (#61).
- **n8n** - Namespace Bull queue (`QUEUE_BULL_PREFIX=n8n`) to prevent neighbour conflicts, raise task runner timeout to 300s, and disable runner auto-shutdown to fix `Missing process handler` and `Task request timed out` errors. Default `N8N_RUNNERS_MAX_CONCURRENCY` raised 5 → 10. All four values configurable via `.env`.

## [1.4.3] - 2026-04-27

### Fixed
- **LightRAG** - Fix crash-loop (`TOKEN_SECRET must be explicitly set`) by generating `LIGHTRAG_TOKEN_SECRET` and passing it as `TOKEN_SECRET` to the container. Recent upstream releases require an explicit JWT signing secret whenever `AUTH_ACCOUNTS` is configured (#60).

## [1.4.2] - 2026-03-28

### Fixed
- **n8n** - Make `N8N_PAYLOAD_SIZE_MAX` configurable via `.env` (was hardcoded to 256, ignoring user overrides)
- **Uptime Kuma** - Fix healthcheck failure (`wget: not found`) by switching to Node.js-based check

## [1.4.1] - 2026-03-23

### Fixed
- **Supabase Storage** - Fix crash-loop (`Region is missing`) by adding missing S3 storage configuration variables (`REGION`, `GLOBAL_S3_BUCKET`, `STORAGE_TENANT_ID`) from upstream Supabase
- **Supabase** - Sync new environment variables to existing `supabase/docker/.env` during updates (previously only populated on first install)

## [1.4.0] - 2026-03-15

### Added
- **Uptime Kuma** - Self-hosted uptime monitoring with 90+ notification services
- **pgvector** - Switch PostgreSQL image to `pgvector/pgvector` for vector similarity search support

## [1.3.3] - 2026-02-27

### Fixed
- **Postiz** - Generate `postiz.env` file to prevent `dotenv-cli` crash in backend container (#40). Handles edge case where Docker creates the file as a directory, and quotes values to prevent misparses.

## [1.3.2] - 2026-02-27

### Fixed
- **Docker Compose** - Respect `docker-compose.override.yml` for user customizations (#44). All compose file assembly points now include the override file when present.

## [1.3.1] - 2026-02-27

### Fixed
- **Installer** - Skip n8n workflow import and worker configuration prompts when n8n profile is not selected

## [1.3.0] - 2026-02-27

### Added
- **Appsmith** - Low-code platform for building internal tools, dashboards, and admin panels

## [1.2.8] - 2026-02-27

### Fixed
- **Ragflow** - Fix nginx config mount path (`sites-available/default` → `conf.d/default.conf`) to resolve default "Welcome to nginx!" page (#41)

## [1.2.7] - 2026-02-27

### Fixed
- **Docker** - Limit parallel image pulls (`COMPOSE_PARALLEL_LIMIT=3`) to prevent `TLS handshake timeout` errors when many services are selected

## [1.2.6] - 2026-02-10

### Changed
- **ComfyUI** - Update Docker image to CUDA 12.8 (`cu128-slim`)

## [1.2.5] - 2026-02-03

### Fixed
- **n8n** - Use static ffmpeg binaries for Alpine/musl compatibility (fixes glibc errors)

## [1.2.4] - 2026-01-30

### Fixed
- **Postiz** - Fix `BACKEND_INTERNAL_URL` to use `localhost` instead of Docker hostname (internal nginx requires localhost)

## [1.2.3] - 2026-01-29

### Fixed
- **Gost proxy** - Add Telegram domains to `GOST_NO_PROXY` bypass list for n8n Telegram triggers

## [1.2.2] - 2026-01-26

### Fixed
- **Custom TLS** - Fix duplicate hostname error when using custom certificates. Changed architecture from generating separate site blocks to using a shared TLS snippet that all services import.

## [1.2.1] - 2026-01-16

### Added
- **Temporal** - Temporal server and UI for Postiz workflow orchestration (#33)

## [1.2.0] - 2026-01-12

### Added
- Changelog section on Welcome Page dashboard

## [1.1.0] - 2026-01-11

### Added
- **Custom TLS certificates** - Support for corporate/internal certificates via `caddy-addon/` mechanism
- New `make stop` and `make start` commands for stopping/starting all services without restart
- New `make setup-tls` command and `scripts/setup_custom_tls.sh` helper script for easy certificate configuration
- New `make git-pull` command for fork workflows - merges from upstream instead of hard reset

## [1.0.0] - 2026-01-07

### Added
- First official stable release

## [0.38.0] - 2026-01-04

### Fixed
- Gost proxy bypass for Supabase internal services

## [0.37.0] - 2026-01-02

### Added
- Workflow import command (`make import`)

## [0.36.0] - 2025-12-28

### Changed
- Postgresus renamed to Databasus with new Docker image `databasus/databasus:latest`
- Now supports PostgreSQL, MySQL, MariaDB, and MongoDB backups

## [0.35.0] - 2025-12-25

### Added
- Anonymous telemetry via Scarf (opt-out with `SCARF_ANALYTICS=false`)

## [0.34.0] - 2025-12-25

### Added
- NocoDB - Open source Airtable alternative with spreadsheet database interface

## [0.33.0] - 2025-12-22

### Fixed
- Static ffmpeg binary for n8n 2.1.0+ compatibility (apk removed upstream)

## [0.32.0] - 2025-12-21

### Fixed
- Healthcheck proxy bypass for localhost connections

## [0.31.0] - 2025-12-20

### Added
- Gost proxy - HTTP/HTTPS proxy for AI services outbound traffic (geo-bypass)

## [0.30.0] - 2025-12-11

### Added
- Doctor diagnostics - System health checks and troubleshooting
- Update preview - Preview changes before applying updates
- Wizard service groups for better organization

## [0.29.0] - 2025-12-12

### Fixed
- Open-webui healthcheck with longer start_period

## [0.28.0] - 2025-12-11

### Added
- Welcome page dashboard with service credentials and quick start

## [0.27.0] - 2025-12-09

### Fixed
- n8n v2.0 migration review issues

## [0.26.0] - 2025-12-09

### Added
- n8n 2.0 support with worker-runner sidecar pattern
- Makefile for common project commands (`make install`, `make update`, `make logs`, etc.)

### Changed
- Task execution now uses dedicated runners per worker
- Workers and runners generated dynamically via `scripts/generate_n8n_workers.sh`

## [0.25.0] - 2025-12-08

### Changed
- n8n Dockerfile updated to use stable version 2.0.0

## [0.24.0] - 2025-11-09

### Added
- Docling - Universal document converter to Markdown/JSON

## [0.23.0] - 2025-11-01

### Added
- LightRAG - Graph-based RAG with knowledge graphs

## [0.22.0] - 2025-10-29

### Added
- RAGFlow - Deep document understanding RAG engine

## [0.21.0] - 2025-10-15

### Added
- WAHA - WhatsApp HTTP API (NOWEB engine)

## [0.20.0] - 2025-08-28

### Added
- Postgresus - PostgreSQL backups & monitoring

## [0.19.0] - 2025-08-28

### Added
- LibreTranslate - Self-hosted translation API (50+ languages)

## [0.18.0] - 2025-08-27

### Added
- PaddleOCR - OCR API Server

## [0.17.0] - 2025-08-19

### Added
- Postiz - Social publishing platform

## [0.16.0] - 2025-08-15

### Added
- Python Runner - Custom Python code execution environment

## [0.15.0] - 2025-08-15

### Added
- RAGApp - Open-source RAG UI + API

## [0.14.0] - 2025-08-13

### Added
- Cloudflare Tunnel - Zero-trust secure access

## [0.13.0] - 2025-08-07

### Added
- ComfyUI - Node-based Stable Diffusion UI

## [0.12.0] - 2025-08-07

### Added
- Portainer - Docker management UI

## [0.11.0] - 2025-08-06

### Added
- Gotenberg - Document conversion API (internal use)

## [0.10.0] - 2025-08-06

### Added
- Dify - AI Application Development Platform with LLMOps

## [0.9.0] - 2025-06-17

### Added
- Qdrant Caddy reverse proxy configuration

## [0.8.0] - 2025-05-28

### Added
- Monitoring stack - Prometheus, Grafana, cAdvisor, node-exporter

## [0.7.0] - 2025-05-26

### Added
- Neo4j - Graph database

## [0.6.0] - 2025-05-24

### Added
- Weaviate - Vector database with API Key Auth

## [0.5.0] - 2025-05-22

### Added
- Qdrant - Vector database

## [0.4.0] - 2025-05-15

### Added
- Ollama - Local LLM inference

## [0.3.0] - 2025-05-15

### Added
- Letta - Agent Server & SDK

## [0.2.0] - 2025-05-09

### Added
- Interactive service selection wizard using whiptail
- Profile-based service management via Docker Compose profiles

## [0.1.0] - 2025-04-18

### Added
- Langfuse - LLM observability and analytics platform
- Initial fork from coleam00/local-ai-packager with enhanced service support

---

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).