docker-archive-public/docker.machine
Machine management for a container-centric world
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓38+ active contributors
- ✓Distributed ownership (top contributor 30% of recent commits)
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 4y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/docker-archive-public/docker.machine)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/docker-archive-public/docker.machine on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: docker-archive-public/docker.machine
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/docker-archive-public/docker.machine shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 38+ active contributors
- Distributed ownership (top contributor 30% of recent commits)
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 4y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live docker-archive-public/docker.machine
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/docker-archive-public/docker.machine.
What it runs against: a local clone of docker-archive-public/docker.machine — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in docker-archive-public/docker.machine | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1574 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of docker-archive-public/docker.machine. If you don't
# have one yet, run these first:
#
# git clone https://github.com/docker-archive-public/docker.machine.git
# cd docker.machine
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of docker-archive-public/docker.machine and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "docker-archive-public/docker.machine(\\.git)?\\b" \\
&& ok "origin remote is docker-archive-public/docker.machine" \\
|| miss "origin remote is not docker-archive-public/docker.machine (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/docker-machine/machine.go" \\
&& ok "cmd/docker-machine/machine.go" \\
|| miss "missing critical file: cmd/docker-machine/machine.go"
test -f "commands/commands.go" \\
&& ok "commands/commands.go" \\
|| miss "missing critical file: commands/commands.go"
test -f "drivers/amazonec2/amazonec2.go" \\
&& ok "drivers/amazonec2/amazonec2.go" \\
|| miss "missing critical file: drivers/amazonec2/amazonec2.go"
test -f "drivers/azure/azure.go" \\
&& ok "drivers/azure/azure.go" \\
|| miss "missing critical file: drivers/azure/azure.go"
test -f "commands/create.go" \\
&& ok "commands/create.go" \\
|| miss "missing critical file: commands/create.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1574 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1544d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/docker-archive-public/docker.machine"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Docker Machine is a tool that provisions Docker hosts across multiple environments (local VMs via VirtualBox, cloud providers like DigitalOcean, or on-premises data centers) by automating server creation, Docker installation, and client configuration. It solves the problem of managing heterogeneous Docker environments with a unified CLI interface rather than manual per-provider setup. Monolithic CLI tool: cmd/docker-machine/machine.go is the entry point, commands/ contains 20+ subcommands (create, ls, env, ssh, rm, provision, etc.) with peer test files, and drivers/ (not shown but implied) abstracts cloud/VM providers. Each command is a self-contained handler. Machine state and config are filesystem-based in ~/.docker/machine/.
👥Who it's for
DevOps engineers and developers who need to quickly spin up Docker hosts on diverse infrastructure (laptops, AWS, Azure, GCP, DigitalOcean, Hyper-V) without learning each provider's native tooling. Users want a single command—docker-machine create -d <driver> <name>—instead of wrestling with provider-specific APIs.
🌱Maturity & risk
This is a mature but archived project. The repo contains 954KB of Go code with comprehensive test coverage (95+ test files in /commands), multiple CI systems (.travis.yml, circle.yml, .gitlab-ci.yml, appveyor.yml), and a detailed CHANGELOG.md. However, Docker's focus has shifted to Docker Desktop and cloud-native tooling; this repo is no longer actively developed and exists in docker-archive-public, indicating it's legacy/deprecated.
High risk: this is archived/unmaintained code. The last commit is likely years old (visible from archive status). The driver-plugin architecture means third-party drivers could lag or break with Go version updates. No recent security patches. Dependency management relies on Gopkg.lock with unknown outdatedness. Suitable only for legacy workloads, not new projects.
Active areas of work
Nothing—this is archived. No active work. The repo exists as a historical reference in docker-archive-public. Any 'issues' are stale. Users should migrate to Docker Desktop or container orchestration platforms (Kubernetes, Docker Swarm).
🚀Get running
Clone and build: git clone https://github.com/docker-archive/docker-machine.git && cd docker-machine && make. The Makefile.inc and Makefile handle Go compilation. Requires Go 1.x (check Gopkg.toml for exact version). Binary output will be in ./bin/.
Daily commands:
make builds the binary. Use ./bin/docker-machine <command> locally. No dev server—it's a stateless CLI that talks to cloud APIs and SSH. Test with make test (runs Go test suite).
🗺️Map of the codebase
cmd/docker-machine/machine.go— Entry point for the docker-machine CLI application; all command routing and initialization flows through here.commands/commands.go— Core command registry and dispatcher that defines the CLI interface; essential for understanding how subcommands are structured.drivers/amazonec2/amazonec2.go— Primary driver implementation example; demonstrates the driver interface pattern used across all cloud provider integrations.drivers/azure/azure.go— Complex multi-cloud driver showing authentication, resource lifecycle, and provisioning patterns replicated across providers.commands/create.go— Orchestrates machine creation workflow; demonstrates how drivers are instantiated, validated, and provisioned.commands/mcndirs/utils.go— Manages machine configuration and certificate directory structure; critical for understanding state persistence.README.md— Project scope and feature overview; establishes what machine management responsibilities are in scope.
🛠️How to make changes
Add a New Cloud Driver
- Create driver directory:
drivers/mynewprovider/with main driver file implementing the driver interface (drivers/mynewprovider/mynewprovider.go) - Implement required driver methods: Create, Remove, Start, Stop, Restart, Kill, GetURL, GetIP, GetState, and GetConfig (
drivers/mynewprovider/mynewprovider.go) - Add provider-specific utilities for API client initialization and authentication (follow Azure pattern) (
drivers/mynewprovider/util.go) - Register the driver in the command factory by modifying the driver loader logic (
commands/create.go) - Add tests following existing driver test patterns (amazonec2_test.go as reference) (
drivers/mynewprovider/mynewprovider_test.go)
Add a New CLI Command
- Create command file in commands/ directory with struct implementing the Command interface (
commands/mynewcommand.go) - Implement Flags(), Run(), PreRunChecks() methods and command logic (
commands/mynewcommand.go) - Register command in commands registry by adding to commands map (
commands/commands.go) - Add comprehensive tests using commandstest utilities (
commands/mynewcommand_test.go)
Extend Machine Configuration & State
- Define new configuration fields in machine config struct (
commands/config.go) - Add persistence logic to save/load config files using mcndirs utilities (
commands/mcndirs/utils.go) - Add config inspection command or extend existing config.go command (
commands/config.go) - Update machine lifecycle commands to handle new config during create/provision flow (
commands/create.go)
Add Provider-Specific Authentication
- Create auth utility module in provider directory following Azure pattern (
drivers/mynewprovider/util/auth.go) - Implement credential resolution from environment, config files, and CLI flags (
drivers/mynewprovider/util/auth.go) - Add auth setup in driver initialization during Create command flow (
drivers/mynewprovider/mynewprovider.go) - Add tests for auth flows including token refresh and credential rotation (
drivers/mynewprovider/util/auth_test.go)
🔧Why these technologies
- Go — Cross-platform CLI tool requiring single binary distribution; used for Docker ecosystem tooling; enables concurrent provisioning operations.
- Cloud SDK packages (AWS SDK, Azure SDK, DigitalOcean API) — Required for vendor-specific API interactions; enables feature parity with native cloud consoles without reimplementing REST clients.
- SSH protocol — Standard remote access mechanism for all machines; enables provisioning without vendor-specific agents; compatible across all cloud providers and hypervisors.
- TLS/X.509 certificates — Secures Docker daemon communication; required for remote Docker client connections; certificates stored locally in mcndirs.
- Docker daemon provisioning via shell scripts — OS-agnostic installation method; handles version selection and configuration; avoids pre-baked images reducing setup complexity.
⚖️Trade-offs already made
-
Driver interface abstraction vs. provider-specific client libraries
- Why: Enables pluggable backends without modifying core command logic; allows third-party driver implementations.
- Consequence: Each driver must reimplement resource lifecycle patterns (Create, Start, Stop, Remove); duplication across amazonec2, azure, digitalocean drivers.
-
undefined
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
Machine state is filesystem-based in ~/.docker/machine/; no central database, so concurrent modifications can corrupt state. SSH setup assumes port 22 is open on created hosts; cloud firewalls can silently block provisioning. Driver-specific bugs are common (e.g., DigitalOcean driver may not handle API rate limits). Provisioning is blocking and slow (5-15 min); no async polling. The env command outputs shell syntax (eval "$(docker-machine env default)") which varies per shell (bash/zsh/fish/powershell)—shell detection is fragile.
🏗️Architecture
💡Concepts to learn
- Driver Plugin Architecture — Machine abstracts cloud providers and VM hypervisors as pluggable drivers; understanding how drivers implement Create/Stop/Remove/IP/SSH is key to extending the tool or debugging provider-specific issues
- SSH-based Provisioning — Machine relies entirely on SSH key pairs and SSH commands to install Docker, configure TLS certs, and manage the remote daemon—no cloud APIs for daemon control, only for VM lifecycle
- TLS Certificate Management — Machine auto-generates self-signed TLS certs for each host (~/.docker/machine/machines/<name>/) and configures the Docker daemon to use them—critical for secure client-daemon communication over the network
- Boot2Docker Image — Many drivers use boot2docker (a minimal Linux ISO with Docker pre-installed) as the base OS; understanding how machine downloads, verifies, and injects it into VMs is essential for offline/air-gap deployments
- Environment Variable Injection (DOCKER_HOST, DOCKER_CERT_PATH) — Machine's env command outputs shell exports that point the local Docker CLI to a remote daemon; this context-switching pattern predates Docker's native context feature and is fragile across shells
- Filesystem-based State Store — Machine stores all host metadata, SSH keys, and certs in ~/.docker/machine/ as plain files; concurrent access or edits can corrupt state, and cloud-synced home dirs can cause hidden conflicts
🔗Related repos
docker/docker— The Docker Engine that docker-machine configures remote Docker daemons to run—machine is a provisioning layer on top of Dockerdocker/docker-compose— Companion tool for multi-container orchestration; often used after docker-machine env sets the remote Docker hostmoby/moby— The open-source Docker Engine core; docker-machine installs this on provisioned hosts and talks to its daemon APIkubernetes/kubernetes— The successor to docker-machine for production workload orchestration; K8s and cloud-native tooling made docker-machine obsoletedocker/cli— The Docker CLI client that docker-machine configures via TLS certs and DOCKER_HOST env vars—machine acts as a context switcher before Docker v20.10 contexts became native
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add missing unit tests for commands/mount.go and commands/scp.go platform-specific implementations
The repo has commands/scp_unix.go and commands/scp_windows.go (platform-specific implementations) but no corresponding tests. Similarly, mount.go lacks comprehensive test coverage. These are critical host-to-machine file operations that need platform-specific validation. Adding tests for platform detection, error handling, and cross-platform compatibility would prevent regressions.
- [ ] Create commands/mount_unix.go and commands/mount_windows.go if needed, or add platform-specific test cases to commands/mount_test.go
- [ ] Add comprehensive tests in commands/scp_test.go covering both unix and windows code paths (currently only general scp_test.go exists)
- [ ] Test SSH key path handling, file permission preservation, and error cases on both platforms
- [ ] Verify tests run on both Unix and Windows CI environments (leverage .travis.yml and appveyor.yml)
Migrate CI configuration from Travis/AppVeyor/Circle to GitHub Actions
The repo has .travis.yml, appveyor.yml, and circle.yml (3 separate CI systems) which creates maintenance overhead and inconsistent testing. GitHub Actions is now the standard for GitHub projects. Consolidating to GitHub Actions would simplify the workflow, reduce configuration duplication, and leverage .github/pull_request_template.md that's already in place.
- [ ] Create .github/workflows/test.yml to replace .travis.yml (Linux builds, Go test suite, cross-architecture builds)
- [ ] Create .github/workflows/windows.yml to replace appveyor.yml (Windows builds with docker-machine create tests)
- [ ] Create .github/workflows/lint.yml for Go linting (gofmt, golint checks on all commands/ and cmd/ files)
- [ ] Remove .travis.yml, appveyor.yml, and circle.yml once workflows are validated
Add integration test suite for machine lifecycle commands with fake drivers
The repo has commands/commandstest/ with fake implementations (fake_command_line.go, stdout_capture.go), suggesting a test infrastructure exists but is underutilized. There are minimal tests for the complete lifecycle: create → start → stop → rm. Adding integration tests covering error states, driver failures, and state transitions would catch bugs in orchestration logic without requiring real VirtualBox/cloud infrastructure.
- [ ] Create commands/integration_test.go exercising the full machine lifecycle using fake command infrastructure
- [ ] Add tests for commands/create.go, commands/start.go, commands/stop.go, commands/rm.go sequentially to validate state management
- [ ] Test error recovery scenarios: create failures, SSH timeouts (in commands/ssh_test.go), invalid machine states
- [ ] Enhance commands/commandstest/fake_command_line.go to support stubbing machine driver responses for different failure modes
🌿Good first issues
- Add missing unit tests for commands/mount.go and commands/scp.go—these have test stubs but incomplete coverage, especially around cross-platform path handling (Unix vs Windows paths with -c flag)
- Improve the error messages in commands/create.go when driver initialization fails—currently generic 'driver failed' with no hint which driver or which step (SSH key gen, instance creation, provisioning)
- Document the expected output format of commands/ls.go (CSV-like with NAME|ACTIVE|DRIVER|STATE|URL|SWARM|DOCKER|ERRORS columns) in a shared flag definition; currently hardcoded in ls.go with no reusable format constant
⭐Top contributors
Click to expand
Top contributors
- @dgageot — 30 commits
- @unkaktus — 12 commits
- @shin- — 8 commits
- [@Yoan Blanc](https://github.com/Yoan Blanc) — 8 commits
- @guillaumerose — 3 commits
📝Recent commits
Click to expand
Recent commits
b170508— Merge pull request #4748 from StefanScherer/update-golang-1-12-9 (guillaumerose)9f4d13b— Update golang 1.12.9 (StefanScherer)a555e4f— Merge pull request #4710 from Serozd/arch-storage-driver (guillaumerose)2b36917— Merge pull request #4679 from afbjorklund/svm (guillaumerose)8eb98e3— set storage driver to overlay2 for archlinux (Serozd)173a41d— Fix broken IsVTXDisabled detection on AMD CPU (afbjorklund)61ef47d— Merge pull request #4654 from ulyssessouza/master (chris-crone)7de3f3c— Removing "dgageot" handle form "Core maintainers" since it's description doesn't exist anymore (see 60613ca470897ae9cfe3 (Ulysses Souza)58792cd— Merge pull request #4650 from dgageot/remove-dgageot (dgageot)60613ca— Remove myself from the list of maintainers (dgageot)
🔒Security observations
- High · Outdated Go Version in Dockerfile —
Dockerfile, line 1. The Dockerfile uses golang:1.12.9, which is significantly outdated (released in 2019). This version contains numerous known security vulnerabilities in the Go runtime and standard library that have been patched in newer versions. Fix: Update to a recent, actively maintained Go version (1.21+). Review and test compatibility with the current codebase. - High · Missing Package Dependency Information —
Gopkg.lock, Gopkg.toml. The dependency file content is empty or not provided. Without visibility into Gopkg.lock or go.mod, known vulnerabilities in dependencies cannot be verified. The project may contain outdated or vulnerable packages. Fix: Run 'go mod tidy' and 'go list -json -m all' to audit dependencies. Use 'go vuln' or tools like 'nancy' or 'snyk' to check for known CVEs in dependencies. - High · Insecure SSH Key Handling Pattern —
commands/create.go, drivers/amazonec2/amazonec2.go, drivers/azure/azure.go. File structure indicates SSH key generation and certificate management (e.g., 'Creating SSH key', cert copying). SSH key handling in cloud provisioning contexts is vulnerable to weak key generation, insecure storage, and improper permission management. Fix: Ensure SSH keys are generated with strong algorithms (ed25519 preferred), stored with restricted permissions (0600), and never logged or exposed in output. Audit cert/key generation logic. - Medium · Credentials in AWS Driver —
drivers/amazonec2/awscredentials.go. The amazonec2 driver includes awscredentials.go which handles AWS credentials. Potential for credential exposure through logging, environment variables, or insecure storage mechanisms. Fix: Verify credentials are never logged, printed, or stored in plaintext. Use IAM roles where possible. Implement secure credential rotation and use credential providers that don't expose secrets. - Medium · Azure Authentication Handling —
drivers/azure/azureutil/auth.go, drivers/azure/azureutil/authorizer.go. Azure driver contains auth.go and authorizer.go files indicating custom authentication logic. Custom authentication implementations are prone to bypass vulnerabilities and improper token/credential handling. Fix: Use official Azure SDK for authentication. Avoid custom token parsing or validation. Implement proper token expiration handling and refresh mechanisms. - Medium · Command Injection Risk via Shell Commands —
commands/ssh.go, commands/scp.go, commands/scp_unix.go, commands/scp_windows.go, commands/mount.go. Files like commands/ssh.go, commands/scp.go, and commands/mount.go execute shell commands to remote machines. Insufficient input validation could allow command injection attacks. Fix: Use parameterized command execution instead of shell string concatenation. Validate and sanitize all user inputs before passing to shell. Use Go's os/exec package with argument arrays, not shell interpretable strings. - Medium · Unvalidated Cloud Provider Inputs —
drivers/amazonec2/amazonec2.go, drivers/azure/azure.go. Cloud drivers (EC2, Azure) accept configuration parameters that may not be properly validated. Missing validation could allow privilege escalation, resource creation abuse, or unauthorized access. Fix: Implement strict input validation for all cloud provider configuration parameters. Whitelist acceptable values where possible. Validate VM sizes, instance types, regions, and security group configurations. - Medium · Insecure File Permissions in mcndirs —
commands/mcndirs/utils.go. The mcndirs utility handles directory operations for machine configuration. Improper file permissions could expose sensitive machine credentials, keys, and certificates. Fix: Ensure all machine config directories are created with 0700 permissions. Config files should use 0600. Verify permissions before reading/writing sensitive files. Check directory ownership. - Medium · Missing Input Validation in inspect/config Commands —
undefined. The inspect.go and config.go commands accept machine names as input. Without validation, path traversal or argument injection attacks could access unauthorized machine configs. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.