Dokku API Client
Relevant source files
The following files were used as context for generating this wiki page:
The Dokku API Client is a Go package within the dokku-mcp project that serves as the foundational infrastructure layer for all communication with a Dokku server instance. It abstracts the complexities of executing commands over SSH, providing a robust, secure, and intelligent interface for interacting with the dokku command-line tool.
This client is responsible for command execution, output parsing, security validation, capability discovery, and caching. All server plugins, such as app and core, rely on this client to perform their operations, making it a critical component of the system's architecture.
Core Architecture
The client is designed with a clear separation of concerns, using interfaces to decouple its components. The main DokkuClient interface is a composite of several smaller, focused interfaces, promoting modularity and testability.
Sources: internal/dokku-api/client.interface.go, internal/dokku-api/client.types.go:41-52
Components
The primary implementation is the client struct, which orchestrates several key components:
SSHConnectionManager: Manages the details of creating and preparing SSH commands, including authentication.DokkuCapabilities: Tracks the features of the target Dokku instance, such as version and JSON support for commands.CommandCacheManager: An optional component that caches command outputs to improve performance and reduce load on the Dokku server.slog.Logger: Used for structured logging throughout the client's operations.
The following diagram illustrates the relationship between the client and its main collaborators.
This diagram shows how various adapters use the central client struct, which in turn relies on helper components for SSH, capabilities, and caching.
Sources: internal/dokku-api/client.types.go:41-52, internal/dokku-api/base_adapter.go
Initialization
The client is instantiated via the NewDokkuClient function. This function takes a ClientConfig and a logger, sets up the SSHConnectionManager, and launches a background goroutine to perform initial capability discovery. This non-blocking discovery ensures the server can start quickly while the client learns about the target Dokku environment.
Sources: internal/dokku-api/client.go:81-111
Command Execution Lifecycle
Every command sent to Dokku passes through a well-defined lifecycle within the client to ensure security, performance, and correctness.
The diagram below outlines the sequence of operations for a typical ExecuteCommand call.
This flowchart shows the command execution path, from initial validation and cache checks to SSH execution and error handling.
Sources: internal/dokku-api/client.go:113-125
Key Stages
-
Validation:
ValidateCommandis called first. It checks the command name and arguments against a dynamic blacklist and a static list of dangerous characters (|,;,$, etc.) to prevent command injection.
Sources: internal/dokku-api/client.go:16-56, internal/dokku-api/client_blacklist_test.go -
Caching: If caching is enabled, the
cacheManagerchecks for a previously executed identical command. If a valid cache entry is found, its result is returned immediately.
Sources: internal/dokku-api/client.go:117-120 -
Execution: If the command is not cached,
executeCommandDirectprepares the full SSH command via theSSHConnectionManagerand executes it using Go'sos/execpackage with a context for timeout handling.
Sources: internal/dokku-api/client.go:126-150 -
Error Handling: The
handleCommandErrorfunction processes any execution failures. It contains specialized logic to identify common issues, such as an app not existing (NotFoundError), and to handle expected non-zero exit codes, like probing for JSON support.
Sources: internal/dokku-api/client.go:185-220 -
Result Caching: Upon successful execution or a cacheable error, the output is stored in the
cacheManagerfor future requests.
Sources: internal/dokku-api/client.go:123
Intelligent Output Parsing
The client features a sophisticated, JSON-first parsing strategy to convert Dokku's text-based output into structured data.
ExecuteWithAutoFormat
The ExecuteWithAutoFormat function is the core of this system. It intelligently decides the best way to parse a command's output.
The logic follows these steps:
- It consults the
DokkuCapabilitiesto check if the command is known to support JSON output. - If JSON is supported, it appends
--format jsonto the command. If the execution is successful and returns valid JSON, the result is returned. If it fails, the capability is downgraded to prevent future failed attempts. - If JSON support is unknown, it may perform an "opportunistic probe" for commands like
apps:reportorapps:info. A successful probe updates the capabilities for future calls. - If JSON is not available or fails, the client falls back to text-based parsing, inferring the correct strategy (e.g., key-value, list) from patterns in the command name (e.g.,
:list,:report).
This flowchart details the decision-making process for the JSON-first parsing strategy.
Sources: internal/dokku-api/client.go:323-392
Output Formats
The client can parse several common Dokku output formats, defined by the OutputFormat type.
| Format | Description | Example Command |
|---|---|---|
OutputFormatKeyValue | Lines with a key and value separated by a character (e.g., : or =). | apps:report |
OutputFormatList | A simple list of items, one per line. | apps:list |
OutputFormatTable | Tabular data with headers. | plugin:list |
OutputFormatJSON | Raw JSON output. | apps:report --format json |
OutputFormatRaw | The raw, unprocessed byte output from the command. | logs |
Sources: internal/dokku-api/client.types.go:9-15
Capability Discovery
To enable intelligent parsing and behavior, the client must understand the capabilities of the remote Dokku instance. This is handled by the DokkuCapabilities component.
-
DokkuCapabilitiesStruct: This struct stores the discovered Dokku version, a list of installed plugins, and, most importantly, a map (JSONSupport) indicating which commands support JSON output.
Sources: internal/dokku-api/capabilities.go:11-17 -
Discovery Process: When the client is initialized, the
DiscoverCapabilitiesfunction is run in a background goroutine. It executesdokku version,dokku plugin:list, and probes a list of common commands with the--format jsonflag to populate theJSONSupportmap. This asynchronous process allows the server to start without waiting for discovery to complete.
Sources: internal/dokku-api/client.go:102-108, internal/dokku-api/capabilities.go:142-198
Security Features
Security is a primary concern for the client, as it executes commands on a remote server. It employs two main security mechanisms.
Command Validation
The ValidateCommand function acts as a critical security gate before any command is executed. It sanitizes input by checking for a list of dangerousChars (e.g., ;, |, &, (, )) in both the command name and its arguments. This check is designed to prevent shell injection attacks.
Sources: internal/dokku-api/client.go:29-47
Command Blacklisting
The client implements a dynamic command blacklist. The SetBlacklist method allows the application to provide a list of string patterns at runtime. If a command name contains any of these patterns (e.g., "destroy", "uninstall"), it is blocked before any further processing occurs. This provides a configurable safety layer to prevent accidental or malicious use of destructive commands.
Sources: internal/dokku-api/client.go:23-27, internal/dokku-api/client_blacklist_test.go:28-33
Configuration
The client's behavior is configured through the ClientConfig struct, which is typically populated from a YAML file or environment variables.
| Field | Type | Description |
|---|---|---|
DokkuHost | string | SSH host of the Dokku server. |
DokkuPort | int | SSH port of the Dokku server. |
DokkuUser | string | SSH user for the Dokku server (usually "dokku"). |
DokkuPath | string | Path to the dokku executable on the server. |
SSHKeyPath | string | Filesystem path to the SSH private key for authentication. |
CommandTimeout | time.Duration | Timeout for each individual command execution. |
Cache | *CacheConfig | Configuration for the command output cache. |
Sources: internal/dokku-api/client.types.go:29-38
Summary
The Dokku API Client is a sophisticated and essential component of the dokku-mcp project. It provides a secure, reliable, and performant bridge to a Dokku instance by abstracting SSH communication, implementing a smart JSON-first parsing strategy, and enforcing strict security controls. Its ability to dynamically discover and adapt to the capabilities of the remote Dokku server makes it a flexible and powerful foundation for all server management tasks.