Implementation Plan: dokploy apply - Declarative YAML Config
Nobody has claimed this yet.
- 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
- Parse & validate YAML against Zod schema (fail fast)
- Fetch all projects → find by name client-side (API is ID-based)
- For each environment → fetch or create by name
- For each resource → create (minimal fields) + update (remaining fields), or update if changed
- 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
findByNameAPI exists) - Resource creation is two-step: create with minimal fields, then update with full config
- Compose domains matched by
host+serviceName(not justhost) - 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
applycommand (commands/apply.ts) — wire everything together with oclif flags - Implement
--dry-runmode (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
applycommand docs - Add example
dokploy.yamlfiles
Future Extensions (out of scope)
--pruneflag to delete resources not in YAMLdokploy exportto 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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