Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 136 additions & 29 deletions getting-started/installation/kubernetes.md
Original file line number Diff line number Diff line change
@@ -1,65 +1,172 @@
# Install on Kubernetes

The official Helm chart deploys Dagu to any Kubernetes 1.19+ cluster.
The official Helm chart installs Dagu in a plug-and-play standalone mode by default. One pod runs the Web UI, scheduler, and local workflow executor, so a regular `ReadWriteOnce` volume is enough for most installations.

## Prerequisites

- Kubernetes 1.19+
- Helm 3.0+
- **A `StorageClass` that supports `ReadWriteMany`** — Dagu's server components need shared storage so the Web UI, scheduler, and run history stay in sync across pods. Examples: NFS (`nfs-client-provisioner`), AWS EFS, CephFS, Azure Files Premium, GlusterFS.
- Kubernetes 1.19 or newer
- Helm 3
- A default `StorageClass` that supports `ReadWriteOnce`, or the name of one to select

An Ingress controller, DNS record, and TLS certificate are needed only when the UI should be reachable through Ingress.

## Install

```bash
helm repo add dagu https://dagucloud.github.io/dagu
helm repo update
helm install dagu dagu/dagu --set persistence.storageClass=<your-rwx-storage-class>
helm upgrade --install dagu dagu/dagu \
--namespace dagu \
--create-namespace \
--wait
```

If your cluster's default `StorageClass` already supports `ReadWriteMany`, you can drop the `--set persistence.storageClass=...` flag.
The default installation creates:

- a release-scoped Kubernetes ServiceAccount
- one Dagu Deployment running the server, scheduler, and local executor
- a 10 Gi `ReadWriteOnce` PersistentVolumeClaim
- a `ClusterIP` Service for the UI and API

The PVC is retained when the Helm release is uninstalled.

If the cluster has no default StorageClass, save the selection in `dagu-values.yaml`:

```yaml
persistence:
storageClass: standard
```

## Render manifests without installing
Use that file for the installation and every later upgrade:

```bash
helm template dagu dagu/dagu --set persistence.storageClass=<your-rwx-storage-class>
helm upgrade --install dagu dagu/dagu \
--namespace dagu \
--create-namespace \
--values dagu-values.yaml \
--wait
```

## Upgrade
## Open the UI

For temporary access, forward the UI Service:

```bash
helm repo update
helm upgrade dagu dagu/dagu --set persistence.storageClass=<your-rwx-storage-class>
kubectl --namespace dagu port-forward service/dagu-ui 8080:8080
```

Open <http://localhost:8080> and complete the administrator setup. Run `helm get notes dagu --namespace dagu` to see access commands for the installed release.

## Configure Ingress

Create `dagu-values.yaml`, or add these settings to the existing file while preserving values such as `persistence.storageClass`. Replace the ingress class, hostname, and TLS Secret with values for the cluster:

```yaml
ingress:
enabled: true
className: your-ingress-class
host: dagu.example.com
tls:
enabled: true
secretName: dagu-tls

config:
publicUrl: https://dagu.example.com
```

The TLS Secret must exist in the Dagu namespace. Leave `secretName` empty only when the ingress controller supplies a default certificate.

Apply the values:

```bash
helm upgrade --install dagu dagu/dagu \
--namespace dagu \
--create-namespace \
--values dagu-values.yaml \
--wait
```

## From a source checkout
Point `dagu.example.com` at the ingress controller, then check the resource:

```bash
git clone https://github.com/dagucloud/dagu.git
cd dagu
helm install dagu ./charts/dagu --set persistence.storageClass=<your-rwx-storage-class>
kubectl --namespace dagu get ingress dagu-ui
```

## Image and version
Open <https://dagu.example.com>. The bundled UI and API use the same origin, so no CORS setting is needed. With OIDC, use the same URL for `auth.oidc.clientUrl` and register `https://dagu.example.com/oidc-callback` with the identity provider.

Proxy-header authentication has a separate trust model and cannot use the chart-managed Ingress. Follow [Proxy Authentication](/server-admin/authentication/proxy) before enabling it.

- Chart version comes from `charts/dagu/Chart.yaml`.
- Container image comes from `values.yaml` — defaults to `ghcr.io/dagucloud/dagu:latest`. Pin a specific tag in production:
## Customize storage

```bash
helm install dagu dagu/dagu \
--set persistence.storageClass=<rwx-class> \
--set image.tag=vX.Y.Z
```
Set the size or StorageClass with a values file:

## Full configuration
```yaml
persistence:
size: 20Gi
storageClass: standard
```

To reuse a PVC managed outside the release:

All values are documented in [`charts/dagu/README.md`](https://github.com/dagucloud/dagu/blob/main/charts/dagu/README.md) and validated against `values.schema.json`.
```yaml
persistence:
existingClaim: dagu-data
```

The existing PVC must be in the release namespace. The chart does not create, resize, or delete it.

## Use distributed mode

Distributed mode runs the UI server, scheduler, coordinator, and workers in separate Deployments. The server-side components require shared `ReadWriteMany` storage:

```yaml
deploymentMode: distributed

persistence:
accessMode: ReadWriteMany
storageClass: nfs-client
```

Workers use ephemeral local storage and report results through the coordinator. See [Kubernetes deployment](/server-admin/deployment/kubernetes#distributed-mode) for worker pools and operational details.

## Upgrade

```bash
helm repo update
helm upgrade dagu dagu/dagu \
--namespace dagu \
--values dagu-values.yaml \
--wait
```

Keep the release configuration in a values file and pass the same file on every upgrade. If the release uses only chart defaults, omit the `--values` line.

## Install from a source checkout

From the Dagu repository root:

```bash
helm upgrade --install dagu ./charts/dagu \
--namespace dagu \
--create-namespace \
--wait
```

## Image version

The chart uses its `appVersion` as the image tag by default. Override the tag only when a different Dagu version is required:

```yaml
image:
tag: "<dagu-version>"
```

## Verify

```bash
kubectl get pods -l app.kubernetes.io/name=dagu
kubectl port-forward svc/dagu 8080:8080
# visit http://localhost:8080
kubectl --namespace dagu get pods
kubectl --namespace dagu get pvc
helm test dagu --namespace dagu
```

Next: [Quickstart](/getting-started/quickstart).
For all chart settings, troubleshooting, and distributed configuration, see [Kubernetes deployment](/server-admin/deployment/kubernetes). To remove the release, see [Uninstall](/getting-started/installation/uninstall#helm).
23 changes: 21 additions & 2 deletions getting-started/installation/uninstall.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ docker volume rm dagu # destroys workflow history
## Helm

```bash
helm uninstall dagu
kubectl delete pvc -l app.kubernetes.io/name=dagu # destroys workflow history
RELEASE=dagu
NAMESPACE=dagu
helm uninstall "$RELEASE" --namespace "$NAMESPACE"
```

The official chart retains its managed PVC by default, so uninstalling Dagu does not remove workflows, run history, credentials, or other persisted state.

List the PVC for the release:

```bash
kubectl --namespace "$NAMESPACE" get pvc \
--selector "app.kubernetes.io/instance=$RELEASE"
```

If the chart created the PVC, delete it only when the data is no longer needed. Set `PVC_NAME` to the name returned by the previous command:

```bash
PVC_NAME=dagu-data
kubectl --namespace "$NAMESPACE" delete pvc "$PVC_NAME"
```

Set `RELEASE` and `NAMESPACE` to the values used during installation. A claim configured through `persistence.existingClaim` is managed outside Helm and is never deleted by the chart; do not run the manual deletion command for that claim.
2 changes: 1 addition & 1 deletion overview/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Dagu follows the XDG Base Directory specification for file organization:

## Distributed Execution Architecture

Dagu supports distributed execution through a coordinator-worker model. DAG definitions are transmitted to workers via gRPC, so workers only need shared storage for execution state and logs.
Dagu supports distributed execution through a coordinator-worker model. DAG definitions are transmitted to workers via gRPC. Shared-nothing workers also return status and logs over gRPC, while shared-filesystem workers write that data directly to common storage.

### Overview

Expand Down
8 changes: 5 additions & 3 deletions server-admin/authentication/proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,8 @@ auth:
```

The chart rejects proxy authentication when `ui.replicas` is not `1`, when
`auth.mode` is not `builtin`, or when `extraEnv` contains a
`auth.mode` is not `builtin`, when the UI Service is not a `ClusterIP`, when
the chart-managed Ingress is enabled, or when `extraEnv` contains a
`DAGU_AUTH_PROXY_*` override. It uses the `Recreate` strategy for the UI
Deployment, so UI upgrades briefly interrupt browser access.

Expand All @@ -288,8 +289,9 @@ Start with the chart's
then change its namespaces and selectors. Allow the component that forwards the
application request to Dagu, not necessarily the authentication service.

Keep the UI Service as `ClusterIP`. Do not expose another `LoadBalancer`,
`NodePort`, Ingress, Gateway, or service-mesh route that bypasses authentication.
Keep `ui.service.type: ClusterIP` and `ingress.enabled: false`. Create the
authenticated Ingress, Gateway, or service-mesh route separately. Do not expose
another `LoadBalancer`, `NodePort`, or route that bypasses authentication.

## Verify the deployment

Expand Down
Loading