Dokploy / Dokploy/dokploy

Implementation Plan: dokploy apply - Declarative YAML Config

Open
#4,008 4 comments 34 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

Summary

Implementation plan for dokploy apply -f dokploy.yaml — a declarative config command for the Dokploy CLI that enables managing Dokploy resources as code.

Related: #3872

High-Level Design

What it does

Users define their Dokploy infrastructure in a dokploy.yaml file and run dokploy apply -f dokploy.yaml to create or update resources on the server. This is the first step toward the full GitOps vision described in #3872.

YAML Schema (single project per file)
apiVersion: v1
kind: Project
name: my-project
description: "My project"

environments:
  - name: production
    applications:
      - name: web-api
        sourceType: github
        buildType: dockerfile
        repository: org/api-repo
        branch: main
        dockerfile: Dockerfile
        replicas: 1
        autoDeploy: true
        domains:
          - host: api.example.com
            port: 3000
            https: true
            certificateType: letsencrypt
        ports:
          - publishedPort: 8080
            targetPort: 3000
            protocol: tcp
        mounts:
          - type: volume
            mountPath: /data
            volumeName: api-data
        schedules:
          - name: cleanup
            cronExpression: "0 2 * * *"
            command: "rm -rf /tmp/logs/*.log"
            shellType: bash

    compose:
      - name: monitoring
        sourceType: github
        repository: org/monitoring
        branch: main
        composePath: ./docker-compose.yml
        domains:
          - host: grafana.example.com
            port: 3000
            serviceName: grafana

    postgres:
      - name: main-db
        dockerImage: postgres:16
        databaseName: myapp
        databaseUser: admin
        databasePassword: secure-password

    mysql:
      - name: mysql-db
        dockerImage: mysql:8
        databaseName: myapp
        databaseUser: admin
        databasePassword: pw
        databaseRootPassword: root-pw

    mariadb: [...]
    mongo: [...]
    redis: [...]
Key Design Decisions
Decision Choice
Format YAML
Scope per file Single project
Reconciliation Name-based matching, create/update only (no deletes)
Env vars Managed separately via dokploy env push
Resource coverage Applications, compose, all 5 DB types, domains, mounts, ports, redirects, security, schedules
Server targeting Optional serverName field, resolved by name
CLI target Added to existing Dokploy CLI
CLI Interface
dokploy apply -f dokploy.yaml              # Apply config
dokploy apply -f dokploy.yaml --dry-run    # Preview changes
dokploy apply -f dokploy.yaml --verbose    # Detailed output
Architecture (new files in CLI repo)
src/
├── commands/apply.ts           # oclif command entry point
├── lib/apply/
│   ├── parser.ts               # YAML parsing + Zod validation
│   ├── schema.ts               # Zod schema for dokploy.yaml
│   ├── types.ts                # TypeScript types
│   ├── reconciler.ts           # Orchestrates the full apply flow
│   ├── differ.ts               # Compares YAML vs server state → plan
│   ├── executor.ts             # Executes plan via API calls
│   ├── api-client.ts           # Typed tRPC endpoint wrappers
│   └── reporter.ts             # Terminal output formatting
Reconciliation Flow
  1. Parse & validate YAML against Zod schema (fail fast)
  2. Fetch all projects → find by name client-side (API is ID-based)
  3. For each environment → fetch or create by name
  4. For each resource → create (minimal fields) + update (remaining fields), or update if changed
  5. For each child resource (domains, ports, mounts, etc.) → match by unique key, create or update

Important implementation details:

  • Name-based lookup is done client-side (no findByName API exists)
  • Resource creation is two-step: create with minimal fields, then update with full config
  • Compose domains matched by host + serviceName (not just host)
  • If multiple resources share the same name → error out (name uniqueness not enforced in DB)

Implementation Steps

Phase 1: Foundation
  • Set up project structure in CLI repo (lib/apply/ directory)
  • Define TypeScript types (types.ts)
  • Build Zod validation schema (schema.ts)
  • Build YAML parser with validation (parser.ts)
Phase 2: API Client
  • Build typed API client wrappers for all resource types (api-client.ts)
    • Project: list, create
    • Environment: list, create
    • Application: list, create, update
    • Compose: list, create, update
    • Postgres/MySQL/MariaDB/Mongo/Redis: list, create, update
    • Domain: list, create, update
    • Port: list, create, update, delete
    • Mount: list, create, update
    • Redirect: list, create, update
    • Security: list, create, update
    • Schedule: list, create, update
Phase 3: Diff & Reconciliation
  • Build differ (differ.ts) — compare YAML config vs remote state, produce action plan
  • Build reconciler (reconciler.ts) — orchestrate the flow in dependency order
  • Build executor (executor.ts) — execute actions with error handling
Phase 4: CLI Command & Output
  • Build reporter (reporter.ts) — format plan and results for terminal
  • Build apply command (commands/apply.ts) — wire everything together with oclif flags
  • Implement --dry-run mode (compute plan, print, skip execution)
Phase 5: Testing & Docs
  • Unit tests for parser, differ, schema validation
  • Integration tests against a Dokploy instance
  • Update CLI README with apply command docs
  • Add example dokploy.yaml files

Future Extensions (out of scope)

  • --prune flag to delete resources not in YAML
  • dokploy export to generate YAML from existing state
  • Organization-level resources (notifications, certificates, registries)
  • Swarm-specific configuration block
  • GitOps reconciliation controller (ArgoCD/Flux-style)
  • Multi-file support (dokploy apply -f dir/)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in the Dokploy CLI repository by reading src/commands/apply.ts and the planned src/lib/apply/ files, beginning with schema.ts and parser.ts. Trace the existing API and oclif patterns before implementing the reconciliation flow. Done means the apply command validates YAML, produces a dry-run plan, applies supported resources, and has the listed unit, integration, and documentation coverage.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend-api-design, cli, devops
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.