shc clone
The shc clone command creates a duplicate of a running stack, enabling testing, staging environments, or development copies.
Overview
Section titled “Overview”Clone creates a copy of a stack while keeping the original intact. It shares infrastructure with the move command but preserves the source stack.
| Operation | Flow | Original Stack |
|---|---|---|
| Clone | Backup -> Recover | Kept |
| Move | Backup -> Uninstall -> Recover | Deleted |
shc clone
Section titled “shc clone”Create a duplicate of a stack:
# Clone to same node with new nameshc clone myapp myapp-clone
# Clone to different nodeshc clone myapp myapp-prod --node node-abc123
# Clone with all connected stacks (integrations)shc clone myapp myapp-prod --node node-abc123 --all-connections
# Clone to different environmentshc clone myapp myapp-staging --target-environment staging
# Clone to different tenant (requires permission)shc clone myapp myapp-copy --target-tenant other-org
# Dry run (preview without executing)shc clone myapp myapp-clone --dry-runArguments
Section titled “Arguments”| Argument | Required | Description |
|---|---|---|
<source> | Yes | Source stack name |
<new-name> | Yes | Target stack name (positional) |
| Flag | Default | Description |
|---|---|---|
--node, -n | same | Target node (or swarm for Swarm) |
--target-environment | same | Target environment |
--target-tenant | same | Target tenant (requires permission) |
--all-connections, -a | false | Clone entire integration graph |
--rename, -r | none | Rename dependencies: old:new,old2:new2 |
--dry-run | false | Show what would be cloned |
Examples
Section titled “Examples”Basic Clone
Section titled “Basic Clone”# Create a test copy of production databaseshc clone postgres postgres-test
# Output:# Cloning postgres -> postgres-test# v Backing up postgres# v Recovering postgres-test# Clone completeClone with Integrations
Section titled “Clone with Integrations”When a stack has integrations (plugs/sockets), you must use --all-connections to clone the entire graph:
# Clone app and its database togethershc clone myapp myapp-staging --all-connections
# Clone with dependency renamingshc clone myapp myapp-test --all-connections --rename postgres:postgres-testWithout --all-connections, cloning a stack with dependencies will fail:
$ shc clone nextcloud nextcloud-testError: Stack 'nextcloud' has dependencies that would be orphaned: - postgres (provides: postgres-socket)
Use --all-connections to clone the entire integration graph, orunplug dependencies first.Clone to Different Node
Section titled “Clone to Different Node”# Clone to a specific nodeshc clone myapp myapp-prod --node node-abc123 --all-connections
# Clone to Swarm (spans all Swarm nodes)shc clone myapp myapp-prod --node swarm --all-connections
# This performs a full backup -> recover cycle# Data is transferred to the target nodeClone to Different Environment
Section titled “Clone to Different Environment”# Create staging copy from productionshc clone myapp myapp --target-environment staging
# Note: Same stack name is allowed when environment differsSame-Node Optimization
Section titled “Same-Node Optimization”When cloning to the same node (only name change), SHC uses a fast rename path instead of full backup/recover. This renames:
| Resource | Pattern |
|---|---|
| Database stack record | name column |
| Deployment directory | {base}/deployments/{tenant}/{stack}/{environment}/ |
| App directory | {base}/apps/{tenant}/{stack}/ |
| Docker Compose project | {tenant}_{environment}_{stack} |
| Docker volumes | {tenant}_{environment}_{stack}_{volume} |
| Vault secrets | tenants/{tenant}/stacks/{stack}/... |
| Schedule records | schedules.stack column |
| Backup cache | backup_cache.stack column |
Integration Handling
Section titled “Integration Handling”| Scenario | Behavior |
|---|---|
Same node, no --all-connections | Reintegrates with existing providers (shares integrations) |
Different node, no --all-connections | FAILS if stack has connections (explicit safety) |
Different node, --all-connections | Clones all connected stacks (full backup + recover) |
| Auto-suffix on collision | Dependencies get -1, -2, etc. suffix |
Name Collision Rules
Section titled “Name Collision Rules”Clone always requires a different name, environment, or tenant from the source:
# These will fail (same name in same scope)$ shc clone myapp myappError: Target stack 'myapp' already exists in tenant 'default', environment 'default'
# These work (different scope)shc clone myapp myapp --target-environment staging # Different environmentshc clone myapp myapp --target-tenant other-org # Different tenantshc clone myapp myapp-copy # Different nameProcess Flow
Section titled “Process Flow”- Preflight - Validate target doesn’t exist, check quota
- Backup - Create coordinated backup of source stack(s)
- Recover - Deploy to target with new name/location
- Integrate - Re-establish integrations (if applicable)
See Also
Section titled “See Also”shc@docs:~$