# How to Deploy OpenWork to Production Using Docker Compose and Helm Charts

> Deploy OpenWork to production using Docker Compose for single-host setups or Helm charts for Kubernetes on AWS EKS, Azure AKS, or GCP GKE. Get your OpenWork instance live quickly.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-04

---

**Deploy OpenWork to production by using Docker Compose for single-host deployments via [`packaging/docker/docker-compose.yml`](https://github.com/different-ai/openwork/blob/main/packaging/docker/docker-compose.yml), or use the Helm chart from GHCR (`ghcr.io/different-ai/charts/openwork-ee`) for Kubernetes clusters on AWS EKS, Azure AKS, or GCP GKE.**

The `different-ai/openwork` repository provides two officially supported paths for deploying OpenWork to production environments. Whether you need a lightweight container stack for a single server or a cloud-native Kubernetes deployment with auto-scaling, the source code includes hardened configurations for both scenarios.

## Docker Compose Deployment

The Docker Compose setup provides a lightweight, self-contained stack ideal for on-premises servers, small VMs, or early-stage production testing.

### Prerequisites and Setup

Clone the repository and navigate to the Docker packaging directory:

```bash
git clone https://github.com/different-ai/openwork.git
cd openwork/packaging/docker

```

The main orchestration file is [`packaging/docker/docker-compose.yml`](https://github.com/different-ai/openwork/blob/main/packaging/docker/docker-compose.yml), which defines the `openwork-host` service, persistent volumes, and port mappings.

### Configuration and Environment Variables

Before starting the stack, review the environment block in [`docker-compose.yml`](https://github.com/different-ai/openwork/blob/main/docker-compose.yml). Set `OPENWORK_TOKEN` or `OPENWORK_HOST_TOKEN` (lines 13–17) to configure static API authentication tokens:

```yaml
environment:
  - OPENWORK_TOKEN=your-secure-token-here
  - OPENWORK_HOST_TOKEN=your-host-token-here

```

These values allow API clients to authenticate against the OpenWork server immediately upon startup.

### Starting and Managing the Stack

Launch the production stack in detached mode:

```bash
docker compose up -d

```

This command performs the following actions:

- Builds the `openwork-host` image using the Dockerfile in the same directory
- Exposes the server on port **8787** via the mapping `- "8787:8787"`
- Mounts the local `workspace` directory into the container for persistent user data

### Data Persistence and Upgrades

The `data` volume (lines 20–22) stores OpenCode caches, server configuration, and authentication tokens. Back up this directory regularly to prevent data loss.

To upgrade OpenWork when a new version is released:

```bash
git pull origin main
docker compose up -d --build

```

The volume mount ensures user data persists across image rebuilds and container restarts.

## Helm Charts for Kubernetes

For scalable, highly-available deployments, the OpenWork EE Helm chart supports AWS EKS, Azure AKS, and GCP GKE. The chart is published as an OCI artifact to GitHub Container Registry.

### Cloud Provider Prerequisites

Create a managed Kubernetes cluster using your provider's recommended tooling. For AWS, EKS Auto Mode provides the simplest path. Provision a managed MySQL instance (RDS for AWS) and configure security groups to allow cluster connectivity on port 3306.

### Preparing the Values File

Copy the starter values file for your provider:

- AWS: [`values.aws-load-balancer.yaml`](https://github.com/different-ai/openwork/blob/main/values.aws-load-balancer.yaml)
- Azure: [`values.azure-load-balancer.yaml`](https://github.com/different-ai/openwork/blob/main/values.azure-load-balancer.yaml) (referenced in [`docs/azure-aks-helm.md`](https://github.com/different-ai/openwork/blob/main/docs/azure-aks-helm.md))
- GCP: GKE-specific starter (referenced in [`docs/gcp-gke-helm.md`](https://github.com/different-ai/openwork/blob/main/docs/gcp-gke-helm.md))

Fill all `REPLACE_*` placeholders, paying special attention to:

- `secret.values.betterAuthSecret` – Authentication signing key
- `secret.values.denDbEncryptionKey` – Database encryption key
- `config.tenancy.singleOrgName` – Organization name
- `ownerEmails` and `bootstrapAdminEmails` – Initial admin accounts (lines 33–45)

### Installing from GHCR

Render the chart locally to verify configuration, then install:

```bash
helm template openwork-ee oci://ghcr.io/different-ai/charts/openwork-ee \
  --version <OPENWORK_VERSION> \
  -f values.aws.yaml

helm upgrade --install openwork-ee oci://ghcr.io/different-ai/charts/openwork-ee \
  --version <OPENWORK_VERSION> \
  --namespace openwork-ee --create-namespace \
  -f values.aws.yaml

```

Replace `<OPENWORK_VERSION>` with the specific OpenWork release you want to run.

### Database Migrations and Hooks

The chart automatically creates a Helm hook job named `openwork-ee-migrate` that runs database migrations before the main Deployments start. If the installation stalls, inspect the migration logs:

```bash
kubectl logs -l job-name=openwork-ee-migrate -n openwork-ee

```

### Exposing Services and TLS

By default, the chart creates two Network Load Balancers—one for the web UI and one for the API. Configure DNS records to point to these load balancers (e.g., `openwork.example.com` and `api.openwork.example.com`).

Attach ACM certificates using the `service.beta.kubernetes.io/aws-load-balancer-ssl-cert` annotation (lines 66–71 of the values file). For Azure, use `service.beta.kubernetes.io/azure-load-balancer-*` annotations; for GCP, use `service.beta.kubernetes.io/gcp-load-balancer-*` annotations.

### SSO and Admin Bootstrap

Configure single sign-on before the first user sign-in by populating the `config.sso.*` fields with your IdP metadata (sections 52–78). The chart supports OIDC and SAML out of the box.

Verify deployment readiness by hitting the `/ready` endpoints on both the API and web services:

```bash
curl https://api.openwork.example.com/ready
curl https://openwork.example.com/ready

```

## Provider-Specific Helm Configurations

While the core chart remains consistent, each cloud provider requires specific annotations and networking configurations documented in the repository.

### AWS EKS

The [`docs/aws-eks-helm.md`](https://github.com/different-ai/openwork/blob/main/docs/aws-eks-helm.md) guide provides complete instructions for EKS Auto Mode, RDS provisioning, and AWS Load Balancer Controller integration. Use [`values.aws-load-balancer.yaml`](https://github.com/different-ai/openwork/blob/main/values.aws-load-balancer.yaml) as your starter template.

### Azure AKS

For Azure deployments, consult [`docs/azure-aks-helm.md`](https://github.com/different-ai/openwork/blob/main/docs/azure-aks-helm.md). This guide includes the [`values.azure-load-balancer.yaml`](https://github.com/different-ai/openwork/blob/main/values.azure-load-balancer.yaml) starter and notes on Azure Load Balancer annotations for internal or external IP configuration.

### GCP GKE

The [`docs/gcp-gke-helm.md`](https://github.com/different-ai/openwork/blob/main/docs/gcp-gke-helm.md) documentation covers GKE-specific starters and instructions for enabling the GCP Load Balancer controller. Replace AWS-specific annotations with GCP equivalents in your values file.

## Summary

- **Docker Compose** provides single-host production deployments using [`packaging/docker/docker-compose.yml`](https://github.com/different-ai/openwork/blob/main/packaging/docker/docker-compose.yml), exposing port 8787 and persisting data via the `data` and `workspace` volumes.
- **Helm Charts** enable cloud-native Kubernetes deployments via `oci://ghcr.io/different-ai/charts/openwork-ee`, supporting AWS EKS, Azure AKS, and GCP GKE with provider-specific values files.
- **Critical configuration** requires setting `secret.values.betterAuthSecret`, `secret.values.denDbEncryptionKey`, and `bootstrapAdminEmails` before the first deployment.
- **Database migrations** run automatically via Helm hooks, but require valid `DATABASE_URL` connectivity to your managed MySQL instance.
- **TLS termination** occurs at the cloud load balancer level using provider-specific annotations for certificate management.

## Frequently Asked Questions

### How do I back up OpenWork data in a Docker Compose deployment?

Back up the `data` volume directory regularly, as it contains OpenCode caches, server configuration, and authentication tokens. The `workspace` directory mounted from the host also requires backup to preserve user project files across container restarts.

### What Kubernetes permissions are required to install the OpenWork Helm chart?

You need cluster-admin privileges or sufficient RBAC permissions to create namespaces, Deployments, Services, Ingress resources, and Jobs. The chart creates a migration Job that requires permission to run pods and access Secrets containing database credentials.

### Can I use a private container registry instead of GHCR for the Helm deployment?

Yes. Create a Docker registry secret in the `openwork-ee` namespace and reference it using `imagePullSecrets` in your values file. Update the `image.repository` and `image.tag` fields to point to your private registry location.

### How do I troubleshoot failed database migrations during Helm installation?

Check the logs of the migration Job using `kubectl logs -l job-name=openwork-ee-migrate -n openwork-ee`. Common failures include incorrect `DATABASE_URL` formatting, network connectivity issues between the cluster and MySQL instance, or insufficient database permissions for the migration user.