I recently ran into a minor inconvenience with a configuration on one of my Vagrant machines. You see, I’m implementing a queueing service on an application and I needed that service to be started whenever the machine starts up. Normally, this is quite simple and is done by creating a file named
/etc/systemd/system with content like so:
[Unit] Description=My Queue Worker %I After=network.target [Service] User=www-data Group=www-data ExecStart=/usr/bin/php /var/www/my_project/my_script --verbose Restart=on-failure [Install] WantedBy=multi-user.target
systemctl daemon-reload and
systemctl enable myservice@1 myservice@2 to start two workers on system boot. Reboot your system, run
systemctl status myservice@* and you should see both of those services running.
The problem with doing this on Vagrant occurs when the file your service is attempting to run is located in the shared folder that doesn’t end up getting mounted until the system has already started all services. But Vagrant has that handy file for provisioning and it can do all sorts of neat things like run shell commands after provisioning. To get these very same services to start up in a Vagrant VM, you simply need to add this bit to your Vagrantfile:
Vagrant.configure("2") do | config| config.vm.provision "shell", run: "always", inline: "systemctl start myservice@1 myservice@2" end
Because this is a change to the Vagrantfile, you’ll have to re-provision the VM with
vagrant reload --provision. This will shutdown the currently running VM, and re-run all provisions. Normally, these provisions are only run during the provisioning stage of Vagrant but because we added the
run: "always" flag, this snippet will be run every time the machine is started. Now, once you’ve booted your VM with
vagrant up, ssh into it with
vagrant ssh and you should be able to run
systemctl status myservice@* to see all of your services running.