14

I'm trying to set up a simple dev environment with Vagrant. The base box (that I created) has CentOS 6.5 64bit with Apache and MySQL.

The issue is, the httpd service doesn't start on boot after I reload the VM (vagrant reload or vagrant halt then up).

The problem only occurs when I run a provision script that alters the DocumentRoot and only after the first time I halt the machine.

More info:

httpd is on chkconfig on levels 2, 3, 4 and 5

There are no errors written to the error_log (on /etc/httpd/logs).

If I ssh into the machine and start the service manually, it starts with no problem.

I had the same issue with other CentOS boxes (like the chef/centos-6.5 available on vagrantcloud.com), that's why I created one myself.

Other services, like mysql, start fine, so it's a problem specific to apache.

Resuming:

  • httpd always start on first boot, even with the provision script (like after vagrant destroy)
  • httpd always start when I don't run a provision script (but I need it to set the DocumentRoot)
  • httpd doesn't start after first halt, with a provision script that messes with DocumentRoot (not sure if that's the problem).

This is my Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "centos64_lamp"
  config.vm.box_url = "<url>/centos64_lamp.box"
  config.vm.hostname = "machine.dev"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder ".", "/vagrant", owner: "root", group: "root"
  config.vm.provision :shell, :path => "vagrant_files/bootstrap.sh"

end

I tried to create the vagrant folder with owner/group root and apache. Same problem with both (as with owner vagrant).

These are the provision scripts (bootstrap.sh) that I tried. The only thing that I want them to do is to change the DocumentRoot to the vagrant folder. Neither worked.

Try 1

#!/usr/bin/env bash

sudo rm -rf /var/www/html
sudo ln -fs /vagrant/app/webroot /var/www/html

Try 2

#!/usr/bin/env bash

sudo cp /vagrant/vagrant_files/httpd.conf /etc/httpd/conf
sudo service httpd restart

The httpd.conf on the second try is equal to the default one, except for the DocumentRoot path. This second alternative allows me to do vagrant up --provision to force the restart of the service, but that should be an unnecessary step.

What else can I try to solve this? Thank you.

Zé Cipriano
  • 411
  • 1
  • 3
  • 11

4 Answers4

17

Apparently the problem was due to the vagrant folder not being mounted when Apache tries to start. Although I still don't understand why no error is thrown.

I solved it by creating an Upstart script (on the folder /etc/init) to start the service after vagrant mounts its folder (it emits an event called vagrant-mounted)

This is the script I used (with the filename httpd.conf but I don't think that's necessary).

# start apache on vagrant mounted

start on vagrant-mounted

exec sudo service httpd start

Upstart can do much more but this solves it.

Zé Cipriano
  • 411
  • 1
  • 3
  • 11
  • I dropped `sudo` , and instead used `exec service apache2 restart` in ubuntu based boxes. – Erik Dec 23 '14 at 20:13
3

First of all, check if httpd suppose to be started for specific runlevels (at least 2-5) by (which you did):

chkconfig | grep httpd

In that case it may be related that your DocumentRoot or its symlink points to Vagrant synced folder, so it's not available yet during service being started.

Workaround is to add service start httpd command at the end of your shell provisioning script, e.g.:

service httpd status || service httpd start

in order to fix it.

For more bullet-proof workaround, add it into trap function (for Bash script), e.g.:

trap onerror 1 2 3 15 ERR

#--- onerror()
onerror() {
  service httpd status || service httpd start
}

This may be not enough, so to make it start in halt & up cases, you need to run your shell as always in your Vagrantfile, for example:

config.vm.provision :shell, run: "always", :inline => "service httpd status || service httpd start"

or provide a script, e.g.:

config.vm.provision :shell, run: "always", path: "scripts/check_vm_services.sh"

Then the script may look like:

#!/usr/bin/env bash
# Script to re-check VM state.
# Run each time when vagrant command is invoked.

# Check if httpd service is running.
echo Checking services...
service httpd status || service httpd start

Alternatively check: Launching services after Vagrant mount which uses upstart event that Vagrant emits each time it mounts a synced folder that is called vagrant-mounted, so we can modify the upstart configuration file for services that depend on the Vagrant synced folder to listen and start check and restart the services after the vagrant-mounted event is emitted.

kenorb
  • 155,785
  • 88
  • 678
  • 743
0

i confirm that the above ^ solution absolutely works. i added a file named vagrant-mounted.conf within /etc/init, containing:

start on vagrant-mounted
exec sudo sh /etc/startup.sh

the shell script /etc/startup.sh i had already added, as a means of manually starting up httpd, mysqld and sendmail but required logging in via vagrant ssh after vagrant up to do so... now it's automatic. great!

0

My nginx was not starting up on Vagrant reload or Vagrant up, so this is my solution:

sudo cat > /etc/init/vagrant-mounted.conf << EOL
# start services on vagrant mounted

start on vagrant-mounted

exec sudo service php5-fpm restart
exec sudo service mysql restart
exec sudo service memcached restart
exec sudo service nginx restart
exec sudo nginx
EOL
ethanneff
  • 3,083
  • 5
  • 23
  • 15