Claude-skill-registry dokploy-template-toml
Generate template.toml configuration for Dokploy templates with variables, domains, environment mappings, and file mounts. Use when finalizing Dokploy templates.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dokploy-template-toml" ~/.claude/skills/majiayu000-claude-skill-registry-dokploy-template-toml && rm -rf "$T"
manifest:
skills/data/dokploy-template-toml/SKILL.mdsource content
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
# 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
[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 |
|---|---|---|
| User-provided domain | |
| N-char random password | |
| N-char base64 secret | |
| Random UUID v4 | |
| User-provided username | |
| User-provided email | |
Pattern 2: Domain Configuration
# 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
[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
# 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)
# 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)
# 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)
# 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
# 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
for database passwords${password:N} - Use
for encryption keys${base64:N} - 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
: Service names for domain configdokploy-compose-structure
: Environment variable patternsdokploy-environment-config
: R2 configurationdokploy-cloudflare-integration
Invoked By
command: Phase 3 (Generation) - Step 6 (Final)/dokploy-create
Order in Workflow (Progressive Loading)
: Create compose filedokploy-compose-structure
: Add routingdokploy-traefik-routing
: Add health checksdokploy-health-patterns
: Add CF config (if applicable)dokploy-cloudflare-integration
: Plan environment varsdokploy-environment-config- This skill: Create template.toml (final generation step)
See:
.claude/commands/dokploy-create.md for full workflow