Vagrant 虚拟机管理速查表 - Vagrant 常用命令与配置大全
Vagrant 的价值可以归成一句话:把怎么搭环境写进 Vagrantfile,vagrant up 就能在任何人电脑上复现同样的虚拟机。生命周期命令本身并不复杂,真正要留意的是 box 版本锁定、同步目录选型、以及 Provision 脚本到底在什么时机执行——这三处是「我这台能跑你那台不能」的主要来源。这张表按虚拟机生命周期、Box 镜像管理、Vagrantfile 配置、网络与同步目录、多机器与 Provision、快照与插件分组,把生命周期命令与这些配置点放在一起。什么时候翻它:接手一个跑不起来的 Vagrantfile 要排查、要把本地环境交付给新同事、Windows 上文件监听很卡要换同步方式、或者需要多台机器同时起一套服务做联调。判断依据是改完配置后环境是否真的可重建:能 destroy 再 up 一次得到同样结果,才算这套定义成立。
典型使用场景
面向需要在一台笔记本上复现多台机器的完整环境、并且希望团队成员一条命令就能得到同样系统的工程师:本地跑一套 LAMP + Nginx、多台机器演练负载均衡、在 CI 里起一个带依赖服务的测试环境。Vagrant 的核心价值是把「机器」和「初始化脚本」都写进一个可 review 的 Vagrantfile,因此关键是理解它的四条状态线:虚拟机生命周期(up / halt / suspend / destroy)、box 管理(本地缓存的镜像,版本错配是故障高发区)、网络与同步目录(forwarded_port 与私有网络)、以及 provision(首次 up 与 reload 时执行,destroy 后需重跑)。最需要警惕的是 destroy:它会销毁虚拟机,但 Vagrantfile 本身不受影响,配置错误的代价是一次重新下载 box 与重新 provision。
虚拟机生命周期 9
vagrant init ubuntu/jammy64vagrant upvagrant sshvagrant haltvagrant destroyvagrant suspend / vagrant resumevagrant reloadvagrant statusvagrant global-statusBox 镜像管理 6
vagrant box add ubuntu/jammy64vagrant box listvagrant box outdatedvagrant box update --box ubuntu/jammy64vagrant box remove ubuntu/jammy64vagrant box add my-box ./package.boxVagrantfile 配置 6
config.vm.box = "ubuntu/jammy64"config.vm.hostname = "dev-server"config.vm.provider "virtualbox" do |vb|\n vb.memory = "2048"\n vb.cpus = 2\nendconfig.vm.synced_folder "./src", "/var/www"config.vm.provision "shell", path: "setup.sh"config.vm.provision "shell", inline: "apt-get update"网络与同步目录 6
config.vm.network "forwarded_port", guest: 80, host: 8080config.vm.network "private_network", ip: "192.168.33.10"config.vm.network "public_network"config.vm.synced_folder "./src", "/var/www", type: "nfs"config.vm.synced_folder "./data", "/data", disabled: truevagrant port多机器与 Provision 6
config.vm.define "web" do |web|\n web.vm.box = "ubuntu/jammy64"\nendconfig.vm.define "db" do |db|\n db.vm.box = "ubuntu/jammy64"\nendvagrant up webvagrant ssh webvagrant provisionvagrant provision --provision-with shell快照与插件 7
vagrant snapshot save my-snapshotvagrant snapshot restore my-snapshotvagrant snapshot listvagrant snapshot delete my-snapshotvagrant plugin install vagrant-vbguestvagrant plugin listvagrant package --output my-box.box参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
vagrant init ubuntu/jammy64 | 在当前目录生成一份可用的 Vagrantfile,是所有后续命令的前提 | vagrant init ubuntu/jammy64 |
vagrant up | 创建并启动虚拟机;首次会下载 box 并执行 provision,之后每次启动都会重新跑 provision | vagrant up |
vagrant ssh | 用 vagrant 账号登录虚拟机,省去记用户名与密码 | vagrant ssh |
vagrant halt | 正常关机,磁盘与配置保留;这是「暂停一天」该用的命令 | vagrant halt |
vagrant destroy | 销毁虚拟机与其磁盘;不可撤销,Vagrantfile 保留但要重新下载与 provision | vagrant destroy |
vagrant suspend / vagrant resume | 把虚拟机内存快照落盘后挂起,恢复时状态与挂起前完全一致,比 halt 更快但占磁盘 | vagrant suspend |
vagrant reload | 重启虚拟机并重新执行 provision,是「改了 provision 脚本」后的标准动作 | vagrant reload |
vagrant status | 查看当前项目下每台机器的状态(running / poweroff / not created) | vagrant status |
vagrant global-status | 列出目录下所有项目的虚拟机状态,解决「我是不是在别的目录操作」的困惑 | vagrant global-status |
vagrant box add ubuntu/jammy64 | 把 box 下载到本地缓存,之后其它项目用同一个 box 就不用再下 | vagrant box add ubuntu/jammy64 |
vagrant box list | 列出本地已缓存的 box 与版本,能解释为什么版本对不上 | vagrant box list |
vagrant box outdated | 检查已装 box 是否有新版本,是升级前的标准检查 | vagrant box outdated |
vagrant box remove ubuntu/jammy64 | 移除本地缓存的 box;报错时先确认没有虚拟机仍在使用它 | vagrant box remove ubuntu/jammy64 |
config.vm.box | 指定使用哪个 box;版本锁定写在这里,改它需要 destroy 后重建才生效 | config.vm.box = "ubuntu/jammy64" |
config.vm.hostname | 设置虚拟机内主机名,排障时用于确认连的是哪台 | config.vm.hostname = "dev-server" |
vb.memory / vb.cpus | 在 provider 块里调整内存与 CPU;改后必须 reload 才生效 | config.vm.provider "virtualbox" do |vb|\n vb.memory = "2048"\n vb.cpus = 2\nend |
config.vm.synced_folder "./src", "/var/www" | 把宿主机目录挂进虚拟机;默认类型是 VirtualBox 共享文件夹,性能差时改 nfs | config.vm.synced_folder "./src", "/var/www" |
type: "nfs" | 同步目录改用 NFS,在 Linux 宿主机上性能明显好于共享文件夹 | config.vm.synced_folder "./src", "/var/www", type: "nfs" |
disabled: true | 默认不挂载该目录,需要时再用 vagrant up --enable-... 打开 | config.vm.synced_folder "./data", "/data", disabled: true |
config.vm.provision "shell", path: "setup.sh" | 引用外部脚本做初始化,脚本逻辑复杂时比 inline 更可维护 | config.vm.provision "shell", path: "setup.sh" |
config.vm.provision "shell", inline: "apt-get update" | 直接内联一段命令,适合一两行的轻量初始化 | config.vm.provision "shell", inline: "apt-get update" |
forwarded_port | 把宿主机端口映射到虚拟机端口,是本地访问容器内服务的标准做法 | config.vm.network "forwarded_port", guest: 80, host: 8080 |
private_network, ip: "192.168.33.10" | 私有网络固定 IP,多机互相访问与文档化地址都依赖它 | config.vm.network "private_network", ip: "192.168.33.10" |
vagrant port | 查映射端口的实际分配值;自动分配或被占用时会与配置不同 | vagrant port |
config.vm.define "web" / "db" | 定义多台机器,之后可以只操作其中一台 | config.vm.define "web" do |web|\n web.vm.box = "ubuntu/jammy64"\nend |
vagrant up web | 只启动具名的那一台,多机项目里避免全部拉起来 | vagrant up web |
vagrant ssh web | 登录指定机器;多机项目里不加名字会登错 | vagrant ssh web |
vagrant provision | 不重启直接重跑 provision 脚本,是改完 setup.sh 后的正确做法 | vagrant provision |
vagrant provision --provision-with shell | 只跑 shell 类 provision,跳过 chef/puppet 等其它 provisioner | vagrant provision --provision-with shell |
vagrant snapshot save / restore / list / delete | 快照是比 box 更细粒度的回滚点,装完依赖后存一个能省大量重装时间 | vagrant snapshot save my-snapshot |
vagrant plugin install | 安装 Vagrant 插件;provider 支持(virtualbox / libvirt)也靠插件提供 | vagrant plugin install vagrant-vbguest |
vagrant plugin list | 确认已装插件,排查 provider 不可用时先看这里 | vagrant plugin list |
vagrant package --output my-box.box | 把当前虚拟机打包成 box 供团队复用,等于团队的自定义基础镜像 | vagrant package --output my-box.box |
易错点与避坑指南
现象vagrant up 报找不到 box,或用的 box 版本与预期不符。
原因Vagrantfile 里写的是浮动版本或短名,本地缓存的却是另一个版本,两者不匹配。
处置用 vagrant box list 看本地实际版本,再把 Vagrantfile 锁到该精确版本;需要时先 vagrant box add 补齐。
现象vagrant destroy 后再 vagrant up,耗时极长且装好的东西全没了。
原因destroy 销毁的是虚拟机磁盘,provision 的一切都不保留,只有 Vagrantfile 还在。
处置在装完依赖后执行 vagrant snapshot save my-snapshot,日后用 vagrant snapshot restore 回滚,而不是重装。
现象改了 setup.sh 里的命令,重新 vagrant up 却没有生效。
原因up 只是启动已存在的机器,provision 脚本内容不会因文件变化而自动重跑(即使重跑也依赖脚本自身幂等)。
处置改完脚本执行 vagrant provision 或 vagrant reload;并让脚本自身可重复执行(用 apt 的 state=present 思路而非裸安装)。
现象宿主机能 ping 通私有 IP,但虚拟机里连不上对方。
原因配置了 private_network 却没指定 ip 时地址不确定;宿主机防火墙与 Vagrant 允许的网段也可能不一致。
处置为每台机器固定 ip,并确认宿主机防火墙放行了 192.168.33.0/24。
现象同步目录在虚拟机里是空的,或者性能极卡。
原因宿主机路径写错、路径含中文/空格导致挂载失败;默认的共享文件夹在部分场景下 I/O 非常慢。
处置在虚拟机里 mount 检查挂载是否真的成功;Linux 宿主机上把 type 改成 "nfs"。
现象端口映射后宿主机访问不通,报 connection refused。
原因服务只监听了 127.0.0.1 而不是 0.0.0.0,端口转发进来的连接因此被拒;或端口已被占用。
处置让服务监听 0.0.0.0,并用 vagrant port 核对实际分配到的宿主端口。
现象vagrant box remove 报 box 仍在使用中。
原因有虚拟机仍在以该 box 创建,Vagrant 拒绝删除正在被引用的 box。
处置先 vagrant status 确认相关项目,把对应虚拟机 destroy 掉再移除 box。
现象多机项目里 `vagrant ssh` 总是登进同一台,停错了机器。
原因未指定机器名时 Vagrant 使用 Vagrantfile 里第一个 define 的机器。
处置始终显式写机器名(vagrant ssh web),并用 vagrant status 核对每台的当前状态。
排障路径
1看当前目录下每台机器的状态
vagrant status区分 not created / poweroff / running,再决定该 up 还是 reload。
2看所有项目的机器状态
vagrant global-status怀疑自己在别的目录操作时用它定位。
3核对本地缓存的 box 与版本
vagrant box list版本错配是启动失败的第一嫌疑。
4检查是否有 box 可升级
vagrant box outdated升级前先备份好 Vagrantfile 与 provision 脚本。
5确认已装插件与 provider 支持
vagrant plugin listprovider 不可用时先确认插件是否装上。
6查端口实际分配值
vagrant port与 Vagrantfile 里写的 host 端口不一致时,说明发生了自动改分配。
命令示例
起一台带端口转发的开发机
vagrant init ubuntu/jammy64
vagrant box add ubuntu/jammy64
vagrant up
vagrant port
vagrant sshvagrant init 只写 Vagrantfile,不会下载镜像,所以必须单独 vagrant box add;Vagrantfile 里已经配了 provider 的同步目录时 add 会自动完成,但保险起见先 add 再 up。vagrant port 用来确认转发映射的真实结果,别假设配置里写了 8080 就一定是 8080——端口被占用时 VirtualBox 会自动往后顺延。
输出
==> web: 80 (guest) => 8080 (host) ==> default: Running (virtualbox)
Provision 是幂等入口,调试时反复重跑
vagrant provision
vagrant provision --provision-with shell
vagrant reload改完 setup.sh 后不需要 destroy 再 up,用 vagrant provision 重跑脚本即可,省掉几分钟的重建时间。写 shell provision 时要自己处理幂等(apt-get update 每次都跑、无条件的 >> append 会把配置写重复),因为 Vagrant 只保证执行一次,不保证脚本本身可重复执行。
破坏性操作前先存快照
vagrant status
vagrant snapshot save my-snapshot
vagrant snapshot list
vagrant snapshot restore my-snapshotdestroy 之前存一个快照,出问题时的恢复路径是 vagrant snapshot restore my-snapshot,而不是从零 vagrant init + up 再重跑所有 provision。快照存在 .vagrant 目录里,记得确认它没被 .gitignore 之外的清理脚本删掉——快照文件是可以随项目目录一起复制的。
多机器:define 定义,up 指定启动
vagrant status
vagrant up web
vagrant ssh web
vagrant global-status两个 config.vm.define 块存在同一个 Vagrantfile 里,vagrant up 不带名字会把所有机器都拉起来,内存和端口都会翻倍。日常只调试 web 时始终显式写 vagrant up web。vagrant global-status 能看到本机所有项目里各虚拟机的状态,是「这台机器明明 up 了但连不上」的第一排查点。
输出
==> web: machine => web ==> db: machine => db
禁用默认同步目录换成固定 IP 直连
config.vm.synced_folder "./data", "/data", disabled: true
config.vm.network "private_network", ip: "192.168.33.10"
vagrant reload虚拟化 provider 的共享文件夹在 IO 密集构建下比宿主机原生速度慢很多,常见做法是 disabled: true 关掉默认 /vagrant 同步,改用 private_network 固定 IP,让宿主机直接读写虚拟机里的目录。改完必须 vagrant reload 才会重建网络配置。
常见坑与注意事项
- vagrant destroy 不可撤销:虚拟磁盘、已 provision 的配置、装在里面的数据库和密钥全部消失。如果 Vagrantfile 里有 config.vm.synced_folder 的默认挂载,宿主机源码还在;但装在虚拟机内的 apt 包、数据库文件、手工创建的用户会一起没。destroy 前必须 vagrant snapshot save 或先 vagrant package --output backup.box 留一份。
- vagrant halt 只是关机(状态为 poweroff),vagrant destroy 是删除。两者都「让机器不见了」,但 halt 可以 vagrant up 重新启动且数据还在,destroy 之后只能重新 provision。团队里有人把 halt 说成「关掉」时,要确认对方是否真的会执行 destroy。
- Vagrantfile 里的 synced_folder 默认把宿主机整个项目目录以读写方式挂进虚拟机。虚拟机里运行的任何代码(含依赖里的 postinstall 脚本、Makefile)都能改写宿主机源码。共享给不受信任的环境或运行陌生项目时,先想清楚这个挂载方向。
- 端口转发映射的宿主机端口被占用时不会报错,而是自动顺延到下一个可用端口,vagrant up 照样成功。CI 脚本里硬编码 http://localhost:8080 就会连到别的东西上或直接连不上。端口映射一律用 vagrant port 读取实际值,不要从 Vagrantfile 里硬编码。
- vagrant box remove 删除的是全局 box 缓存(默认在 ~/.vagrant.d/boxes)。删掉团队公用镜像后,本地每台机器下次 vagrant up 都要重新下载几百 MB 到几 GB,离线环境直接卡死。删 box 前先用 vagrant box list 确认名字并和同事打招呼。
- vagrant package 打包的是当前虚拟机的完整快照,包含里面的所有数据、token、.env 文件和 SSH 私钥(VirtualBox 无人值守时会在机器内生成 authorized_keys)。生成的 .box 文件不要传到公开位置或提交进 Git,发布前至少删掉敏感数据。
提示
- vagrant up 首次运行会自动下载 Box 镜像,后续启动很快。
- Vagrantfile 是 Ruby 语法,但只需要基础配置即可使用。
- vagrant plugin install vagrant-vbguest 可以自动更新 VirtualBox Guest Additions。
- vagrant snapshot save/restore 可以快速保存和恢复虚拟机状态。
- NFS 同步目录比默认的 VirtualBox 共享文件夹性能更好,适合大项目。
- vagrant package 可以将配置好的虚拟机打包成 Box,方便团队共享。
- 在 Vagrantfile 里写 config.vm.box = "name:version" 锁定 box 版本,否则上游更新后同事 up 出来的环境可能和你不同。
- provision 的 "once" 只在首次 up 执行,改了 provisioning 脚本要 vagrant provision --provision-with 单独重跑。
- Windows 上默认共享文件夹在大量小文件项目里极慢,换 synced_folder type "rsync" 需 VirtualBox 4.0 以上并配合 vagrant-vbguest。
常见问题
Vagrant 虚拟机装完新依赖后想重来一遍,用 reload 还是 destroy?
优先 vagrant reload:它重启虚拟机并重新加载 Vagrantfile,但保留磁盘上的数据。若 Vagrantfile 里的 provision 脚本要重跑,用 vagrant provision;只想执行某一类 provision 加 --provision-with shell。vagrant suspend / resume 是挂起与恢复,速度最快,适合合上笔记本再回来。vagrant destroy 会销毁虚拟机、丢掉全部改动,只在确定要推倒重来时才用;日常只想看状态则用 vagrant status,用 vagrant global-status 一次看清本机所有环境。
为什么装好的虚拟机比基础镜像快那么多,代价是什么?
因为首次 vagrant up 会下载 Box 镜像并执行一次完整 provision(脚本装依赖、初始化等),之后每次启动直接复用磁盘上的既有状态,通常几秒就绪。代价是「首次很慢」和「本地脏」:模板改动后必须手动 reload 或重跑 provision 才生效。开发中反复重建代价太高时,可以用 vagrant snapshot save my-snapshot 存一个干净基线,之后 vagrant snapshot restore my-snapshot 一键回到那个状态;vagrant snapshot list 查看已有快照,delete 掉不用的。
本地开发要起多个服务(web、db),Vagrantfile 怎么写?
用 config.vm.define 给每台机器命名:config.vm.define "web" do |web| web.vm.box = "ubuntu/jammy64" end,config.vm.define "db" do |db| db.vm.box = "ubuntu/jammy64" end。之后 vagrant up web 只启动指定的机器,vagrant ssh web 登录对应实例,不带参数则全部启动。跨机访问靠网络配置:config.vm.network "forwarded_port", guest: 80, host: 8080 把 guest 端口映射到宿主机,vagrant port 可以查当前映射;需要固定 IP 互访用 config.vm.network "private_network", ip: "192.168.33.10"。
共享文件夹里装依赖特别慢,换成 NFS 有何讲究?
默认的 VirtualBox 共享文件夹在小文件密集的场景(npm install、pip install)性能很差。改成 config.vm.synced_folder "./src", "/var/www", type: "nfs" 走 NFS,速度通常明显改善。共享范围用 config.vm.synced_folder "./data", "/data", disabled: true 逐条禁用,不要把大目录都挂进去。目录与内存/资源一起在 config.vm.provider "virtualbox" do |vb| 里调:vb.memory = "2048"、vb.cpus = 2,装依赖前先确认资源给够。还可以 vagrant plugin install vagrant-vbguest 让 Guest Additions 自动更新。
怎么把调好环境的虚拟机分发给团队,而不是让每人重装一遍?
用 vagrant package --output my-box.box 把当前虚拟机打包成 Box,同事再执行 vagrant box add my-box ./package.box 就能从本地文件安装并用它初始化项目。分发前先清理 Box 镜像本身:vagrant box list 看已装了哪些,vagrant box outdated 检查有没有更新,vagrant box update --box ubuntu/jammy64 升级指定镜像,vagrant box remove 删除用不到的。保留 Vagrantfile 和 provision 脚本进版本库,打包产物只作为环境快照,二者配合才能保证别人拿到的是同一套环境。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。