Agent skill

dokploy-template-toml

Generate template.toml configuration for Dokploy templates with variables, domains, environment mappings, and file mounts. Use when finalizing Dokploy templates.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/dokploy-template-toml

SKILL.md

Dokploy Template TOML

When to Use This Skill

  • When creating template.toml for a new Dokploy template
  • When configuring Dokploy variable generation (passwords, secrets)
  • When setting up domain configuration for services
  • When adding file mounts for configuration files
  • When user asks about "dokploy variables" or "template configuration"

When NOT to Use This Skill

  • When working with docker-compose only (no Dokploy)
  • For runtime configuration changes (modify environment vars instead)

Prerequisites

  • Completed docker-compose.yml file
  • List of required/optional environment variables
  • Domain configuration requirements
  • Knowledge of secret generation needs

Template.toml Structure

toml
# Header comment with application info
# Application Name - Description
# https://github.com/example/application

[variables]
# User-provided and auto-generated variables
domain = "${domain}"
secret_key = "${base64:64}"
password = "${password:32}"

# Domain configuration for Traefik
[[config.domains]]
serviceName = "app"
port = 3000
host = "${domain}"

# Environment variables for all services
[config.env]
APP_DOMAIN = "${domain}"
APP_SECRET = "${secret_key}"

# Optional file mounts
[[config.mounts]]
serviceName = "app"
mountPath = "/app/config.json"
content = """
{
  "setting": "${variable}"
}
"""

Core Patterns

Pattern 1: Variable Definitions

toml
[variables]
# User-provided domain (required)
domain = "${domain}"

# Random password generation
db_password = "${password:32}"      # 32-char alphanumeric
api_key = "${password:48}"          # 48-char alphanumeric

# Base64 secret generation
secret_key = "${base64:64}"         # 64-char base64 encoded
jwt_secret = "${base64:32}"         # 32-char base64 encoded

# UUID generation
instance_id = "${uuid}"             # Random UUID v4

# User inputs
admin_email = "${email}"            # User-provided email
username = "${username}"            # User-provided username

# Derived variables (string concatenation)
app_url = "https://${domain}"
db_url = "postgresql://user:${db_password}@postgres:5432/db"

Supported Variable Types:

Syntax Description Example Output
${domain} User-provided domain example.com
${password:N} N-char random password aB3kL9mN...
${base64:N} N-char base64 secret dGhpcyBpcyBh...
${uuid} Random UUID v4 550e8400-e29b-41d4-a716-446655440000
${username} User-provided username admin
${email} User-provided email user@example.com

Pattern 2: Domain Configuration

toml
# Single domain
[[config.domains]]
serviceName = "app"
port = 3000
host = "${domain}"

# Multiple domains (different services)
[[config.domains]]
serviceName = "app"
port = 3000
host = "${domain}"

[[config.domains]]
serviceName = "api"
port = 8080
host = "api.${domain}"

# Admin subdomain
[[config.domains]]
serviceName = "admin"
port = 9000
host = "admin.${domain}"

Important: serviceName must match the service name in docker-compose.yml

Pattern 3: Environment Variables

toml
[config.env]
# Required variables (error if not set in compose)
APP_DOMAIN = "${domain}"
APP_SECRET = "${secret_key}"
DATABASE_PASSWORD = "${db_password}"

# Categories with comments
# ===========================================
# Database Configuration
# ===========================================
POSTGRES_DB = "appdb"
POSTGRES_USER = "appuser"
POSTGRES_PASSWORD = "${db_password}"

# ===========================================
# Application Settings
# ===========================================
APP_URL = "https://${domain}"
DEBUG = "false"

# ===========================================
# External Services (Cloudflare R2)
# ===========================================
S3_ENDPOINT = ""
S3_ACCESS_KEY_ID = ""
S3_SECRET_ACCESS_KEY = ""
S3_BUCKET = ""
S3_REGION = "auto"

Pattern 4: File Mounts

toml
# JSON configuration file
[[config.mounts]]
serviceName = "app"
mountPath = "/app/config.json"
content = """
{
  "domain": "${domain}",
  "secret": "${secret_key}",
  "database": {
    "host": "postgres",
    "port": 5432,
    "name": "appdb"
  }
}
"""

# INI/conf file
[[config.mounts]]
serviceName = "app"
mountPath = "/etc/app/settings.conf"
content = """
[general]
domain = ${domain}
debug = false

[database]
host = postgres
port = 5432
password = ${db_password}
"""

# YAML configuration
[[config.mounts]]
serviceName = "app"
mountPath = "/app/config.yaml"
content = """
server:
  host: 0.0.0.0
  port: 3000
  domain: ${domain}

security:
  secret_key: ${secret_key}
"""

Complete Examples

Example 1: Simple Web App (Paaster)

toml
# Paaster - End-to-end encrypted pastebin
# https://github.com/WardPearce/paaster

[variables]
domain = "${domain}"
cookie_secret = "${base64:64}"

[[config.domains]]
serviceName = "paaster"
port = 3000
host = "${domain}"

[config.env]
# ===========================================
# Application Domain
# ===========================================
PAASTER_DOMAIN = "${domain}"

# ===========================================
# Security
# ===========================================
COOKIE_SECRET = "${cookie_secret}"

# ===========================================
# MongoDB Configuration
# ===========================================
MONGO_DB = "paasterv3"

# ===========================================
# Cloudflare R2 Storage
# Get from: Cloudflare Dashboard > R2 > Manage R2 API Tokens
# Endpoint format: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
# ===========================================
S3_ENDPOINT = ""
S3_ACCESS_KEY_ID = ""
S3_SECRET_ACCESS_KEY = ""
S3_BUCKET = ""
S3_REGION = "auto"

Example 2: Git Service with Database (Forgejo)

toml
# Forgejo - Self-hosted Git forge
# https://forgejo.org/

[variables]
domain = "${domain}"
postgres_password = "${password:32}"
secret_key = "${base64:64}"
internal_token = "${base64:48}"
jwt_secret = "${base64:48}"

[[config.domains]]
serviceName = "forgejo"
port = 3000
host = "${domain}"

[config.env]
# ===========================================
# Domain Configuration
# ===========================================
FORGEJO__server__DOMAIN = "${domain}"
FORGEJO__server__ROOT_URL = "https://${domain}/"

# ===========================================
# Database Configuration
# ===========================================
FORGEJO__database__DB_TYPE = "postgres"
FORGEJO__database__HOST = "postgres:5432"
FORGEJO__database__NAME = "forgejo"
FORGEJO__database__USER = "forgejo"
FORGEJO__database__PASSWD = "${postgres_password}"

# PostgreSQL credentials
POSTGRES_USER = "forgejo"
POSTGRES_DB = "forgejo"
POSTGRES_PASSWORD = "${postgres_password}"

# ===========================================
# Security Keys
# ===========================================
FORGEJO__security__SECRET_KEY = "${secret_key}"
FORGEJO__security__INTERNAL_TOKEN = "${internal_token}"
FORGEJO__oauth2__JWT_SECRET = "${jwt_secret}"

# ===========================================
# Optional: SSH Configuration
# ===========================================
SSH_PORT = "2222"

Example 3: Complex Stack (Paperless-ngx)

toml
# Paperless-ngx - Document management system
# https://docs.paperless-ngx.com/

[variables]
domain = "${domain}"
postgres_password = "${password:32}"
secret_key = "${base64:64}"
admin_user = "${username}"
admin_password = "${password:16}"
admin_email = "${email}"

[[config.domains]]
serviceName = "paperless"
port = 8000
host = "${domain}"

[config.env]
# ===========================================
# Database Configuration
# ===========================================
POSTGRES_DB = "paperless"
POSTGRES_USER = "paperless"
POSTGRES_PASSWORD = "${postgres_password}"

# Paperless database settings
PAPERLESS_DBHOST = "postgres"
PAPERLESS_DBNAME = "paperless"
PAPERLESS_DBUSER = "paperless"
PAPERLESS_DBPASS = "${postgres_password}"

# ===========================================
# Application Settings
# ===========================================
PAPERLESS_SECRET_KEY = "${secret_key}"
PAPERLESS_URL = "https://${domain}"
PAPERLESS_ALLOWED_HOSTS = "${domain}"
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${domain}"

# ===========================================
# Admin User (created on first run)
# ===========================================
PAPERLESS_ADMIN_USER = "${admin_user}"
PAPERLESS_ADMIN_PASSWORD = "${admin_password}"
PAPERLESS_ADMIN_MAIL = "${admin_email}"

# ===========================================
# Document Processing
# ===========================================
PAPERLESS_OCR_LANGUAGE = "eng"
PAPERLESS_TIKA_ENABLED = "1"
PAPERLESS_TIKA_ENDPOINT = "http://tika:9998"
PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://gotenberg:3000"

# ===========================================
# Redis
# ===========================================
PAPERLESS_REDIS = "redis://redis:6379"

Example 4: Service with Config File Mount

toml
# ANyONe Protocol Relay
# https://github.com/anyone-protocol/ator-protocol

[variables]
relay_nickname = "${username}"
relay_contact = "${email}"
control_password = "${password:24}"
orport = "9001"
dirport = "9030"
controlport = "9051"
wallet_address = ""

[config.env]
ACCEPT_TOS = "1"
ANON_NICKNAME = "${relay_nickname}"
ANON_CONTACT = "${relay_contact}"
ANON_ORPORT = "${orport}"
ANON_DIRPORT = "${dirport}"
ANON_CONTROLPORT = "${controlport}"

[[config.mounts]]
serviceName = "anon-relay"
mountPath = "/etc/anon/anonrc"
content = """
# ANyONe Protocol Relay Configuration
# Auto-generated by Dokploy

# Relay Identity
Nickname ${relay_nickname}
ContactInfo ${relay_contact}

# Network Ports
ORPort ${orport}
DirPort ${dirport}
ControlPort ${controlport}

# Control Authentication
HashedControlPassword ${control_password}

# Relay Type (exit disabled by default)
ExitRelay 0

# Bandwidth Limits (optional)
# RelayBandwidthRate 1 MB
# RelayBandwidthBurst 2 MB
"""

Quality Standards

Mandatory Requirements

  • All required variables defined in [variables]
  • Domain configuration matches docker-compose service names
  • Environment variables organized with category comments
  • Sensitive values use auto-generation (password, base64)
  • User-facing values use appropriate prompts (domain, email)

Documentation Standards

  • Add header comment with app name and link
  • Comment each category in [config.env]
  • Document where to get external credentials (R2, etc.)

Security Standards

  • Never hardcode passwords or secrets
  • Use ${password:N} for database passwords
  • Use ${base64:N} for encryption keys
  • Leave external API keys blank for user input

Common Pitfalls

Pitfall 1: serviceName mismatch

Issue: Domain config doesn't work Solution: serviceName must exactly match docker-compose service name

Pitfall 2: Missing variable definitions

Issue: Variables referenced but not defined Solution: Define all ${var} references in [variables] section

Pitfall 3: Password in plain text

Issue: Secrets visible in Dokploy UI Solution: Use ${password:N} or ${base64:N} for auto-generation

Pitfall 4: Wrong mount serviceName

Issue: Config file not mounted Solution: Match serviceName to exact docker-compose service


Integration

Skills-First Approach (v2.0+)

This skill is part of the skills-first architecture - loaded progressively during the Generation phase as the final step before validation.

Related Skills

  • dokploy-compose-structure: Service names for domain config
  • dokploy-environment-config: Environment variable patterns
  • dokploy-cloudflare-integration: R2 configuration

Invoked By

  • /dokploy-create command: Phase 3 (Generation) - Step 6 (Final)

Order in Workflow (Progressive Loading)

  1. dokploy-compose-structure: Create compose file
  2. dokploy-traefik-routing: Add routing
  3. dokploy-health-patterns: Add health checks
  4. dokploy-cloudflare-integration: Add CF config (if applicable)
  5. dokploy-environment-config: Plan environment vars
  6. This skill: Create template.toml (final generation step)

See: .claude/commands/dokploy-create.md for full workflow

Didn't find tool you were looking for?

Be as detailed as possible for better results