Feature: Deployment Management
Relevant source files
The following files were used as context for generating this wiki page:
- PHASE1_IMPLEMENTATION.md
- internal/server-plugins/app/plugin.go
- internal/server-plugins/deployment/domain/deployment.entity.go
- internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go
- internal/server-plugins/deployment/infrastructure/deployment_repository.go
- internal/server-plugins/deployment/infrastructure/deployment_status_checker.go
- internal/server-plugins/deployment/module.go
The Deployment Management feature provides a robust, asynchronous system for handling and tracking Dokku application deployments. It replaces a previous "fire-and-forget" approach, ensuring that deployment statuses are accurately monitored and reported. When a deployment is initiated, the system immediately returns a unique deployment ID, while a background poller tracks the actual status on the Dokku host.
This architecture solves critical issues like false success reports on SSH timeouts and provides observability into the deployment lifecycle. It allows clients to query the status of an ongoing or completed deployment, retrieve build logs, and get clear reasons for failures. The system is designed to be reliable, handling temporary network issues and preventing concurrent deployments for the same application.
Sources: PHASE1_IMPLEMENTATION.md
Architecture Overview
The deployment system is composed of several interconnected components that follow Domain-Driven Design (DDD) principles. The app plugin's deploy_app tool initiates the process, which flows through a service layer to the infrastructure layer. The core of the async tracking is managed by a DeploymentTracker, a DeploymentPoller, and a DeploymentStatusChecker.
The following diagram illustrates the high-level interaction between these components.
This diagram shows the flow from the user-facing tool to the background tracking components and their interaction with the Dokku host.
Sources: internal/server-plugins/app/plugin.go, internal/server-plugins/deployment/module.go, PHASE1_IMPLEMENTATION.md
Core Components
The system is built from several key components, each with a distinct responsibility.
| Component | Description | Source File |
|---|---|---|
| Deployment Entity | A domain entity representing a single deployment, its state, and associated metadata. | deployment.entity.go |
| Deployment Tracker | A thread-safe, in-memory manager for tracking the state of active deployments. | PHASE1_IMPLEMENTATION.md |
| Deployment Poller | A background worker that periodically queries Dokku for status updates on active deployments. | PHASE1_IMPLEMENTATION.md |
| Status Checker | An infrastructure component responsible for querying Dokku and interpreting the output to determine a deployment's status. | deployment_status_checker.go |
| Deployment Infrastructure | Implements the deployment logic, handling Dokku commands, managing concurrency, and orchestrating the poller. | deployment_infrastructure.go |
| Deployment Repository | An in-memory repository for storing historical deployment records. | deployment_repository.go |
Deployment Entity
The Deployment entity is the central model in the deployment domain. It encapsulates all information related to a single deployment operation.
Sources: internal/server-plugins/deployment/domain/deployment.entity.go
Fields
| Field | Type | Description |
|---|---|---|
id | string | A unique identifier generated for the deployment (e.g., deploy_1665234567). |
appName | string | The name of the application being deployed. |
gitRef | string | The Git reference (branch, tag, or commit) being deployed. Defaults to main. |
status | DeploymentStatus | The current status of the deployment. |
createdAt | time.Time | Timestamp when the deployment was initiated. |
startedAt | *time.Time | Timestamp when the deployment process began running. |
completedAt | *time.Time | Timestamp when the deployment finished (succeeded or failed). |
errorMsg | string | Contains an error message if the deployment failed. |
buildLogs | string | Aggregated build logs collected during the deployment. |
Sources: internal/server-plugins/deployment/domain/deployment.entity.go:8-18
Status Lifecycle
A Deployment transitions through several states, managed by the DeploymentStatus enum.
This state diagram shows the possible transitions for a deployment from creation to completion.
Sources: internal/server-plugins/deployment/domain/deployment.entity.go:21-27, 86-108
Asynchronous Tracking Components
The asynchronous nature of the deployment system is handled by the DeploymentTracker, DeploymentPoller, and DeploymentStatusChecker.
- DeploymentTracker: Uses a
sync.Mapto provide a thread-safe, in-memory store for active deployments. Completed deployments are automatically cleaned up after a 5-minute TTL to manage memory usage. - DeploymentPoller: Manages background polling for active deployments. It uses a ticker to trigger status checks at a configured interval (default 10 seconds). It includes logic to handle consecutive errors and a maximum polling duration (default 30 minutes) to prevent indefinite polling.
- DeploymentStatusChecker: This is the component that interacts directly with Dokku to determine the real status. It executes
apps:reportandps:reportcommands and analyzes the output to decide if a deployment ispending,running,succeeded, orfailed.
Sources: PHASE1_IMPLEMENTATION.md, internal/server-plugins/deployment/infrastructure/deployment_status_checker.go:24-73
Deployment Flow
The deployment process is divided into two main phases: initiation and background tracking.
1. Deployment Initiation
This sequence diagram shows the synchronous part of the flow, from the tool call to the start of the asynchronous tracking.
This flow ensures the client receives an immediate response, while the long-running build process is handled in the background.
Sources: internal/server-plugins/app/plugin.go:253-276, internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go:81-125, PHASE1_IMPLEMENTATION.md
2. Background Status Tracking
Once initiated, the DeploymentPoller takes over. The following flowchart describes its logic.
This loop continues until the deployment reaches a terminal state (Succeeded, Failed) or a timeout occurs.
Sources: PHASE1_IMPLEMENTATION.md, internal/server-plugins/deployment/infrastructure/deployment_infrastructure.go:128-179, internal/server-plugins/deployment/infrastructure/deployment_status_checker.go:24-73
Configuration
The behavior of the deployment poller can be configured during its initialization.
| Parameter | Default Value | Description |
|---|---|---|
| Poll Interval | 10 * time.Second | The frequency at which the poller checks the deployment status. |
| Max Poll Duration | 30 * time.Minute | The maximum time the poller will track a deployment before marking it as failed. |
| Cleanup TTL | 5 * time.Minute | The time a completed deployment remains in the in-memory tracker before being removed. |
| Max Consecutive Errors | 5 | The number of consecutive polling errors allowed before the deployment is marked as failed. |
These values are set during dependency injection wiring.
Sources: internal/server-plugins/deployment/module.go:39-43, PHASE1_IMPLEMENTATION.md
Dependency Injection
All components of the deployment feature are wired together using the fx dependency injection framework. The deployment.Module defines how each component is created and what its dependencies are. This ensures a decoupled and testable architecture.
For example, the DeploymentPoller is provided with its dependencies, the DeploymentTracker and DeploymentStatusChecker, along with configuration values.
// From internal/server-plugins/deployment/module.go
fx.Annotate(
func(
tracker *domain.DeploymentTracker,
statusChecker domain.DeploymentStatusChecker,
logger *slog.Logger,
) *domain.DeploymentPoller {
return domain.NewDeploymentPoller(
tracker,
statusChecker,
logger,
10*time.Second, // Poll every 10 seconds
30*time.Minute, // Max 30 minutes for deployment
)
},
),
This snippet shows how the poller is constructed with its dependencies and configuration.
Sources: internal/server-plugins/deployment/module.go:14-55
Conclusion
The Deployment Management feature is a significant architectural improvement that brings correctness, observability, and reliability to application deployments in dokku-mcp. By decoupling the deployment trigger from the status tracking, it provides a superior user experience with non-blocking calls and gives developers the tools to monitor the entire lifecycle of a deployment. The use of background polling with robust error handling ensures that the system's state accurately reflects the reality on the Dokku host.
Sources: PHASE1_IMPLEMENTATION.md