
Things I Wish I'd Known Before Using Vagrant - zwischenzug
https://zwischenzugs.com/2017/10/27/ten-things-i-wish-id-known-before-using-vagrant/
======
scrollaway
Here's what I wish I'd known before using Vagrant:

1\. How to properly do cross-platform, high-performance two-way synced folders
between host and guest. Most providers only support one-way syncing.
Virtualbox has shared folders, but their performance is pretty lousy and they
have issues with relative symlinks. In fact, I still don't fully know what the
correct setup is for a dev environment where the files are edited on the host
and the guest immediately picks up on them...

2\. This idea that with vagrant you'll never again say "It works on my
machine" is a lie. So many inconsistencies between Vagrant on Windows, Linux
and macOS. Internet connection sharing, line endings issues, symlinking
issues, ...

If anyone wants to see how we're using Vagrant:

[https://github.com/hearthsim/hearthsim-
vagrant](https://github.com/hearthsim/hearthsim-vagrant)

I don't want to make it sound like Vagrant isn't solving a real problem
though, it is. It's just not the unicorn it claims to be.

~~~
stephenr
2 has been a big issue with a recent client because Virtualbox is a fucking
pig in terms of features and performance compared to the commercial
alternatives.

My advice is to cough up an hour or two salary and pay for parallels or VMware
(if on Mac)

~~~
cytzol
I've been using Vagrant + Virtualbox and have been happy with it. Is Vagrant +
VMWare really that much of a step up in performance? Could you explain which
features have been helpful? Thanks.

~~~
RussianCow
Not the parent, but anecdotally, Vagrant + Parallels runs MUCH faster on my
15" MacBook Pro than Vagrant + VirtualBox. VM startup time is shorter, and CPU
usage seems to be lighter. For instance, I worked on a project where I had a
long-running process that would do a lot of file I/O and periodically collect
the results and run some calculations. On VirtualBox, this basically pegged a
CPU core while it was running, but when I switched to Parallels, CPU usage
hovered around 5%. (I'm guessing this particular example is more to do with
VirtualBox's dog-slow shared folders, but still relevant, I think.)

------
wildpeaks
A couple more for the list:

11\. Shared folders get setup before provision scripts are run

12\. You can detect provision has already run
([https://github.com/hashicorp/vagrant/issues/936#issuecomment...](https://github.com/hashicorp/vagrant/issues/936#issuecomment-288063253))
using:

    
    
      if File.exist?(".vagrant/machines/YOUR_BOX_ID/virtualbox/action_provision")
    

13\. Vagrantfile configs are actually Ruby scripts, so you could do things
like storing your box configs in JSON (like I did in
[https://github.com/wildpeaks/boilerplate-vagrant-
xenial64](https://github.com/wildpeaks/boilerplate-vagrant-xenial64) ) instead
of hardcoding them in the Vagrantfile.

14\. Virtualbox needs Hyper-V disabled whereas Docker for Windows requires
Hyper-V enabled.

~~~
djsumdog
> Vagrantfile configs are actually Ruby scripts

I took advantage of this by storing all my settings in YAML and then using the
same YAML for both Vagrant and my Ansible provisioner:

Here's the Ruby Script that loads the YAML:

[https://github.com/BigSense/vSense/blob/master/core/vagrante...](https://github.com/BigSense/vSense/blob/master/core/vagrantenv.rb)

That I call from my Vagrant file:

[https://github.com/BigSense/vSense/blob/master/core/infrastr...](https://github.com/BigSense/vSense/blob/master/core/infrastructure/Vagrantfile)

That is also loaded in all my Ansible roles:

[https://github.com/BigSense/vSense/blob/master/ansible/bigse...](https://github.com/BigSense/vSense/blob/master/ansible/bigsense.yml)

------
corford
One thing thing I can add to this that was driving me nuts (though not
strictly Vagrant's fault):

The DHCP client on Ubuntu 16.04LTS doesn't always play nice with multi NIC
vagrant machines. All my vagrant boxes are dual NIC (eth0 is the standard
10.0.2.x NAT interface and eth1 is a private interface in the 192.168.56.x
range with a static IP - which makes it easier for various vagrant machines to
talk directly to each other).

I had an infuriating issue where my boxes would startup and then randomly (it
seemed at the time) stop responding to network requests. Initially I thought
they were hanging for some reason and would tear them down and re-init them.

Finally thought to enable GUI mode and I noticed that even though a box had
stopped responding, I could login fine via the virtual box GUI.

It turned out that Ubuntu's DHCP client was ignoring /etc/network/interfaces
(auto generated by vagrant) and wrongly refreshing IP leases on both
interfaces (eth0 and eth1).

The trick is to kill the running dhclient during provisioning and restart it
with switches that force it to only maintain leases for eth0:

    
    
      machine.vm.provision "shell", inline: "kill $(pidof dhclient) && /sbin/dhclient -1 -v -pf /run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -I -df /var/lib/dhcp/dhclient6.eth0.leases eth0"

~~~
throwanem
That's not even a little bit Vagrant's fault - that's 100% Ubuntu nonsense,
the sort of thing that convinced me about a decade ago never to install Ubuntu
again. Sure, running Debian means if you want the latest and greatest you
might have to build it yourself. But it's also much less likely to hose you
for stupid reasons. I'm glad to see that the state of play has improved so
much in the intervening years!

~~~
corford
I'm also a Debian fanboy (been my preferred distro since "potatoe" days) but I
had to switch to Ubuntu for the first time for this current project. It's not
all bad but I'll return to the warm embrace of Debian for my next project.

------
therealmarv
I wished I'd known that Vagrant + Windows is always full of surprises. So many
problems with Windows developers because Vagrant will not work as expected
there :(

Anybody know any best practices what to do with Windows developers? I'm
thinking of going to docker... but I'm not sure if this really helps.

~~~
throwanem
> Anybody know any best practices what to do with Windows developers?

I always just run a Linux VM and do most things there, with host directories
cross-mounted via Cygwin sshd and sshfs (faster, more reliable, and better
permissions mapping in my experience than Virtualbox shared folders) and
anything that needs to take advantage of filesystem capabilities not supported
in NTFS, such as the symlinks mentioned in a sibling comment, done outside a
mounted directory.

This lets me get work done, but it's a suboptimal experience to say the least,
and relies heavily on my prior systems administration experience to _stay_
working when it goes weird. Absent such experience among your developers or at
least someone you can put in support of them, about the best I can recommend
is to struggle through with Vagrant and your local handful of best practices -
at least with Vagrant your dev environments are reproducible, so that when
things go too cattywampus you can just burn down the VM and pop a fresh one
out of the oven and get back to work. (If your Vagrant boxes _aren 't_
reproducible, that's the first thing you want to fix.)

Docker for Windows is not going to be an improvement here; on the one hand,
it's newer and less battle-hardened, and on the other, it has to run in a VM
anyway. (Either Hyper-V or VirtualBox, each of which has its own
idiosyncrasies, and only one of which can be used at a time - enable Hyper-V,
VirtualBox doesn't work any more.) Docker for Windows, like Docker for Mac,
comes with some plumbing that tries to smooth over the impedance mismatch
between platforms, but it's lossy and brings its own headaches, so you're just
adding more complexity to the dev env for no real gain - you can just run
Docker in your Vagrant boxes, if you actually need Docker, and have one fewer
headache that way.

~~~
corford
Similar approach here.

I usually have a "management" vagrant box that exposes my gitrepo back to the
Windows host with samba. I then have two or three other vagrant machines that
can access the same gitrepo via an NFS mount to the "management" machine.

This way I can still code in VSCode on my windows host but I do all my git
commits via the CLI on the "management" vagrant box. The advantage with this
approach is file permissions don't get messed up and symlinks work (i.e. you
can follow and edit them on the windows host).

The only major disadvantage is if your repo has symlinks you can't create new
symlinks on the windows host and you can't use Git for Windows (and, by
extension, the git addon for VSCode). This is because Samba "fakes" symlinks
on windows and doesn't truly support them (although it might be able to do so
in the future). More info here: [https://github.com/git-for-
windows/git/issues/1195](https://github.com/git-for-windows/git/issues/1195)

------
glenscott1
If you work with other developers and store your Vagrantfile in source
control, then you can allow per-developer settings using the method shown
here: [https://www.glenscott.co.uk/blog/allow-per-developer-
vagrant...](https://www.glenscott.co.uk/blog/allow-per-developer-vagrantfile-
customisations/)

~~~
stephenr
I prefer this method:
[https://gist.github.com/stephenreay/2afd4205e76836f20e176722...](https://gist.github.com/stephenreay/2afd4205e76836f20e17672238a10957)

Same basic idea but plain ruby constants no need for yaml parsing.

------
bauerd
I was a long-time Vagrant user but recently switched almost completely to
Docker (Compose). What features does Docker miss that make people keep using
Vagrant?

~~~
RussianCow
To give a counter-point to all the praise here, Docker for Mac has been one of
the most frustrating pieces of software I've had to use for work. It has
improved significantly over the first time I used it (almost immediately after
public beta), but I still occasionally run into various bugs, such as inotify
events ceasing to work arbitrarily. Any kind of networking that makes your
containers visible to the host/on the local network is also a PITA to set up
through the VM that Docker for Mac uses. It's also supposed to abstract away
the fact that it's actually running in a VM, but I have had to tweak the VM's
CPU/memory settings multiple times, and it's not obvious when you have to do
this. On top of that, last I checked, Docker for Windows is still missing some
features like inotify events, and requires you to enable Hyper-V, which of
course removes your ability to have other VMs running simultaneously.

The other side of it is that Vagrant is just easier. Docker requires
everything to fit into a "one container per service, one process per
container" model, which is a really good idea in production, but makes setting
up background services (such as the Flow server) in development way harder
than it needs to be. I'm not a devops person, so the extra overhead of trying
to figure this all out is significant. Vagrant isn't without its own technical
problems, but it mostly Just Works™, and I can do anything to the VM that I'd
do on a regular Linux machine. As someone who really doesn't care how these
things work under the hood, Vagrant has been a significantly smaller source of
friction for me.

~~~
mschuster91
> Docker requires everything to fit into a "one container per service, one
> process per container" model, which is a really good idea in production, but
> makes setting up background services (such as the Flow server) in
> development way harder than it needs to be.

No, it does not. I use Docker as vagrant replacement too, and use a self-
written bash script as "init script" that:

1) launches all services required (e.g. apache, mysql, sshd, elasticsearch) by
running "service XYZ start"

2) records the pidfiles of each service (/var/run/xyz.pid)

3) sleeps 10 seconds, waits for all the pids having exited - if yes, exit the
initscripts, if not, go back to #3

4) on SIGTERM/SIGINT, gracefully shut down the services _in the correct order_
(e.g. apache/php first, then elasticsearch, then mysql); the watcher loop of
#3 will detect all services having shut down and exit cleanly

This way I have _exact_ reproduction of a real target server and don't have to
deal with the myriad of issues that arise with docker-compose and "custom
networks". Also, the documentation on how to set up a production server,
especially the required OS packages, is embedded right in the Dockerfile (or,
as I put the setup script in its own file, in this one). Build time for an
image with identical functionality is approximately equal to what it was with
Vagrant.

In contrast to vagrant, once you build that image initially it starts up way
faster (10s for a LAMP+es stack), and provisioning it is a breeze compared to
puphpet or whatever is the trend now. And you don't have to update your setup
script unless the base OS changes, as compared to puphpet+vagrant - in fact I
can use nearly the same setup and init script across stuff as old as Debian 6
(some ancient proprietary software I had to dockerize) over Ubuntu 16.04 and
as brand new as Debian nightly.

~~~
RussianCow
I used the wrong wording: I should have said that Docker _encourages_ one
process per container, not that it _requires_ it. It's possible to do most of
the same things with Docker as you can do with a VM, including implementing a
full-blown init system, it's just a matter of effort.

Having said that, what you did is definitely non-trivial (at least it would be
for me), and you've basically re-implemented all of the stuff Vagrant gives
you for free, for a pretty marginal benefit (IMO). Maybe that setup works
better for you, but I don't understand why I should go through all that effort
when Vagrant Just Works™ most of the time, and Docker for Mac runs everything
through a VM anyway.

~~~
mschuster91
> but I don't understand why I should go through all that effort when Vagrant
> Just Works™ most of the time

Problem with Vagrant is you can't take the VM you created and deploy it on any
random Linux server (or random Docker-hosting cloud provider) - while a pure
Docker solution can be deployed literally anywhere with Docker support, as
long as you give it a way to persist the data directories of the services.
docker-compose is a hit-and-miss across hosters, and you can't use it on DC/OS
or Kubernetes environments.

I use my script collection mainly for dev environments, but it's useful when
you want to spin up QA/dev instances without having to provision real servers.

------
conradfr
If you're a PHP dev (or even not) check
[https://puphpet.com/](https://puphpet.com/)

I generate my Vagrant files for all my side projects with it and it's a real
time saver, especially if you're not savvy in those fancy provisioners or
sysadmin in general.

------
drinchev
Vagrant's private network is really cool as well. I use it to test ansible
provisioning scripts for server infrastructure.

    
    
        config.vm.define "ums-01" do |machine|
              machine.vm.network "private_network", ip: "192.168.1.10"
              machine.vm.network :forwarded_port, guest: 22, host: 2210, id: "ssh"
        end
    
        config.vm.define "ums-02" do |machine|
              machine.vm.network "private_network", ip: "192.168.1.20"
              machine.vm.network :forwarded_port, guest: 22, host: 2220, id: "ssh"
        end
    
    

\--
[https://www.vagrantup.com/docs/networking/private_network.ht...](https://www.vagrantup.com/docs/networking/private_network.html)

------
wkral
I'd advise caution with the use of landrush, at my company it was very quick
to get up and running using it, but we encountered several problems with it
over time. We have several vagrant boxes coming up and down at various times
on each developer's machine and it would tend to get out of sync in various
cases, hold on to records for machines that no longer existed and macOS DNS
cache also played a role.

Eventually we replaced it with Dnsmasq and a static IP setup with each
development box getting an immutable static IP. Dnsmasq runs on a guest VM
that needs to always be up for other purposes as well.

As always the effort from the landrush developers is much appreciated and it
may be suitable for a limited number of boxes but it didn't scale with our
usecase.

------
mitchty
Here's my advice go to GitHub and type:

filename:Vagrantfile thing you're looking for

You'd be suprised how many hidden gems are on GitHub that you can use to
figure out how to use vagrant. This tip applies more generally.

~~~
amorphid
I often find Google searches for GitHub gists to be super useful.

<stuff you care about> Vagrantfile site:gist.github.com

------
invisiblea
\- Vagrant Triggers plugin is super useful [https://github.com/emyl/vagrant-
triggers](https://github.com/emyl/vagrant-triggers)

\- I've found VMware Fusion as a provider worth the extra cost/disk space

~~~
stephenr
Do you find vmware base box availability an issue? Is it just you or a team
using VMware?

~~~
mafro
Creating your own base boxes is actually pretty straight forward since Packer.

Maintaining them is admittedly a bit of a time sink though.

~~~
stephenr
Haha I'm aware. I'm the maintainer for
[https://app.vagrantup.com/koalephant](https://app.vagrantup.com/koalephant)
\- I was curious about vmware+Vagrant usage, we don't support it right now but
I'm considering adding it.

------
msielski
Also big fan of vagrant global-status. I have it aliased to vgs in my
terminal.

Also very helpful for those using Vagrant on OSX is Vagrant Manager [0] which
gives you menu-bar integration and a quick interface to turn VMs on and off.
It's useful even to remind myself when I've left some VMs on, especially if
I'm running on battery.

[0] [http://vagrantmanager.com/](http://vagrantmanager.com/)

------
achiang
We've avoided many of the problems (and solutions) in the link by
standardizing on Ubuntu laptops for the host OS, and using vagrant-lxc to run
our vagrant guests.

[https://github.com/fgrehm/vagrant-lxc](https://github.com/fgrehm/vagrant-lxc)

At least one or two of our new hires started with OSX hosts, but switched to
Ubuntu after a while, to avoid virtualbox pain.

[edit: added vagrant-lxc link]

------
mister_mister
For me vagrant works best with declarative configuration and a runner.
something like this, with sane defaults and many options available by changing
fields in a dictionary.

[https://github.com/Attumm/vagrantfile_example/blob/master/Va...](https://github.com/Attumm/vagrantfile_example/blob/master/Vagrantfile)

------
nicolasbistolfi
Fore me something that inclined me to use vagrant, was the share feature, so I
can let anyone in the world check my development environment. Now they
deprecated that feature and [https://ngrok.com](https://ngrok.com) does the
job very well.

------
pasta
Ofcourse this depends on the kind of project, but my last experience with a
big Laravel project was that I was running the project working under Apache on
my local machine and the rest of the team was loosing a lot of time because
Vagrant was not working as expected.

I can understand the need for reproducible environments. But when so much time
is lost I doubt the first thing you need is something like Vagrant. To me
Vagrant is a tool that you use when the team starts to struggle with "works on
my machine". But not before that. Because most of the time (well for PHP at
least) it's very easy to make it work on all machines.

~~~
pivotal
I've had quite the opposite experience. Vagrant has saved my team lots of time
fighting environmental issues. The approach of running apache locally falls
apart pretty quickly as you add more components to your application. Elastic
search, mongo, one person happens to have php 7 instead of 5.2 and wrote
everything with short array syntax, etc.

We also work on many different projects, often getting dropped into something
new without much of a primer. Being able to "vagrant up" and not having to
know all the dependencies to get up and running is very handy.

Do we spend time troubleshooting vagrant weirdness? For sure, but compared to
the time saved it's a no-brainer.

~~~
samsonradu
I tend to agree with the parent comment, a small team can get away without it
if the software stack is stable. PHP 5.2 to 7 is quite a change and should
have been documented upfront. I assume that the project must conform to
certain software requirements. On the other hand, npm is full of surprises.

~~~
pivotal
I don't disagree that if you can get away with just a local development
environment that it is likely easier to get up and running. However, it
requires good documentation of project dependencies and discipline by the team
to not accidentally upgrade their version of PHP without telling anyone, both
things that are easier said than done. Vagrant lets you codify that through
"code". In the case of my employer, it's a necessity, but obviously everyone
is different.

~~~
samsonradu
Agreed, but the “Vagrant doesn’t start” saying is a real thing imo. Maybe it’s
my experience but it doesn’t feel very robust.

------
damagednoob
I've used Vagrant extensively in the past but since I found docker-compose, I
haven't reached for it over the past year.

~~~
mafro
Docker and Vagrant are two very different tools.

~~~
welly
Are they? Very different? Not really.

~~~
Can_Not
I'm pretty fustrated reading comments like these because there are use-cases
where these tools are pretty much the same and use-cases where these tools are
wildly different and you guys are going back and forth arguing semantics that
are totally meaningless without the context or use case.

~~~
ahnick
I think the parent's point is that for the majority of web development use
cases (which I'd wager was a large percentage of the Vagrant user base) Docker
has eliminated the need for Vagrant. Agreed, though that there are times when
you need to simulate software running on a particular machine and for that
Vagrant is still useful.

------
jeffshek
Another thing to add to the list is you can set Paravirtualization Interface
if you're using VirtualBox.

If your defaults are currently on "Legacy", empirically we saw 10-30% speedup
by switching to "KVM".

------
pmontra
There used to be a problem with running Vagrant on VirtualBox with more than 1
CPU: [https://github.com/rdsubhas/vagrant-
faster/issues/5](https://github.com/rdsubhas/vagrant-faster/issues/5)

Explanation and workarounds: [http://www.mihaimatei.com/virtualbox-
performance-issues-mult...](http://www.mihaimatei.com/virtualbox-performance-
issues-multiple-cpu-cores/)

Did they fix this?

------
jeff_vader
My top tip: install your dotfiles into any Vagrant VM without modifying
anything in the VMs Vagrantfile/provisioning scripts:
[https://gist.github.com/tadas-s/0cd468a4cc9fa4cafce6fe57a5dc...](https://gist.github.com/tadas-s/0cd468a4cc9fa4cafce6fe57a5dce123)

~~~
stephenr
Because you said "without modifying anything in the vms Vagrantfile" I assume
you put this in $VAGRANT_HOME/Vagrantfile?

Also, nice username. You'll need a tray.

~~~
jeff_vader
No, you put that Vagrantfile with provisioner installing your dotfiles into
$HOME/.vagrant.d/ folder. Every time vagrant creates or starts any vm it will
sort of "extend" its configuration by reading $HOME/.vagrant.d/Vagrantfile (if
it exists).

~~~
stephenr
Um yeah. That's the default location for $VAGRANT_HOME if you don't set the
env var.

------
bryanlarsen
11\. Virtual Box sucks. Try out alternatives, I like vagrant-lxc.

~~~
pmoriarty
Could you elaborate on why you think VirtualBox sucks? Or why you think
vagrant-lxc is better?

~~~
bryanlarsen
VirtualBox is slow (especially sharing files), we've had lots of problems with
it becoming corrupted, and requiring a fixed partition of RAM makes it very
hard to run more than one VM without starving your VM's or host of memory.

vagrant-lxc has none of the above problems, it is just containerization with
no virtualization penalties.

I've had lots of people tell me that Vagrant sucks. When digging into their
problems it's almost always been VirtualBox causing their problems.

------
waibelp
Thank you for "vagrant global-status". There's still a lot of boxes I don't
even remember.

~~~
zwischenzug
You're welcome!

------
marksellers
I've done development with all the databases, languages and packages installed
on the host machine, as well as with vagrant. With the VM, I have to ssh in,
or switch windows to run tests, whereas before I could just run the tests in
vim. How do people achieve fluency with these?

I suppose I could install some more of my tools on the VM, but if you take
that to its absurd conclusion, I'm just running a clone of my host on the VM.

It seems more useful, maybe, to just run databases and other services in the
VM. Those are the more difficult bits to manage usually. A good programming
language already has version and package management facilities.

Or perhaps am I missing something? Anyone have another workflow?

~~~
conradfr
Jetbrains IDE has a good SSH & Vagrant support so mostly I create tools/tasks
that launch through ssh (or use the built-in ssh client but that's like any
console except you can stay in the IDE), same for the database tool.

------
zimbatm
Another thing that's good to know: vboxfs (the default VirtualBox file-sharing
filesystem) doesn't support mmap().

The are quite a few software that use mmap to access files, especially
databases. When that happens, either avoid using the shared folder or switch
to using the nfs mount.

Here is the ticket about it that's been opened 10 years ago:
[https://www.virtualbox.org/ticket/819](https://www.virtualbox.org/ticket/819)

------
vlunkr
Adding swap really is critical. Machines running out of swap was causing my
MBP to crash ~once a day, enough that I ran linux on it for a while (it was
more stable for whatever reason) until we figured out what the issue was.

------
cwaffler
I highly recommend lando. Basically an easy to use CLI wrapper for docker
apps.

[https://docs.devwithlando.io/](https://docs.devwithlando.io/)

~~~
ahnick
From a development perspective, what's the advantage here over just using
Docker Compose? Is it the baked in recipes that it provides?

------
ironjunkie
Is anyone really using Vagrant for anything more than quick tasks on your
local dev machines? I always perceived Vagrant as a hack.

~~~
raziel2p
What would you do instead if you want to test things that need to run on
actual VMs? Configuration management or whatever. Is booting a VM at a public
cloud provider any less of a hack?

~~~
vultour
Last time I did this I just created a base VM that had Ansible set up and
anytime you wanted to get the latest environment you just ran a script.
Although I admit that I'm sort of an infrastructure fanatic and love Ansible,
so that might be why I steer away from things like Vagrant.

------
tonetheman
Yup yup this is a good list. Thanks for mentioning landrush, it is something I
could have used.

------
grabcocque
Vagrant's documentation leaves something to be desired. It's perfectly
possible to control many VMs from one Vagrantfile, but good luck figuring out
how from the docs.

I mean with a bit of ruby knowhow and some digging you can figure most stuff
out, but Vagrant's documentation still lags behind Hashicorp's other stuff
which is usually very well documented.

~~~
zwischenzug
Yeah, that's been my experience too.

Which is a shame, as it's an incredibly powerful tool, it just lacks the 'last
mile' stuff that Docker did so well.

