`deploy/Dockerfile` copies skills, design-systems, craft, prompt-templates,
assets and plugins/_official, but not data/ — so
`data/plugin-previews/manifest.json`, which CI commits precisely so deployments
can find the bakes, is absent at runtime. `resolvePluginPreviewsDir()` defaults
to <projectRoot>/data/plugin-previews, `loadManifest()` returns {},
`applyBakedPreviews()` returns the records untouched, and
`inferPluginPreview(record, { preferBaked: true })` falls through to the live
iframe for every plugin.
Measured on 0.19.2 with 461 registered plugins: the checked-in manifest has 176
entries and 0 records carried od.bakedPreview. With data/ present the same
daemon reports 176 — deck 79, prototype 79, video 10, scenario 4, image 1,
audio 1, template 2. The packaged app reaches the manifest through its own
packaging path, so only Docker/self-hosted deployments are affected.
Also warn once per path when the manifest is absent. `loadManifest()` already
carries the reasoning for the malformed case — «would otherwise silently
disable every baked preview with no trace; surface it so it's diagnosable» —
but the absent branch returned {} with no message, which is the same failure
with the same lack of trace.
Fixes#7018
Co-authored-by: Jason <>
* chore: unify product name display to OpenDesign repo-wide
Rename the user-facing product name from "Open Design" to "OpenDesign"
across documentation, web/desktop UI strings, i18n locales, prompts,
plugin/skill/design-system content, changelogs, and specs, matching the
landing-page rename already in flight.
Deliberately excluded so installed-app identity stays untouched:
- packages/release PRODUCT_NAME and everything derived from it
(app bundle names, installer/registry identity, updater feeds)
- tools/pack, tools/release, apps/packaged, landing page (PR #6983)
- mocks/ recorded traces and LICENSE
- test fixtures and comments that encode real on-disk install paths
(Open Design.app, Program Files\Open Design, AppData paths)
Validated with pnpm guard, pnpm typecheck, and targeted web/desktop/host
test runs over the renamed strings.
* fix(web): keep two-letter author monogram for CamelCase brand names
authorInitials split words on whitespace only, so the renamed single-token
author name "OpenDesign" produced a one-letter monogram. Treat lower-to-upper
CamelCase boundaries as word breaks so the avatar fallback stays "OD".
* fix(release): restore spaced Windows source artifact names in win.ps1
tools/pack still derives builder outputs from the unchanged PRODUCT_NAME
("Open Design"), so the asset script must look for the spaced filenames.
Matches the mac/mac-intel/linux asset scripts, which were already kept on
the original names.
---------
Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
* fix(deploy): use network_mode host to fix loopback guard on Linux Docker
* fix(deploy): address review feedback — wire OD_PORT and tighten auth note
* fix(deploy): wire OD_PORT in Linux override and include linux override in systemd unit and updater
* fix(deploy): lock OD_BIND_HOST to loopback for host networking in Linux
* fix(deploy): add support for mounting host agent CLIs in Linux and extend Dockerfile for glibc compatibility
* fix(deploy): update user in Dockerfile and docker-compose for compatibility with glibc and ownership adjustments
* fix(docs): update Codex install path in README for clarity
---------
Co-authored-by: kemycrome <luca.gernone@gmail.com>
* fix(deploy): use network_mode host to fix loopback guard on Linux Docker
* fix(deploy): address review feedback — wire OD_PORT and tighten auth note
* fix(deploy): wire OD_PORT in Linux override and include linux override in systemd unit and updater
* fix(deploy): reject unsupported Compose implementations for Linux override
* fix(deploy): lock OD_BIND_HOST to loopback for host networking in Linux
---------
Co-authored-by: kemycrome <luca.gernone@gmail.com>
* feat(deploy): add Azure deployment templates (App Service + ACI)
Adds a deploy/azure/ lane so Open Design can be deployed to Microsoft
Azure from the published runtime image, alongside the existing Docker
Compose and Helm options. Covers the App Service + ACI scope of #1028.
Two Bicep templates run the same single-port Alpine image used by
deploy/docker-compose.yml and charts/open-design:
- app-service.bicep: App Service for Containers with managed HTTPS,
Always On, and health checks on /api/health.
- aci.bicep: a single Azure Container Instances group with a public
FQDN and an /api/health liveness probe.
These are evaluation deployments: state lives on the container's local
disk and is ephemeral. Open Design stores SQLite under OD_DATA_DIR, and
SQLite needs real file locking, which the Azure Files (SMB) storage
behind both App Service and ACI persistence cannot provide without
corruption. App Service sets WEBSITES_ENABLE_APP_SERVICE_STORAGE=false to
keep the data dir on local disk. Durable self-hosting stays on the
Compose named volume or the Helm PVC.
Both wire the daemon's env contract (OD_BIND_HOST/OD_PORT/OD_WEB_PORT/
OD_DATA_DIR/OD_PUBLIC_BASE_URL/OD_ALLOWED_ORIGINS/OD_API_TOKEN) and take
the API token as a secure parameter so it never appears in deployment
outputs.
deploy-azure.sh wraps `az` to create the resource group, generate a
token when one isn't supplied, deploy a lane, and print the URL.
README.md documents both lanes, the ephemeral-data caveat, and the
security trade-offs.
deploy/tests/azure-bicep.test.ts guards the runtime contract and that the
data dir is never mounted to Azure Files; when the bicep CLI is present
it also compiles both templates.
* docs(deploy): add ACI health-check example to Azure quick start
The Alpine runtime image ships only BusyBox sh, so coding agents spawned
by the daemon reported "no POSIX shell in this environment" and could not
run their Bash tool. Install bash (and git, needed for nearly any agent
task) in the runtime stage alongside tini and poppler-utils.
* fix(deploy): move stage-2 asset copies into build stage
Stage 2 COPY commands for skills, design-systems, craft,
prompt-templates, assets, and plugins/_official previously read
from the build context, which couples the Dockerfile to the repo
root. Platforms like Railway that require the Dockerfile directory
to equal the build context could not find these paths.
Move the asset directories into the build stage and let Stage 2
pull them via --from=build, so the Dockerfile is fully
self-contained and works from any context directory.
* fix(deploy): chown volume at runtime so containers work with root-owned mounts
Platforms like Railway mount volumes as root, which overrides the
build-time chown on /app/.od. Run the container as root with tini,
chown the volume directory on start, then drop privileges to the
open-design user via su-exec before launching the daemon.
* Revert "fix(deploy): chown volume at runtime so containers work with root-owned mounts"
This reverts commit f32655d9c2.
* feat(deploy): add one-click Docker/Podman Compose installer for Linux and macOS
- Add install.sh with interactive wizard, Podman/Docker runtime detection,
port conflict check, health verification, and systemd user unit creation
- Add update.sh for image pull and restart with health check
- Add uninstall.sh with interactive user data backup before removal
- Unify CLI output styling with step/ok/warn/error/info helpers
- Add install-guide.md documentation
- Add install.test.ts integration test suite
* feat(deploy): add one-click Docker/Podman Compose installer
- interactive setup wizard with port, image, CORS, memory prompts
- automatic Docker/Podman detection with install guidance
- systemd user unit for Linux, health check polling
- update.sh (pull + restart + prune) and uninstall.sh (backup + cleanup)
- node:test integration suite and install-guide.md
* style(deploy): improve POSIX sh compatibility and systemd unit handling
- unify shell shebangs to #!/usr/bin/env bash
- add pipefail option for better error handling
- fix systemd unit for Podman: remove After/Requires when no service
- correct documentation to match actual uninstall behavior
* fix(deploy): address review feedback for installer scripts
- remove curl | sh path, document clone-first only
- isolate tests via docker-compose.override.yml with unique names
- support both --image <ref> and --image=<ref> in update.sh
- add running container detection before install
* docs(install): remove demo scripts and add MCP note
BYOK/API-mode chats bypass the daemon run path, so attached project
files were saved as message metadata but their readable contents were
not sent to the provider. This adds a web-side attachment context step
for API-mode requests, reusing raw text reads and existing document
preview extraction.
Constraint: Docker PDF previews require pdftotext in the runtime image
Confidence: high
Scope-risk: moderate
Tested: corepack pnpm --filter @open-design/web test -- tests/api-attachment-context.test.ts tests/components/ProjectView.api-empty-response.test.tsx
Tested: corepack pnpm --filter @open-design/web typecheck
Tested: corepack pnpm --filter @open-design/web build
Tested: corepack pnpm guard
Tested: corepack pnpm typecheck
Plan J4 / spec §15.4 / §15.5 / §16 Phase 5.
Three landings:
- deploy/Dockerfile now COPYs plugins/_official/ into the image so
the bundled atom plugins from §3.I3 register on container boot —
without this, registerBundledPlugins() silently no-ops inside the
container and the §23 self-bootstrap promise breaks for hosted
deployments.
- tools/pack/docker-compose.yml ships the canonical hosted-mode
manifest spec §15.4 calls out: two-volume layout (od-data +
od-config) per §15.2, OD_BIND_HOST=0.0.0.0 + OD_API_TOKEN +
OD_NAMESPACE + snapshot retention knobs as env, /api/daemon/status
as the healthcheck endpoint (Phase 1.5). Drop-in usable with
`docker compose -f tools/pack/docker-compose.yml up -d`.
- tools/pack/helm/open-design/{Chart.yaml,values.yaml,README.md}
pins the Helm chart parameter surface for the per-cloud overrides
spec §15.5 enumerates (AWS / GCP / Azure / Aliyun / Tencent /
Huawei / self-hosted). Templates land in the Phase 5 follow-up
PR; the values schema is locked here so the per-cloud override
files (values-<cloud>.yaml) review in isolation.
scripts/guard.ts allowlist gains
`packages/agui-adapter/esbuild.config.mjs` so the new package
passes the residual-JS guard.
Daemon tests stay at 1486/1486 (deploy artifacts only).
Co-authored-by: Tom Huang <1043269994@qq.com>
* Add Docker Compose deployment workflow
* Address Docker deployment review feedback
Harden publishing inputs and temporary credential handling, and tighten Docker runtime defaults requested by the PR review.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix Docker publish build in CI mode
Set CI=true during the image build so pnpm prune can run non-interactively inside Docker.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Fix Docker runtime dependency layout
Use pnpm deploy for the daemon package so the runtime image includes production dependencies where Node resolves them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Use legacy pnpm deploy in Docker build
Allow pnpm v10 deploy to package the daemon workspace without requiring injected workspace packages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Align Docker runtime with Node 24
Use Node 24 for both build and runtime stages and update image verification for the workspace daemon dependency layout.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Remove legacy OD_HOST Docker binding fallback
Use OD_BIND_HOST as the single daemon bind-host setting for Docker deployment and origin validation.
* Update Docker image verifier for daemon dist runtime
Check the packaged daemon dist entrypoint and allow npm from the Node 24 runtime image while still rejecting build-only tools.
* Allow private LAN browser origins for daemon
* Share daemon origin validation helpers
Move browser origin validation into a shared daemon module so tests exercise the production logic and cover the remaining private LAN edge cases.
* Harden Docker Compose port exposure
Bind the Compose deployment to localhost by default and pass the published port through to the daemon origin checks so host-port overrides remain same-origin.
* Keep deployment hosts out of local-only no-origin checks
Require an actual matching Origin before configured deployment origins can satisfy local-only daemon guards, preventing no-Origin remote clients from bypassing those checks.
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: mrcfps <mrc@powerformer.com>
Co-authored-by: lefarcen <935902669@qq.com>