This document provides guidance for AI agents working with the CDP (Coolify Deploy) codebase.
CDP is a CLI tool written in Go that provides a Vercel-like deployment experience for Coolify. It enables developers to deploy applications with a single command (cdp) without requiring manual git repository setup or complex configuration.
Commands are organized in the cmd/ directory:
root.go- Main entry point, handles default deploy behaviordeploy.go- Core deployment logiclogin.go- Authentication setuplogout.go- Clear credentialsls.go- List projects/applicationslogs.go- View deployment logslink.go- Link to existing Coolify projectenv.go- Environment variable managementversion.go- Version informationhealth.go- Health check for Coolify serverrollback.go- Rollback to previous deploymentreset.go- Reset project configuration
Coolify API client implementation:
client.go- HTTP client with authenticationapplications.go- Application CRUD operationsdeployments.go- Deployment management, log parsing, health checksprojects.go- Project managementservers.go- Server listingtypes.go- API request/response types
Configuration management:
global.go- Global config (credentials, defaults) stored in~/.cdp/config.jsonproject.go- Project config stored incdp.jsonper projecttypes.go- Configuration structs
Framework detection using coolpack (github.com/coollabsio/coolpack):
detect.go- Detection + Dockerfile generation. Uses coolpack for Node.js (19 frameworks), simple file-based detection for Go/Python/Hugo/static
Deployment orchestration:
setup.go- First-time project setup wizardgit.go- Git-based deployment logic with verbose output supportdocker.go- Docker-based deployment logic with verbose output supportwatcher.go- Deployment status watcher with log streaming
Docker operations:
build.go- Docker image building (callsResult.GenerateDockerfile())push.go- Push images to registry
Git operations:
repo.go- Git repository management (init, commit, push, log)github.go- GitHub API client for repository creation
User interface:
ui.go- Terminal UI helpers (prompts, colors, output formatting) using survey librarytask_runner.go- BubbleTea task runner for async operations with spinner feedbackmessages.go- Message types for BubbleTea communication
Recent Refactoring (Dec 2024): The codebase underwent a major refactoring to improve separation of concerns:
- Deployment orchestration logic moved from
cmd/deploy.gotointernal/deploy/package - Setup wizard extracted to
internal/deploy/setup.gofor better reusability - Git deployment logic isolated in
internal/deploy/git.go - Docker deployment logic isolated in
internal/deploy/docker.go - File watcher functionality separated into
internal/deploy/watcher.go - Task runner with BubbleTea integration added to
internal/ui/task_runner.gofor async operations - Removed
cmd/whoami.go- functionality was redundant
This improves maintainability by keeping command files focused on CLI argument parsing and delegating business logic to dedicated packages.
-
Global Config (
~/.config/cdp/config.json):- Coolify URL and token
- GitHub token (optional)
- Docker registry credentials (optional)
-
Project Config (
cdp.json):- Project name and UUIDs
- Deployment method (docker/git)
- Framework detection results
- Build commands and port
- Single application UUID (supports both production and preview deployments)
-
Docker-based:
- Builds Docker image locally (linux/amd64 for server compatibility)
- Pushes to configured registry
- Creates/updates Coolify Docker image application
- Manual deploys always go to production
- Requires Docker registry configuration locally AND on Coolify server
-
Git-based (recommended):
- Creates/manages GitHub repository automatically
- Supports public/private repos
- Commits and pushes code
- Creates/updates Coolify application with preview deployments enabled
- Manual deploys go to production
- Preview deployments are created automatically by Coolify from GitHub PRs
- Requires GitHub token with
reposcope
When cdp.json doesn't exist, the deployment orchestration is handled by internal/deploy/setup.go:
- Framework detection - Analyzes project files to determine framework type
- Build settings customization - Option to edit install/build/start commands
- Deployment method selection - Choose between Git or Docker deployment
- Server selection - Select from available Coolify servers
- Project selection/creation - Use existing project or create new one
- Advanced configuration - Port, platform, branch, domain settings
- Configuration save - Generates and saves
cdp.json
The setup wizard uses a step-by-step progress indicator (1/5, 2/5, etc.) and the task runner for async operations with spinner feedback.
For operations that may take time (API calls, network requests), use the task runner pattern:
err := ui.RunTasks([]ui.Task{
{
Name: "task-id",
ActiveName: "Loading data...",
CompleteName: "✓ Loaded data",
Action: func() error {
// Your async operation here
return someAsyncOperation()
},
},
})The task runner:
- Displays a spinner while tasks execute
- Shows completion messages when tasks finish
- Handles errors gracefully
- Supports sequential task execution
- Can run in verbose mode (no spinner, immediate output)
- Uses BubbleTea for terminal UI management
The CLI supports a global --verbose / -v flag that enables detailed output:
- Disables spinners in favor of immediate streaming output
- Git operations (
CommitVerbose,PushWithTokenVerbose) stream stdout/stderr in dimmed format - Deployment operations show real-time progress
- Access verbose state via
cmd.IsVerbose()from any command
Set CDP_DEBUG=1 environment variable for internal debugging:
- Shows binary hash on startup
- Enables trace output in UI functions
- Shows detailed deployment watcher status
- Logs API call details and error information
For monitoring deployments, use deploy.WatchDeployment():
success := deploy.WatchDeployment(client, appUUID)
if success {
ui.Success("Deployment complete")
} else {
ui.Error("Deployment failed")
}The watcher:
- Polls Coolify API for deployment status
- Streams build logs in real-time (dimmed output)
- Handles various Coolify API response formats
- Timeouts after ~4 minutes with configurable polling
- Gracefully handles API errors and missing deployments
- Create file in
cmd/directory - Define command with
cobra.Command - Add to
rootCmdininit()function - Follow existing patterns for error handling and UI feedback
For Node.js frameworks: Handled automatically by coolpack (github.com/coollabsio/coolpack). Coolpack supports 19 frameworks with AST-based config parsing for SSR vs Static detection.
For non-Node.js languages (Go, Python, Hugo, etc.):
- Update
internal/detect/detect.go - Add detection logic based on file presence/patterns
- Add Dockerfile template as a const
- Update
Result.GenerateDockerfile()switch statement
- Add methods to
internal/api/client.goif needed - Define request/response types in
internal/api/types.go - Use existing
request()helper for HTTP calls
Always use internal/ui helpers:
ui.Info()- Informational messages (cyan dot prefix)ui.Success()- Success messages (green dash prefix)ui.Warning()- Warnings (yellow exclamation prefix)ui.Error()- Error messages (red X prefix)ui.Dim()- Dimmed/muted outputui.Bold()- Bold textui.Select()/ui.Input()- User prompts (GitHub CLI style via survey library)ui.Confirm()- Yes/no promptsui.Password()- Secure password inputui.LogChoice()- Log auto-selected choices without user interactionui.RunTasks()- Execute async operations with spinner feedbackui.Spacer()- Vertical spacingui.KeyValue()- Display key-value pairs (dimmed, indented)ui.List()- Display bulleted listsui.Table()- Display tabular dataui.NextSteps()- Display next steps to userui.DimStyle- Lipgloss style for dimmed log output
- Always return errors, don't panic
- Use
fmt.Errorf()with%wfor error wrapping - Check login status before API calls using
checkLogin()
- Global config:
~/.config/cdp/config.json(user-specific, permissions 0600) - Project config:
cdp.json(project-specific, should be gitignored) - Never commit credentials or tokens
Single Application Model:
- Creates one Coolify application per project with preview deployments enabled
- Manual
cdpdeploys always target production (PR number = 0) - Preview deployments are created automatically by Coolify from GitHub Pull Requests via webhooks
- Environment variables default to preview scope; use
--prodflag incdp envcommands to target production
Legacy Migration:
- Old configs with separate preview/production apps are automatically migrated
- Uses the production app as the main app and clears legacy fields
- Commands should be testable without actual API calls
- Use dependency injection patterns where possible
- Mock external services (Docker, GitHub, Coolify API)
- Commands:
cmd/*.go - API client:
internal/api/ - Config:
internal/config/ - Framework detection:
internal/detect/ - Deployment orchestration:
internal/deploy/ - Docker ops:
internal/docker/ - Git ops:
internal/git/ - UI helpers:
internal/ui/ - Entry point:
main.go - Dependencies:
go.mod - Build automation:
Makefile
- Read existing code - Understand patterns before modifying
- Maintain consistency - Follow existing code style and structure
- Update config types - If adding config fields, update both structs and save/load logic
- Handle errors gracefully - Provide clear error messages
- Use UI helpers - Maintain consistent user experience
- Test manually - Verify commands work end-to-end
The project includes a Makefile for build automation:
make build- Build binary to./bin/cdpmake install- Install to$GOPATH/binmake clean- Remove build artifactsmake test- Run testsmake help- Show available targets
Build Workflow: Always run make build && make install together when making changes to ensure the CLI is updated both in the bin directory and in the system path.
Key external packages:
github.com/spf13/cobra- CLI frameworkgithub.com/AlecAivazis/survey/v2- Interactive prompts (GitHub CLI style)github.com/charmbracelet/bubbletea- Terminal UI framework for task runnergithub.com/charmbracelet/lipgloss- Terminal stylinggithub.com/charmbracelet/bubbles- BubbleTea components (spinner)