Vagrant
Create reproducible, shareable local development environments. Define your VM in a Vagrantfile, commit it to Git, and every team member runs vagrant up to get an identical environment.
Installing Vagrant and VirtualBox
# macOS brew install --cask virtualbox brew install --cask vagrant # Windows (with Chocolatey) choco install virtualbox vagrant # Linux (Ubuntu/Debian) sudo apt-get install virtualbox wget https://releases.hashicorp.com/vagrant/2.4.1/vagrant_2.4.1_linux_amd64.deb sudo dpkg -i vagrant_2.4.1_linux_amd64.deb # Verify vagrant --version
Basic Vagrantfile
# Vagrantfile
Vagrant.configure("2") do |config|
# Base box — Ubuntu 22.04 from Vagrant Cloud
config.vm.box = "ubuntu/jammy64"
config.vm.box_version = "~> 20240301.0" # pin to a version range
# Hostname
config.vm.hostname = "dev-box"
# Network: forward port 3000 on VM to 3000 on host
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.network "forwarded_port", guest: 5432, host: 5432
# Private network (VM gets a static IP on a host-only network)
config.vm.network "private_network", ip: "192.168.56.10"
# Synced folder: host ./src → VM /var/www/html (NFS for performance)
config.vm.synced_folder "./src", "/var/www/html", type: "nfs"
# VirtualBox provider settings
config.vm.provider "virtualbox" do |vb|
vb.name = "my-dev-box"
vb.memory = "2048"
vb.cpus = 2
end
# Shell provisioner: run once on first vagrant up
config.vm.provision "shell", inline: <<-SHELL
apt-get update -y
apt-get install -y nodejs npm postgresql nginx
systemctl enable postgresql nginx
SHELL
end Ansible Provisioner
# Vagrantfile with Ansible provisioner
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64"
# Ansible is installed on the HOST machine and runs against the VM
config.vm.provision "ansible" do |ansible|
ansible.playbook = "provisioning/site.yml"
ansible.groups = {
"webservers" => ["default"],
}
ansible.extra_vars = {
node_env: "development",
app_port: 3000,
}
ansible.verbose = "v"
end
end
# For environments where Ansible is NOT on the host, use ansible_local:
# config.vm.provision "ansible_local" do |ansible|
# ansible.playbook = "provisioning/site.yml"
# # Vagrant installs Ansible inside the VM then runs it locally
# end Multi-Machine Vagrantfile
# Define multiple machines to simulate a real cluster
Vagrant.configure("2") do |config|
# Web server
config.vm.define "web" do |web|
web.vm.box = "ubuntu/jammy64"
web.vm.hostname = "web"
web.vm.network "private_network", ip: "192.168.56.10"
web.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
web.vm.provision "shell", inline: "apt-get install -y nginx && systemctl enable nginx"
end
# Database server
config.vm.define "db" do |db|
db.vm.box = "ubuntu/jammy64"
db.vm.hostname = "db"
db.vm.network "private_network", ip: "192.168.56.11"
db.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
db.vm.provision "shell", inline: "apt-get install -y postgresql && systemctl enable postgresql"
end
# Load balancer
config.vm.define "lb" do |lb|
lb.vm.box = "ubuntu/jammy64"
lb.vm.hostname = "lb"
lb.vm.network "private_network", ip: "192.168.56.9"
lb.vm.network "forwarded_port", guest: 80, host: 8080
lb.vm.provision "shell", inline: "apt-get install -y haproxy"
end
end
# vagrant up — start all machines
# vagrant up web — start only the web machine
# vagrant ssh web — SSH into web machine
# vagrant status — show all machine statuses Vagrant Commands Cheatsheet
| Command | Description |
|---|---|
vagrant up | Start VM and run provisioners (first time or after destroy) |
vagrant ssh | SSH into the running VM |
vagrant halt | Gracefully shut down the VM |
vagrant suspend | Save VM state (hibernate) — fast resume |
vagrant resume | Resume from suspended state |
vagrant reload | Restart VM (picks up Vagrantfile changes) |
vagrant reload --provision | Restart and re-run all provisioners |
vagrant destroy | Delete VM and free disk space |
vagrant status | Show running/stopped status |
vagrant box list | List downloaded base boxes |
vagrant box update | Download newer version of base box |
vagrant snapshot save NAME | Save a named VM snapshot |
Vagrant vs Docker Compose for Local Dev
| Factor | Vagrant (VMs) | Docker Compose |
|---|---|---|
| Startup time | 2–5 minutes (VM boot) | 5–30 seconds |
| RAM usage | High (512MB–4GB per VM) | Low (containers share host kernel) |
| OS isolation | Full (own kernel) | None (shared kernel) |
| Matches prod | Excellent for VM-based prod | Excellent for container-based prod |
| Provisioning | Shell, Ansible, Chef, Puppet | Dockerfile (layered builds) |
| Best for | OS testing, legacy apps, Ansible dev | Microservices, modern app dev |
Frequently Asked Questions
What is Vagrant and how does it differ from Docker for local development?▼
Vagrant manages full virtual machines (VMs) via providers like VirtualBox, VMware, or Hyper-V, each with their own kernel and OS. Docker manages lightweight containers that share the host kernel. Vagrant is better when you need: a specific OS (e.g., test on Ubuntu 22.04 from a Mac), kernel-level features, full OS testing, or when the application requires a VM (kernel modules, different filesystem, etc.). Docker is better for most microservice development since containers start in seconds, use less RAM, and Docker Compose is excellent for multi-service local stacks. Many teams replaced Vagrant with Docker Compose but Vagrant remains relevant for OS-specific testing and legacy environments.
What is a Vagrantfile and what goes in it?▼
A Vagrantfile is a Ruby script (but reads like a configuration file) that defines the virtual machine configuration: which base box to use, networking, synced folders, provisioners, and resource allocation. The Vagrantfile lives in the project root and is version-controlled so every team member gets the same environment. Key directives: config.vm.box (which OS image), config.vm.network (port forwarding or private network), config.vm.synced_folder (map host directory into VM), config.vm.provider (VirtualBox/VMware settings like RAM and CPU), and config.vm.provision (how to configure the VM: shell, Ansible, Chef, Puppet).
Where do I find Vagrant boxes?▼
Vagrant Cloud (app.vagrantup.com, formerly Vagrant Atlas) is the official registry for public Vagrant boxes. Boxes are base OS images you build your environment on top of. Popular boxes: ubuntu/jammy64 (Ubuntu 22.04), debian/bullseye64, centos/stream8, hashicorp/bionic64, bento/ubuntu-22.04 (the Bento project by Chef has well-maintained boxes). You can also build custom boxes with Packer. Boxes are versioned, so you can pin to a specific version and lock them in your Vagrantfile with config.vm.box_version.
How do synced folders work in Vagrant?▼
Synced folders share a directory between your host machine and the VM in real-time. The default sync type maps the project directory (where Vagrantfile lives) to /vagrant in the VM. For better performance, use NFS (fastest on macOS/Linux) or SMB (Windows). Example: config.vm.synced_folder './src', '/var/www/html', type: 'nfs'. This means you edit code in your IDE on the host, and the VM immediately sees the changes — no SSH copy needed. Some boxes do not include VirtualBox Guest Additions by default (needed for VirtualBox synced folders), so the vagrant-vbguest plugin auto-installs them.
What are the most commonly used Vagrant commands?▼
vagrant up — start and provision the VM (or resume if suspended). vagrant ssh — SSH into the running VM. vagrant halt — shut down the VM (preserves disk state). vagrant suspend — save VM state to disk (like hibernation, faster resume than halt). vagrant resume — resume from suspended state. vagrant reload — restart VM and re-run provisioners. vagrant reload --provision — force re-run all provisioners. vagrant destroy — delete the VM entirely (frees disk space). vagrant status — show VM status. vagrant box update — download newer version of the base box. vagrant provision — re-run provisioners without restarting.
How does Vagrant compare to Docker Compose for local development?▼
Docker Compose is now the default for most modern microservice development: faster startup (seconds vs minutes), lower resource usage (containers vs full VMs), easy multi-service networking, and tight integration with the container ecosystem. Vagrant is better when you specifically need full VM isolation, a different kernel or OS from your host, or are replicating a production VM environment. Some teams use both: Docker Compose for application services and Vagrant for infrastructure testing (e.g., testing Ansible playbooks against a real Ubuntu VM before deploying to production servers).
Related Products
on GumroadPremium Workflow Pack
Production-grade workflows, architecture guides, and deployment scripts for teams that ship. 10 advanced CI/CD workflows (blue-green, canary, E2E, security), 5 architecture deep-dives, code review checklist, PR process guide, and 5 battle-tested Bash deployment scripts.
Buy on Gumroad →GitHub Actions CI/CD Templates Pack
12 production-ready GitHub Actions workflow templates covering Node.js, Python, Docker, multi-environment deployments, security scanning, and auto-changelog. Copy, paste, ship.
Buy on Gumroad →Developer Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →You Might Also Need
Nomad Job Spec Builder
Generate HashiCorp Nomad job specification HCL from form inputs. Build service, batch, and system jobs with Docker/exec drivers, resources, and Consul service registration.
Open free tool →
Vault Policy Generator
Generate HashiCorp Vault HCL policies from path and capabilities form. Build least-privilege Vault policies for secrets access control.
Open free tool →
Docker Compose Generator
Generate docker-compose.yml configurations visually in your browser. Add services, ports, volumes, environment variables, and networks. Export production-ready YAML instantly. Free Docker tool.
Open free tool →
More Free Tools
Related Articles
Docker Compose 開發環境架設:前端、後端、資料庫一鍵啟動
用 Docker Compose 建立完整的本地開發環境,包含 React 前端、Node.js 後端、PostgreSQL 資料庫,一個指令啟動所有服務,告別「在我電腦上可以跑」的問題。
GitHub Actions 入門必讀:從 0 到自動化部署
完整的 GitHub Actions 新手教學,從基本概念、workflow 語法到實戰 CI/CD 自動部署。附完整 YAML 範例,30 分鐘學會持續整合。
DevOps Automation Tools in 2026: Orchestrating the Software Delivery Pipeline
Master DevOps automation with this guide to the tools that orchestrate modern software delivery. Covers CI/CD pipelines, infrastructure provisioning, configuration management, testing automation, and the emerging AI-assisted automation patterns that define 2026.
DevSecOps Tools Checklist 2026: 20 Essential Tools for Shift-Left Security
Complete DevSecOps tools checklist for 2026. 20 essential SAST, DAST, SCA, secrets scanning, and container security tools with free/open-source options.
Docker Compose vs Kubernetes: When to Use Each (2026)
A practical guide to choosing between Docker Compose and Kubernetes in 2026. Compare complexity, use cases, cost, and learn when to migrate from one to the other.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →