Starting Systemd Services with Vagrant machines
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 myservice@service
in /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
Then run 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.