Configure Dagu server settings.
::: info Deployment Model
This page documents self-hosted Dagu server configuration. Hosted Dagu Cloud includes managed authentication, audit logging, and related platform services by default, so you typically do not configure those features through config.yaml there. See the pricing page for current self-host and cloud availability.
:::
Precedence order:
- Command-line flags (highest)
- Environment variables (
DAGU_prefix) - Configuration file (lowest)
# CLI flag wins
dagu start-all --port=8000
# Even with env var
export DAGU_PORT=8080
# And config file
port: 7000Location: ~/.config/dagu/config.yaml
# Server Configuration
host: "127.0.0.1" # Web UI binding host
port: 8080 # Web UI binding port
base_path: "" # Base path for reverse proxy (e.g., "/dagu")
api_base_path: "/api/v1" # API endpoint base path
tz: "Asia/Tokyo" # Server timezone
debug: false # Debug mode
log_format: "text" # Log format: "text" or "json"
access_log_mode: "all" # Access log mode: "all" (default), "non-public", or "none"
headless: false # Run without Web UI
check_updates: true # Automatic web UI update checks (default: true)
metrics: "private" # Metrics endpoint access: "private" (default) or "public"
# Directory Paths (must be under "paths" key)
paths:
dags_dir: "~/.config/dagu/dags" # DAG definitions
docs_dir: "" # Auto: {dags_dir}/docs
log_dir: "~/.local/share/dagu/logs" # Log files
data_dir: "~/.local/share/dagu/data" # Application data
suspend_flags_dir: "~/.local/share/dagu/suspend" # Suspend flags
admin_logs_dir: "~/.local/share/dagu/logs/admin" # Admin logs
event_store_dir: "" # Auto: {admin_logs_dir}/events
base_config: "~/.config/dagu/base.yaml" # Base configuration
dag_runs_dir: "" # Auto: {data_dir}/dag-runs
queue_dir: "" # Auto: {data_dir}/queue
proc_dir: "" # Auto: {data_dir}/proc
contexts_dir: "" # Auto: {data_dir}/contexts
executable: "" # Auto: current executable
# Permissions
permissions:
write_dags: true # Allow creating/editing/deleting DAGs
run_dags: true # Allow running/stopping/retrying DAGs
# Authentication
auth:
mode: "builtin" # "none", "basic", or "builtin" (default)
# Builtin auth (JWT sessions, API keys, and role-based access)
builtin:
token:
secret: "your-secret" # Auto-generated if not set
ttl: "24h"
# Basic auth (simple username/password)
basic:
username: "admin"
password: "secret"
# OIDC auth (auto-enabled under builtin mode when all required fields are set)
oidc:
client_id: "your-client-id"
client_secret: "your-client-secret"
client_url: "http://localhost:8080"
issuer: "https://accounts.google.com"
scopes: ["openid", "profile", "email"]
whitelist: ["admin@example.com"]
# Builtin-specific fields (only used when mode: builtin)
auto_signup: true # Auto-create users on first login
role_mapping:
default_role: "viewer" # Role for new users
allowed_domains: ["company.com"] # Allowed email domains
button_label: "Login with SSO" # SSO button text
# TLS/HTTPS Configuration
tls:
cert_file: "/path/to/cert.pem"
key_file: "/path/to/key.pem"
# UI Customization
ui:
navbar_color: "#1976d2" # Header color (hex or name)
navbar_title: "Dagu" # Header title
log_encoding_charset: "utf-8" # Log file encoding (see reference for supported encodings)
max_dashboard_page_limit: 100 # Max items on dashboard
dags:
sort_field: "name" # Default DAG list request sort field (`name` or `nextRun`)
sort_order: "asc" # Default sort order (asc/desc)
# Latest Status Configuration
latest_status_today: true # Show only today's latest status
# Execution Mode
default_execution_mode: "local" # "local" (default) or "distributed"
# When "distributed", all DAGs dispatch to workers
# Terminal Configuration
terminal:
enabled: false # Enable web-based terminal (default: false)
max_sessions: 5 # Maximum concurrent terminal sessions per server
# Audit Logging
audit:
enabled: true # Enable audit logging (default: true)
retention_days: 7 # Days to keep audit logs (default: 7, 0 = keep forever)
# Centralized Event Store
event_store:
enabled: true # Enable centralized event logging (default: true)
retention_days: 3 # Days to keep event log files (default: 3, 0 = keep forever)
# Session Storage
session:
max_per_user: 100 # Max sessions per user (default: 100, 0 = unlimited)
# Queue System
queues:
enabled: true # Enable queue system (default: true)
config:
- name: "critical"
max_concurrency: 5 # Maximum concurrent DAG runs
- name: "batch"
max_concurrency: 1
- name: "default"
max_concurrency: 2
# Remote Nodes
remote_nodes:
- name: "staging"
api_base_url: "https://staging.example.com/api/v1"
auth_type: "basic"
basic_auth_username: "admin"
basic_auth_password: "password"
- name: "production"
api_base_url: "https://prod.example.com/api/v1"
auth_type: "token"
auth_token: "prod-token"
skip_tls_verify: falseAll options support DAGU_ prefix:
Server:
DAGU_HOST- Host (default:127.0.0.1)DAGU_PORT- Port (default:8080)DAGU_TZ- TimezoneDAGU_DEBUG- Debug modeDAGU_LOG_FORMAT- Log format (text/json)DAGU_ACCESS_LOG_MODE- Access log mode:all(default),non-public, ornoneDAGU_CHECK_UPDATES- Enable automatic web UI update checks (default:true)DAGU_SERVER_METRICS- Metrics endpoint access:private(default) orpublic
Paths:
DAGU_HOME- Set all pathsDAGU_DAGS_DIR- DAGs directoryDAGU_LOG_DIR- LogsDAGU_DATA_DIR- DataDAGU_EVENT_STORE_DIR- Centralized event log directoryDAGU_CONTEXTS_DIR- CLI contexts directory
Auth:
DAGU_AUTH_MODE- Auth mode:none,basic, orbuiltin(default:builtin)
Builtin Auth (RBAC):
DAGU_AUTH_TOKEN_SECRET- JWT signing secret (auto-generated if not set)DAGU_AUTH_TOKEN_TTL- JWT token expiry (default:24h)
Basic Auth:
DAGU_AUTH_BASIC_USERNAME- Basic auth usernameDAGU_AUTH_BASIC_PASSWORD- Basic auth password
OIDC Auth:
DAGU_AUTH_OIDC_CLIENT_ID- OIDC client IDDAGU_AUTH_OIDC_CLIENT_SECRET- OIDC client secretDAGU_AUTH_OIDC_CLIENT_URL- OIDC client URLDAGU_AUTH_OIDC_ISSUER- OIDC issuer URLDAGU_AUTH_OIDC_SCOPES- OIDC scopes (comma-separated)DAGU_AUTH_OIDC_WHITELIST- OIDC email whitelist (comma-separated)DAGU_AUTH_OIDC_AUTO_SIGNUP- Auto-create users on first login (default:true)DAGU_AUTH_OIDC_DEFAULT_ROLE- Role for auto-created users (default:viewer)DAGU_AUTH_OIDC_ALLOWED_DOMAINS- Allowed email domains (comma-separated)DAGU_AUTH_OIDC_BUTTON_LABEL- SSO login button text
UI:
DAGU_UI_DAGS_SORT_FIELD- Default DAGs page request sort field (nameornextRun)DAGU_UI_DAGS_SORT_ORDER- Default DAGs page sort order
Terminal:
DAGU_TERMINAL_ENABLED- Enable web-based terminal (default:false)DAGU_TERMINAL_MAX_SESSIONS- Maximum concurrent terminal sessions (default:5)
Audit Logging:
DAGU_AUDIT_ENABLED- Enable audit logging (default:true)DAGU_AUDIT_RETENTION_DAYS- Days to keep audit logs (default:7,0= keep forever)
Event Store:
DAGU_EVENT_STORE_ENABLED- Enable centralized event logging (default:true)DAGU_EVENT_STORE_RETENTION_DAYS- Days to keep event log files (default:3,0= keep forever)
Session Storage:
DAGU_SESSION_MAX_PER_USER- Max sessions per user (default:100,0= unlimited)
host: "127.0.0.1"
port: 8080
debug: truehost: "0.0.0.0"
port: 443
permissions:
write_dags: false
auth:
mode: builtin
builtin:
token:
secret: "${AUTH_TOKEN_SECRET}" # auto-generated if not set
ttl: "24h"
tls:
cert_file: "/etc/ssl/cert.pem"
key_file: "/etc/ssl/key.pem"Before exposing Dagu beyond a single-user localhost setup, review these controls:
- Use builtin auth for exposed instances.
auth.mode: builtinis the recommended self-hosted mode for browser access, API keys, and role-based access. Reserveauth.mode: basicfor simple private deployments, and avoidauth.mode: noneoutside isolated local development. - Keep metrics private by default. Leave
metrics: "private"unless Prometheus reaches Dagu only over a trusted private network. - Minimize write access. If operators should run reviewed DAGs but not modify them, set
permissions.write_dags: false. - Keep the web terminal disabled unless you need it.
terminal.enabled: falseis the safest setting for shared environments. - Use TLS or a trusted reverse proxy. If Dagu binds to
0.0.0.0, pair that with TLS termination and network-level controls rather than exposing the port broadly. - Secure distributed traffic. For coordinator and worker traffic that crosses host or network boundaries, set
peer.insecure: falseand configurepeer.cert_file,peer.key_file, andpeer.client_ca_filefor peer TLS/mTLS. - Treat host executors as privileged. Docker socket mounts, root containers, host bind mounts, and shell-capable workflows should be treated as administrative access to the machine that runs Dagu.
Example production-focused baseline:
host: "0.0.0.0"
port: 443
metrics: "private"
permissions:
write_dags: false
auth:
mode: builtin
terminal:
enabled: false
peer:
insecure: false
tls:
cert_file: "/etc/ssl/cert.pem"
key_file: "/etc/ssl/key.pem"docker run -d \
-e DAGU_HOST=0.0.0.0 \
-e DAGU_AUTH_MODE=builtin \
-e DAGU_AUTH_BUILTIN_INITIAL_ADMIN_USERNAME=admin \
-e DAGU_AUTH_BUILTIN_INITIAL_ADMIN_PASSWORD=your-secure-password \
-p 8080:8080 \
-v dagu-data:/var/lib/dagu \
ghcr.io/dagucloud/dagu:latest
# Admin auto-created on first startup; omit INITIAL_ADMIN vars to use the /setup page insteadBuiltin auth provides JWT sessions, initial admin bootstrap, password management, API keys, and the role model used by self-hosted Dagu. On self-hosted Dagu, creating, updating, and deleting additional users requires an active self-host license. Hosted Dagu Cloud includes user management by default. See the pricing page for current self-host and cloud availability. Available roles are admin, manager, developer, operator, and viewer.
auth:
mode: builtin
builtin:
token:
secret: "${AUTH_TOKEN_SECRET}" # auto-generated if not set
ttl: "24h"
initial_admin: # optional — auto-create admin on first startup
username: admin
password: "${ADMIN_PASSWORD}"# Environment variables
export DAGU_AUTH_MODE=builtin
# Token secret auto-generated if not set
# Optional — auto-create admin on first startup (both required together)
export DAGU_AUTH_BUILTIN_INITIAL_ADMIN_USERNAME=admin
export DAGU_AUTH_BUILTIN_INITIAL_ADMIN_PASSWORD=your-secure-passwordWhen initial_admin is configured and no users exist, the server creates the admin at startup and skips the setup page. The guided script installers can populate these settings for you during setup. When initial_admin is not configured, visit the web UI on first startup to create your admin account via the setup page.
See Builtin Authentication for detailed setup.
Simple single-user authentication without user management.
auth:
mode: basic
basic:
username: "admin"
password: "${ADMIN_PASSWORD}"Builtin + OIDC (SSO with user management and RBAC):
auth:
mode: builtin
builtin:
token:
secret: "${AUTH_TOKEN_SECRET}"
oidc:
client_id: "${OIDC_CLIENT_ID}"
client_secret: "${OIDC_CLIENT_SECRET}"
client_url: "https://dagu.example.com"
issuer: "https://accounts.google.com"
auto_signup: true
role_mapping:
default_role: viewerSee OIDC Configuration for detailed setup.
Let's Encrypt:
certbot certonly --standalone -d dagu.example.com
export DAGU_CERT_FILE=/etc/letsencrypt/live/dagu.example.com/fullchain.pem
export DAGU_KEY_FILE=/etc/letsencrypt/live/dagu.example.com/privkey.pemBehind Nginx:
# config.yaml
base_path: "/dagu"
host: "127.0.0.1"
port: 8080location /dagu/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}ui:
navbar_color: "#1976d2"
navbar_title: "Workflows"
log_encoding_charset: "utf-8"Color suggestions:
- Production:
#ff0000(red) - Staging:
#ff9800(orange) - Development:
#4caf50(green)
The log_encoding_charset option specifies the character encoding used to read log files in the UI. This is useful when your DAG steps produce output in non-UTF-8 encodings.
Common encodings:
utf-8(default) - Unicodeshift_jis,euc-jp- Japanesegb2312,gbk,gb18030- Simplified Chinesebig5- Traditional Chineseeuc-kr- Koreaniso-8859-1throughiso-8859-16- Latin/Europeanwindows-1250throughwindows-1258- Windows code pageskoi8-r,koi8-u- Cyrillic
See Configuration Reference - Supported Log Encodings for the complete list of 50+ supported encodings.
Example for Japanese logs:
ui:
log_encoding_charset: "shift_jis"Environment variable:
export DAGU_UI_LOG_ENCODING_CHARSET="shift_jis"remote_nodes:
- name: "production"
api_base_url: "https://prod.example.com/api/v1"
auth_type: "basic"
basic_auth_username: "admin"
basic_auth_password: "${PROD_PASSWORD}"
- name: "staging"
api_base_url: "https://staging.example.com/api/v1"
auth_type: "token"
auth_token: "${STAGING_TOKEN}"See Queue Configuration for full documentation.
queues:
enabled: true
config:
- name: "critical"
max_concurrency: 5
- name: "batch"
max_concurrency: 1
- name: "default"
max_concurrency: 2~/.config/dagu/base.yaml provides shared defaults for all DAGs:
mail_on:
failure: true
smtp:
host: "smtp.company.com"
port: "587"
username: "${SMTP_USER}"
password: "${SMTP_PASS}"
env:
- ENVIRONMENT: productionSee Base Configuration for complete documentation on all available fields and inheritance behavior.
Dagu exposes Prometheus metrics at /api/v1/metrics. By default, this endpoint requires authentication.
# Require authentication (default)
metrics: "private"
# Allow public access (no authentication required)
metrics: "public"Or via environment variable:
export DAGU_SERVER_METRICS=publicWhen metrics is set to private (default), configure Prometheus to authenticate:
scrape_configs:
- job_name: 'dagu'
bearer_token: 'your-api-token'
static_configs:
- targets: ['dagu:8080']
metrics_path: '/api/v1/metrics'Or with basic auth:
scrape_configs:
- job_name: 'dagu'
basic_auth:
username: 'admin'
password: 'secret'
static_configs:
- targets: ['dagu:8080']
metrics_path: '/api/v1/metrics'When metrics is set to public, no authentication is needed:
scrape_configs:
- job_name: 'dagu'
static_configs:
- targets: ['dagu:8080']
metrics_path: '/api/v1/metrics'Dagu uses in-memory caches to improve performance. Cache limits can be configured via presets:
cache: normal # options: low, normal, high (default: normal)Or via environment variable:
export DAGU_CACHE=low| Preset | DAG Definitions | DAG Run Status | API Keys | Webhooks |
|---|---|---|---|---|
low |
500 | 5,000 | 100 | 100 |
normal |
1,000 | 10,000 | 500 | 500 |
high |
5,000 | 50,000 | 1,000 | 1,000 |
- low: For memory-constrained environments
- normal: Balanced for typical deployments (default)
- high: For large-scale deployments with many DAGs
TTL (time-to-live): DAG caches expire after 12 hours, API key/webhook caches after 15 minutes.
Use Prometheus metrics to monitor cache sizes:
dagu_cache_entries_totalSee Prometheus Metrics for more details.
The web-based terminal allows executing shell commands directly from the Dagu UI. This feature is disabled by default for security reasons.
terminal:
enabled: true
max_sessions: 5Or via environment variable:
export DAGU_TERMINAL_ENABLED=true
export DAGU_TERMINAL_MAX_SESSIONS=5- The terminal runs commands with the same permissions as the Dagu server process
- Only enable in trusted environments where users should have shell access
- Consider using authentication (
auth.mode: builtin) when enabling terminal access - New sessions are rejected with HTTP
429afterterminal.max_sessionsactive terminals - Terminal sessions are logged in the audit log (when audit logging is enabled)
::: info Self-Host License On self-hosted Dagu, audit logging requires an active self-host license. Hosted Dagu Cloud includes audit logging by default. See the pricing page for current self-host and cloud availability. :::
Dagu maintains audit logs for security-sensitive operations. Audit logging is enabled by default.
audit:
enabled: true # Enable audit logging (default: true)Or via environment variable:
export DAGU_AUDIT_ENABLED=false
export DAGU_AUDIT_RETENTION_DAYS=30Audit log files are automatically cleaned up based on the retention_days setting:
- Default: 7 days (keeps today plus the 7 previous days)
- Disable cleanup: Set to
0to keep logs forever - Cleanup runs on startup, then every 24 hours
- Dates are evaluated in UTC
- Only files matching the
YYYY-MM-DD.jsonlnaming pattern are affected
When enabled, the following events are recorded:
- Authentication: Login attempts (success/failure), password changes
- User Management: User creation, updates, deletion
- API Keys: Key creation, updates, deletion
- Webhooks: Webhook creation, deletion, token regeneration
- Terminal: Shell command executions
Audit logs are written as daily records and can be reviewed in the Web UI at Settings > Audit Logs. Keep the admin log directory on persistent storage if you want that history to survive restarts.
The centralized event store persists operational events such as DAG-run outcomes and LLM usage records. It is enabled by default in dagu server and dagu start-all.
The /api/v1/event-logs endpoint reads from this store, and the Slack and Telegram DAG-run monitors use it when available.
event_store:
enabled: true
retention_days: 3Or via environment variables:
export DAGU_EVENT_STORE_ENABLED=true
export DAGU_EVENT_STORE_RETENTION_DAYS=7The event store keeps recent operational history according to event_store.retention_days. Place the admin log directory on persistent storage if you want those records to survive restarts.
Dagu keeps agent chat history per user. To prevent unbounded growth, older sessions are cleaned up automatically when a per-user limit is exceeded.
session:
max_per_user: 100 # Max sessions per user (default: 100, 0 = unlimited)Or via environment variable:
export DAGU_SESSION_MAX_PER_USER=50- When a new session is created and the user exceeds the limit, the oldest sessions are deleted
- Sub-sessions (created by delegate agents) are deleted together with their parent session and do not count toward the limit
- Set to
0to disable cleanup (keep all sessions)
- Set up authentication for secure access
- Configure remote nodes for multi-environment management
- Customize the UI for your organization
- Enable HTTPS for encrypted connections
- Configure terminal access for shell access
- Configure audit logging for security monitoring
- Prometheus Metrics for monitoring