Docker Copy is a cross-platform desktop app for migrating Docker containers, volumes, and networks between hosts. It uses SSH and rsync for data transfer and relies on Docker CLI commands on both ends.
Note: Container runtime configuration recreation is not fully automated yet. The plan includes placeholder steps to guide manual recreation.
- Move Docker workloads between hosts with a guided, repeatable plan
- Review what will change before any action is taken
- Keep volume data in sync using rsync
- Keep migrations predictable with warnings and preflight checks
- Source/target host configuration over SSH
- Inventory listing for containers, volumes, and networks
- Migration plan preview with warnings
- Volume synchronization via rsync
- Target network and volume creation
- Friendly UI built with Electron + Vite
- Connect to source and target hosts over SSH.
- Read inventory (containers, volumes, networks).
- Generate a migration plan (with warnings and placeholders).
- Create missing target networks and volumes.
- Sync volume data using rsync.
- Recreate containers manually based on the plan output.
- Docker CLI available on both hosts
- SSH access to the target host
- rsync installed locally (and on the target host when syncing volumes)
- Install dependencies.
- Start the development app.
- Configure source and target hosts.
- Generate and review the migration plan.
npm install
npm run dev- Move workloads between on-prem hosts
- Migrate a homelab to new hardware
- Stage a migration plan before a maintenance window
Use SSH keys to authenticate to remote Docker hosts without passwords.
-
Open PowerShell as your user (not admin). Confirm
ssh-keygenexists (Get-Command ssh-keygen). -
Generate a new ED25519 key pair in your user profile:
ssh-keygen -t ed25519 -C "docker-copy" -f $env:USERPROFILE\.ssh\id_ed25519
- When prompted, set a strong passphrase.
-
Start the built-in SSH agent, set it to start automatically, and add the key:
Get-Service ssh-agent | Set-Service -StartupType Automatic Start-Service ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519
-
Copy the public key to the target host (replace
user@target-host). Windows does not shipssh-copy-id, so append the key manually:Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@target-host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
-
Test the connection to verify the key works and the host key is trusted:
ssh user@target-host
-
(Optional) Add an SSH config entry at
$env:USERPROFILE\.ssh\configto set the host alias, user, and identity file.
-
Open a terminal on the machine running Docker Copy.
-
Generate a new ED25519 key pair:
ssh-keygen -t ed25519 -C "docker-copy" -f ~/.ssh/id_ed25519
- When prompted, set a strong passphrase.
-
Start the SSH agent and add the key:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519
-
Copy the public key to the target host user you will connect as:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@target-hostIf
ssh-copy-idis not available, append the key manually:cat ~/.ssh/id_ed25519.pub | ssh user@target-host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
-
Test the connection to confirm the host key is trusted and the key is accepted:
ssh user@target-host
-
(Optional) Create an SSH config entry with the host alias, user, and identity file to simplify connections.
Tip: For least-privilege access, create a dedicated migration user on the target host and grant only the required Docker permissions.
Common scripts (see package.json for the full list):
- dev: Run the Electron app with Vite in development
- build: Build the renderer and Electron main process
- package: Build a distributable app using electron-builder
- Electron 36
- React 19 + TypeScript
- Vite 7
- Docker CLI + SSH + rsync
Run the package script to build a distributable app using electron-builder.
npm run package- Store SSH keys securely and use least-privilege users.
- Review generated migration commands before executing.
- Consider a dedicated migration user on the target host.
- Container runtime configuration capture and replay
- Safer dry-run validation of remote actions
- Improved conflict detection and resolution
Free to use under the MIT License. See LICENSE.
