Skip to main content

Automatically start a Parallels Virtual Machine at boot on Mac OS X 10.8

Setting up my new Mac OS X server, I have a need to set up a virtual Windows Server to host some of my ASP.net websites under IIS. Knowing that there are several virtualization options available for OS X, including VMware Fusion, Oracle VM VirtualBox, and Parallels Desktop, I decided to go with Parallels as I am already used to its interface and how it works (since I use it on my MacBook to virtualize Windows 8) and I happened to have an available license for it. While the instructions below are explicit for Parallels Desktop 8, I imagine the other solutions should work in a similar fashion, especially VirtualBox since I know it has a command line interface and can easily run in headless mode.

Installing Windows Server 2012 was pretty straightforward and uneventful, the only option I can think of that might have an impact is I selected the "Share this virtual machine with others" option when creating the virtual machine. Selecting this option caused the virtual machine to be stored at /Users/Shared/Parallels instead of being placed in the signed in users home directory. This should definitely be selected if you plan on running the virtual machine under a service account rather than the owner account.

Since we're wanting to run this on machine boot without using auto login and the user's login items (as suggested in many places online) we're going to need another launchd property list file to instruct launchd to start our virtual machine for us.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.gibixonline.miu</string>
  <key>UserName</key>
  <string>miu-owner</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/prlctl</string>
    <string>start</string>
    <string>{ffae2c75-8f39-4ac5-9585-868bdfa91014}</string>
  </array>
  <key>KeepAlive</key>
  <dict>
    <key>SuccessfulExit</key>
    <false />
  </dict>
  <key>RunAtLoad</key>
  <true />
  <key>LaunchOnlyOnce</key>
  <true />
  <key>AbandonProcessGroup</key>
  <true />
</dict>
</plist>

The above file is saved using the reverse DNS style in the /Library/LaunchDaemons folder (since this is a non-interactive system process added by us) and the label matches the file name. In case I have other virtual machines in the future, I decided to use the virtual machine's name (Miu) as part of the file name (com.gibixonline.miu.plist) and label (com.gibixonline.miu). There are a couple significant items I would like to point out this particular property list file.

  • We're making use of the UserName key to launch the VM as the owner (the user which created the VM). I intend on making a service account like I did for Nginx, but I haven't done so yet. I don't think there will be any problems since I marked the VM as "Shared." Of course, if your VM lives in a home directory, the user will need to be able to write there to boot.

  • We switched from using the Program key to ProgramArguments. The last item in the array is the machine's unique identifier. You can use either the unique id or the name of the machine, I chose to use the unique identifier in case I ever changed the name of the machine. You can get the unique id by running prlctl list -a

  • LaunchOnlyOnce is added, since there is no way for launchd to know the status of the VM. This indicates that the property list should be loaded and executed once and discarded. You won't find the status of this job in the list.

  • Most importantly, AbandonProcessGroup is set. Without it, when prlctl exits, launchd will automatically terminate any process with a parent process id that matched prlctl. This meant the machine wouldn't boot for more than a second or two.

After creating the plist file, don't forget to register it with launchd by running sudo launchctl load /Library/LaunchDaemons/com.gibixonline.miu.plist. I've had no issues with the machine booting when the host boots and I haven't run in to any stability problems with the VM.

One important thing I would like to point out. When launching in headless mode like this you should avoid opening the Parallels Desktop app in your login session. In doing so, the VM will show its screen (which is nice) but you won't be able to close Parallels Desktop or log out of your Mac without suspending or stopping the virtual machine. If you accidentally do this (or had to because it disappeared from the network) simply make sure Parallels Desktop has quit and either ssh or open a terminal and type in the start command (no need for sudo, su maybe, if you're running as another user): prlctl start Miu will bring the VM right back up.

In fact, to avoid this, I installed a remote desktop client and will connect through there if I need a "console." Since the official Microsoft Remote Desktop client for Mac crashes so much and has issues with accessing a tunneled RDP session, I recommend using the free CoRD remote desktop software.

Imported Comments

Adam on Monday, August 19, 2013 at 10:38 PM wrote:

Thanks for taking the time to write this up! Its exactly what I was looking for. I think the only think missing was I had to chown on the file to root in order for "sudo launchctl load <filename>" to work.