Vagrant — Reproducible VM Development Environments

Practical guide to Vagrant — VM-based development environments with Vagrantfile, boxes, providers, provisioning and snapshots on the command line.

Vagrant by HashiCorp builds reproducible development environments as full virtual machines – not containers. The entire configuration lives in a single file, the Vagrantfile, which you version alongside your project. Prebuilt boxes serve as the base images, and Vagrant boots them through a provider such as VirtualBox, VMware, Hyper-V or libvirt. A single vagrant up gives every team member the exact same environment. This guide walks you through the essential commands – from initializing through provisioning to snapshots.

Initialize & Start

vagrant init <box> — Create a Vagrantfile for a specific box.

vagrant init ubuntu/jammy64

vagrant up — Start and provision the VM.

vagrant up

vagrant up --provider=<name> — Start with a specific provider.

vagrant up --provider=vmware_desktop

vagrant up --no-provision — Start without running provisioners.

vagrant up --no-provision

vagrant reload — Restart the VM (applies Vagrantfile changes).

vagrant reload

vagrant reload --provision — Restart and re-run provisioners.

vagrant reload --provision

Stop & Destroy

vagrant halt — Gracefully shut down the VM.

vagrant halt

vagrant halt -f — Force shutdown the VM.

vagrant halt -f

vagrant suspend — Suspend the VM (save state to disk).

vagrant suspend

vagrant resume — Resume a suspended VM.

vagrant resume

vagrant destroy — Stop and delete the VM completely.

vagrant destroy

vagrant destroy -f — Force destroy without confirmation.

vagrant destroy -f

SSH & Status

vagrant ssh — Connect to the VM via SSH.

vagrant ssh

vagrant ssh -c '<command>' — Run a command inside the VM via SSH.

vagrant ssh -c 'cat /etc/os-release'

vagrant ssh-config — Show SSH config (for use with ssh command).

vagrant ssh-config >> ~/.ssh/config

vagrant status — Show status of the current VM.

vagrant status

vagrant global-status — Show status of all Vagrant VMs system-wide.

vagrant global-status

vagrant port — Show port mappings for the VM.

vagrant port

Provisioning

vagrant provision — Run provisioners on a running VM.

vagrant provision

vagrant provision --provision-with <name> — Run only a specific provisioner.

vagrant provision --provision-with shell

vagrant upload <src> <dest> — Upload a file to the VM.

vagrant upload config.yaml /home/vagrant/config.yaml

Box Management

vagrant box list — List all installed boxes.

vagrant box list

vagrant box add <name> — Download and add a box.

vagrant box add ubuntu/jammy64

vagrant box update — Update the box for the current environment.

vagrant box update

vagrant box remove <name> — Remove a box from local storage.

vagrant box remove ubuntu/focal64

vagrant box outdated — Check if the box is outdated.

vagrant box outdated

vagrant package --output <file> — Package the current VM into a reusable box.

vagrant package --output mybox.box

Snapshots

vagrant snapshot save <name> — Take a named snapshot of the VM.

vagrant snapshot save before-update

vagrant snapshot restore <name> — Restore a snapshot.

vagrant snapshot restore before-update

vagrant snapshot list — List all snapshots.

vagrant snapshot list

vagrant snapshot delete <name> — Delete a snapshot.

vagrant snapshot delete before-update

vagrant snapshot push — Take a quick snapshot (stack-based).

vagrant snapshot push

vagrant snapshot pop — Restore and delete the last pushed snapshot.

vagrant snapshot pop

Conclusion

Vagrant shines wherever you need a complete, isolated environment – a different operating system, a kernel module or a setup that is awkward to reproduce with containers. Once your Vagrantfile is in place, onboarding a new team member is a single command. For lightweight, purely Linux-based services, containers are often the leaner choice; for reproducible VM environments, Vagrant remains the tool to reach for.

Further Reading

  • ddev – container-based local development environments for PHP projects
  • docker – build and run containers instead of full VMs
  • docker-compose – orchestrate multiple containers declaratively