State Management
Relevant source files
The following files were used as context for generating this wiki page:
State management in Docktree is responsible for tracking the lifecycle, configuration, and resource allocations of Docker Compose projects across multiple git worktrees. It ensures that each worktree maintains isolation while allowing the CLI to perform global operations like cleaning stale resources or viewing the status of all instances.
The system distinguishes between Local State, stored within each worktree's directory, and Global State, typically located in a shared configuration directory (e.g., via XDG_CONFIG_HOME). This dual-layer approach allows Docktree to manage unique port allocations and container names without collisions.
Sources: internal/cli/up.go:132-135, tests/concurrent_smoke_test.go:94-98
Local Instance State
Each active worktree maintains a local state file, usually named state.json, within a directory defined in the docktree.yml configuration (defaulting to .docktree). This state persists metadata about the specific instance, such as its creation time, the branch it represents, and the hash of the Compose files used to start it.
Instance Data Structure
The state.Instance struct is the primary container for local metadata.
| Field | Type | Description |
|---|---|---|
Name | string | The unique name of the instance. |
ProjectName | string | The Docker Compose project name. |
RepoRoot | string | Absolute path to the main git repository. |
WorktreeRoot | string | Absolute path to the specific worktree directory. |
Branch | string | The git branch associated with the worktree. |
ComposeFiles | []string | List of absolute paths to the Compose files used. |
ComposeFileHash | string | A hash of the Compose file contents to detect changes. |
LastActiveAt | time.Time | Timestamp of the last up command. |
Sources: internal/state/state.go:10-25, internal/cli/types.go:26-42
State Persistence Flow
When a user runs docktree up, the system initializes or updates the local state.
The flow ensures that state is synchronized locally and globally before the actual Docker containers are provisioned.
Sources: internal/cli/up.go:189-210, internal/cli/up.go:303-310
Global State and Registries
Global state provides a centralized view of all managed worktrees and shared resources. It is stored in the user's config directory (e.g., ~/.config/docktree/).
Global Instance Registry
The instances.json file tracks all known Docktree projects. This is critical for the docktree status --all and docktree clean commands, which need to identify worktrees that may have been deleted from the filesystem but still have running containers or allocated ports.
Sources: tests/concurrent_smoke_test.go:94-100, internal/cli/types.go:130-137
Port Registry
The port registry (ports.json) manages unique host port allocations. To prevent collisions during concurrent up operations, Docktree uses a file-based locking mechanism on this registry.
State Synchronization
Docktree includes a sync system to propagate changes from the main repository to various worktrees.
Sync Logic
The sync command identifies "stale" files—files defined in setup.copy that differ between the repository root and the worktree.
- Running Instances: To avoid corruption, Docktree skips syncing worktrees that are currently running according to the state/Docker status.
- Dry Run: Users can preview changes before overwriting files in multiple worktrees.
| Result Type | Field | Description |
|---|---|---|
SyncItem | Files | List of files that were (or would be) synced. |
SyncItem | Skipped | Reason for skipping a worktree (e.g., "running"). |
Sources: internal/cli/types.go:174-188, internal/cli/up.go:92-98
Resource Cleanup
The clean command uses the global state to reconcile Docktree-managed resources with the physical state of the filesystem.
Stale Resource Detection
Resources are considered stale if:
- Missing Worktree: The
WorktreeRootdefined in the state no longer exists on disk. - Explicit Cleanup: The user manually triggers cleanup for idle instances.
During cleanup, Docktree removes:
- Docker containers associated with the project.
- Docker networks.
- Port reservations in the global port registry.
- Metadata entries in the global instance registry.
- (Optional) Docker volumes if the
--volumesflag is used.
Sources: internal/cli/types.go:139-160, tests/concurrent_smoke_test.go:183-195
Conclusion
State management in Docktree acts as the "source of truth" for the CLI, enabling it to manage complex Docker Compose topologies across dynamic git worktrees. By combining local metadata with global registries and file-based locking, it provides a robust mechanism for resource isolation and automated cleanup.