Deployment Strategies for OpenWork: Private Network, Air-Gapped, and Local Development
OpenWork supports three distinct deployment strategies—Private-Network Helm deployments for corporate LANs, Fully Air-Gapped installations with complete artifact mirroring, and Local Docker Compose stacks for development—all configurable through the official different-ai/openwork repository.
The different-ai/openwork repository provides enterprise-grade deployment strategies that accommodate everything from rapid local prototyping to hardened, isolated production environments. Each strategy shares the same core architecture comprising the Den API (control-plane), Den Web (UI layer), optional Inference services, a MySQL-compatible database, and Better Auth for authentication, ensuring consistency across development and production.
Core Architecture Across All Strategies
Every deployment strategy relies on the same service boundaries defined in the source tree:
| Component | Role | Source Reference |
|---|---|---|
| Den API | Control-plane service storing organizations, policies, and MCP connections | packages/den-api |
| Den Web | Web UI and reverse proxy that desktop clients authenticate against | packages/den-web |
| Inference | Optional internal model provider runtime | packages/inference |
| MySQL-compatible DB | Persistent state storage | External dependency |
| Better Auth | Authentication layer for desktop client sessions | Configured via Helm/Compose |
Private-Network Deployment Strategy
Private-Network deployment is designed for organizations where developer laptops retain internet access (for npm packages, model catalogs, and installers), but the Den services must remain inside a corporate LAN or VPN. This semi-air-gapped approach uses the OpenWork EE Helm Chart documented in packaging/helm/openwork-ee/README.md.
Configuration
Create a values.private-network.yaml file that exposes Den Web as the single origin endpoint:
# values.private-network.yaml
config:
tenancy:
mode: "single_org"
singleOrgName: "Acme"
singleOrgSlug: "acme"
ownerEmails: "admin@acme.com"
public:
webOrigin: "https://openwork.acme.internal"
apiOrigin: "https://api.openwork.acme.internal"
mcpResourceUrl: "https://api.openwork.acme.internal/mcp"
desktopDenBaseUrl: "https://openwork.acme.internal"
corsOrigins: "https://openwork.acme.internal,https://api.openwork.acme.internal"
betterAuthTrustedOrigins: "https://openwork.acme.internal"
secret:
values:
databaseUrl: "mysql://openwork:REPLACE_ME@mysql.internal:3306/openwork_den"
betterAuthSecret: "REPLACE_WITH_32+_CHARS"
denDbEncryptionKey: "REPLACE_WITH_32+_CHARS"
Installation
Deploy using the OCI-hosted Helm chart:
helm upgrade --install openwork-ee \
oci://ghcr.io/different-ai/charts/openwork-ee \
--version <release-tag> \
-f values.private-network.yaml
In this configuration, Den Web acts as a reverse proxy for Den API (/api/den), allowing the desktop client to communicate through a single origin while all database and inference traffic remains internal. For detailed network diagrams and troubleshooting, refer to packages/docs/start-here/private-network-deployment.mdx.
Fully Air-Gapped Deployment Strategy
Fully Air-Gapped deployment prohibits all outbound internet access, requiring every dependency—including Helm charts, container images, installer artifacts, model catalogs, and provider APIs—to be mirrored internally. This strategy uses the same Helm chart as the private-network approach but requires extensive pre-configuration.
Prerequisites
According to packages/docs/start-here/air-gapped-deployment.mdx, you must mirror:
- Deployment artifacts: All images (
openwork-den-api,openwork-den-web,openwork-inference) into an internal OCI registry - Installer artifacts: Mount release files inside Den via
installerArtifacts.mountPathand setOPENWORK_INSTALLER_ARTIFACTS_DIR - Desktop runtime: Internal mirror for
OPENCODE_MODELS_URLand npm registry fornpx openwork-ui-mcp - Security: Load private CAs using
customCain Helm values
Configuration
Create a values.air-gapped.yaml that disables external dependencies:
# values.air-gapped.yaml
config:
tenancy:
mode: "single_org"
singleOrgName: "Acme"
singleOrgSlug: "acme"
ownerEmails: "admin@acme.com"
public:
webOrigin: "https://openwork.acme.internal"
apiOrigin: "https://api.openwork.acme.internal"
mcpResourceUrl: "https://api.openwork.acme.internal/mcp"
desktopDenBaseUrl: "https://openwork.acme.internal"
corsOrigins: "https://openwork.acme.internal"
betterAuthTrustedOrigins: "https://openwork.acme.internal"
installerReleaseTag: "v0.18.0"
installerReleaseRepo: "different-ai/openwork"
installerArtifacts:
enabled: true
existingClaim: openwork-desktop-artifacts
mountPath: /var/lib/openwork/installer-artifacts
secret:
create: false
customCa:
enabled: true
existingSecret: openwork-ca
key: ca.crt
Installation from Internal Registry
helm upgrade --install openwork-ee \
oci://registry.internal/different-ai/openwork-ee \
--version <release-tag> \
-f values.air-gapped.yaml
All external URLs—including model catalogs and provider endpoints—must resolve to internal equivalents, or the desktop client will fail during authentication or model loading.
Local Development Deployment Strategy
Local Development deployment uses Docker Compose to spin up Den API, Den Web, and MySQL on a single workstation. This strategy, defined in packaging/docker/docker-compose.den-dev.yml, is ideal for UI development, feature prototyping, and integration testing.
Quick Start
Run the development stack:
docker compose -f packaging/docker/docker-compose.den-dev.yml up -d
The compose file exposes the following ports by default:
3005→ Den Web8788→ Den API3306→ MySQL
Verification
Confirm service health before connecting a client:
curl http://localhost:3005/api/health # Den Web health
curl http://localhost:8788/health # Den API health
Once healthy, point the desktop client to http://localhost:3005. The default configuration automatically creates a single organization named OpenWork for immediate testing.
Selecting the Right Deployment Strategy
| Requirement | Recommended Strategy | Configuration File |
|---|---|---|
| Fast iteration, no production SLA | Docker Compose | packaging/docker/docker-compose.den-dev.yml |
| Enterprise on-prem with internet access | Private-Network Helm | values.private-network.yaml |
| Strict security, no outbound traffic | Air-Gapped Helm | values.air-gapped.yaml |
| Managed Kubernetes (EKS, AKS, GKE) | Private-Network Helm | Chart examples in packaging/helm/openwork-ee/ |
All strategies share the same codebase, allowing seamless promotion from local Docker Compose development to production Kubernetes deployments without modification.
Summary
- Private-Network deployments use the
openwork-eeHelm chart to keep Den services inside corporate networks while allowing desktop clients internet access for dependencies. - Air-Gapped deployments require complete mirroring of Helm charts, container images, installer artifacts, and model catalogs into internal infrastructure, configured via
values.air-gapped.yaml. - Local development relies on
docker-compose.den-dev.ymlfor disposable, workstation-based environments with automatic single-organization creation. - All strategies depend on the same five core components: Den API, Den Web, Inference (optional), MySQL, and Better Auth.
Frequently Asked Questions
What are the core components required for every OpenWork deployment?
Every deployment strategy requires the Den API (control-plane), Den Web (UI and reverse proxy), a MySQL-compatible database, and Better Auth for authentication. The Inference service is optional and only required if running model providers internally rather than using external APIs.
How do I deploy OpenWork without any internet access?
Use the Fully Air-Gapped strategy. You must mirror the openwork-ee Helm chart and all container images (openwork-den-api, openwork-den-web, openwork-inference) into an internal OCI registry, mount installer artifacts via the installerArtifacts configuration, and point all external URLs (model catalogs, npm registries) to internal mirrors as documented in packages/docs/start-here/air-gapped-deployment.mdx.
Can I run OpenWork locally without Kubernetes?
Yes. Clone the different-ai/openwork repository and run docker compose -f packaging/docker/docker-compose.den-dev.yml up -d. This starts Den API on port 8788, Den Web on port 3005, and MySQL on port 3306, suitable for development and testing without Kubernetes overhead.
What is the difference between single-organization and multi-tenant modes?
In single_org mode (configured via config.tenancy.mode), the deployment automatically provisions one organization at startup using the singleOrgName, singleOrgSlug, and ownerEmails values. Multi-tenant mode allows dynamic organization creation through the API. Single-organization mode is recommended for enterprise deployments where a single entity manages the instance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →