webSIGHTdesigns - Web Design, Web Development, Web Hosting

How to Configure an Ubuntu Web Server VM with Vagrant

Posted on Tuesday, July 1st, 2014 at 10:23 pm
by webSIGHTdesigns

How to use Vagrant to configure a Linux web server virtual machine running Apache, MySQL and PHP on Ubuntu Precise.

Setting Up a New Vagrant Box

Vagrant is free and open-source software for creating and configuring virtual development environments. To set up a new vagrant instance just make a new directory to keep your virtual machine in and change into that directory:

$ mkdir precise64
$ cd precise64

Once you're in the directory where you'd like to create your virtual machine, initiate the vagrant instance:

$ vagrant init

The initiation process will create a file called Vagrantfile in the directory. This is your configuration file for your vagrant instance. Edit the file and replace it with the following:

# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise64"
  config.vm.provision :shell, :path => "bootstrap.sh"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box"
  config.vm.network :private_network, ip: "192.168.56.101"
  config.vm.synced_folder ".", "/vagrant", id: "vagrant-root",
    owner: "vagrant",
    group: "vagrant"
end

If you prefer to set up a 32-bit install of Ubuntu Precise, you can use the URL http://files.vagrantup.com/precise32.box instead.

Next you'll need to set up the bootstrap.sh file, a simple Bash script used for setting up new packages and running any Linux commands you'd like to run each time you provision the vagrant instance. Create a bootstrap.sh file and enter the following:

#!/usr/bin/env bash

sudo apt-get update 2> /dev/null

sudo apt-get install -y make 2> /dev/null

sudo apt-get install -y vim 2> /dev/null

sudo apt-get install -y apache2 2> /dev/null
sudo apt-get install -y openssl 2> /dev/null
sudo a2enmod rewrite 2> /dev/null

APACHEUSR=`grep -c 'APACHE_RUN_USER=www-data' /etc/apache2/envvars`
APACHEGRP=`grep -c 'APACHE_RUN_GROUP=www-data' /etc/apache2/envvars`
if [ APACHEUSR ]; then
    sed -i 's/APACHE_RUN_USER=www-data/APACHE_RUN_USER=vagrant/' /etc/apache2/envvars
fi
if [ APACHEGRP ]; then
    sed -i 's/APACHE_RUN_GROUP=www-data/APACHE_RUN_GROUP=vagrant/' /etc/apache2/envvars
fi
sudo chown -R vagrant:www-data /var/lock/apache2

sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password password ROOTPASSWORD'
sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password ROOTPASSWORD'
sudo apt-get install -y mysql-server 2> /dev/null
sudo apt-get install -y mysql-client 2> /dev/null

if [ ! -f /var/log/dbinstalled ];
then
    echo "CREATE USER 'mysqluser'@'localhost' IDENTIFIED BY 'USERPASSWORD'" | mysql -uroot -pROOTPASSWORD
    echo "CREATE DATABASE internal" | mysql -uroot -pROOTPASSWORD
    echo "GRANT ALL ON internal.* TO 'mysqluser'@'localhost'" | mysql -uroot -pROOTPASSWORD
    echo "flush privileges" | mysql -uroot -pROOTPASSWORD
    touch /var/log/dbinstalled
    if [ -f /vagrant/data/initial.sql ];
    then
        mysql -uroot -pROOTPASSWORD internal < /vagrant/data/initial.sql
    fi
fi

sudo apt-get install -y memcached libmemcached-tools 2> /dev/null

sudo apt-get install -y php5 php-pear php5-dev php5-gd php5-curl php5-mcrypt 2> /dev/null

yes | sudo pecl install memcache 2> /dev/null

sudo touch /etc/php5/conf.d/memcache.ini
sudo echo "extension=memcache.so" >> /etc/php5/conf.d/memcache.ini
sudo echo "memcache.hash_strategy=\"consistent\"" >> /etc/php5/conf.d/memcache.ini

# if /var/www is not a symlink then create the symlink and set up apache
if [ ! -h /var/www ];
then
    rm -rf /var/www
    ln -fs /vagrant /var/www
    sudo a2enmod rewrite 2> /dev/null
    sed -i '/AllowOverride None/c AllowOverride All' /etc/apache2/sites-available/default
    sudo service apache2 restart 2> /dev/null
fi

# restart apache
sudo service apache2 reload 2> /dev/null

# copy addwebsite command
cp /vagrant/addwebsite /usr/local/bin/addwebsite 2> /dev/null
chmod +x /usr/local/bin/addwebsite 2> /dev/null
cp /vagrant/skeleton /etc/apache2/sites-available/skeleton 2> /dev/null

sudo apt-get install -y git 2> /dev/null

sudo apt-get install -y subversion 2> /dev/null

# install phpmyadmin
mkdir /vagrant/phpmyadmin/ 2> /dev/null
wget -O /vagrant/phpmyadmin/index.html http://www.phpmyadmin.net/
awk 'BEGIN{ RS="<a *href *= *\""} NR>2 {sub(/".*/,"");print; }' /vvagrant/phpmyadmin/index.html >> /vagrant/phpmyadmin/url-list.txt
grep "http://sourceforge.net/projects/phpmyadmin/files/phpMyAdmin/" /vagrant/phpmyadmin/url-list.txt > /vagrant/phpmyadmin/phpmyadmin.url
sed -i 's/.zip/.tar.bz2/' /vagrant/phpmyadmin/phpmyadmin.url
wget -O /vagrant/phpmyadmin/phpMyAdmin.tar.bz2 `cat /vagrant/phpmyadmin/phpmyadmin.url`
mkdir /vagrant/myadm.localhost
tar jxvf /vagrant/phpmyadmin/phpMyAdmin.tar.bz2 -C /vagrant/myadm.localhost --strip 1
rm -rf /vagrant/phpmyadmin 2> /dev/null

# configure phpmyadmin
mv /vagrant/myadm.localhost/config.sample.inc.php /vagrant/myadm.localhost/config.inc.php
sed -i 's/a8b7c6d/NEWBLOWFISHSECRET/' /vagrant/myadm.localhost/config.inc.php
echo "CREATE DATABASE pma" | mysql -uroot -pROOTPASSWORD
echo "CREATE USER 'pma'@'localhost' IDENTIFIED BY 'PMAUSERPASSWD'" | mysql -uroot -pROOTPASSWORD
echo "GRANT ALL ON pma.* TO 'pma'@'localhost'" | mysql -uroot -pROOTPASSWORD
echo "GRANT ALL ON phpmyadmin.* TO 'pma'@'localhost'" | mysql -uroot -pROOTPASSWORD
echo "flush privileges" | mysql -uroot -pROOTPASSWORD
mysql -D pma -u pma -pPMAUSERPASSWD < /vagrant/myadm.localhost/examples/create_tables.sql
cat /vagrant/phpmyadmin.conf > /vagrant/myadm.localhost/config.inc.php

# set up mywebsite.localhost
if [ ! -d /vagrant/mywebsite.localhost ];
then
    git clone ssh://git@domain.com/repo/mywebsite.com /vagrant/mywebsite.localhost 2> /dev/null
    cp /vagrant/skeleton /etc/apache2/sites-available/mywebsite.localhost 2> /dev/null
    find /etc/apache2/sites-available/mywebsite.localhost -type f -exec sed -i "s/SKELETON/mywebsite.localhost/" {} \;
fi
if [ ! -d /var/lib/mysql/mywebsite ];
then
    echo "CREATE USER 'mysqluser'@'localhost' IDENTIFIED BY 'USERPASSWORD'" | mysql -uroot -pROOTPASSWORD
    echo "CREATE DATABASE mywebsite" | mysql -uroot -pROOTPASSWORD
    echo "GRANT ALL ON mywebsite.* TO 'mysqluser'@'localhost'" | mysql -uroot -pROOTPASSWORD
    echo "flush privileges" | mysql -uroot -pROOTPASSWORD
    if [ -f /vagrant/mywebsite.sql ];
    then
        mysql -uroot -pROOTPASSWORD mywebsite < /vagrant/mywebsite.sql 2> /dev/null
    fi
fi

Developer Scripts

Before we can start up vagrant we'll need to set up a couple of extra bash scripts referenced in the above bootstrap.sh configuration. First, create a file called addwebsite and enter the following contents:

#!/bin/sh

WEBROOT="/var/www/"
VHOSTDIR="/etc/apache2/sites-available/"
EXTENSION=""
RESTARTCMD="/usr/bin/sudo service apache2 reload"

if [ "$1" != '' ]; then
  if [ ! -f "$VHOSTDIR$1.conf" ]; then
    cp "$VHOSTDIR/skeleton" "$VHOSTDIR$1$EXTENSION"
    echo "created $VHOSTDIR$1$EXTENSION"
  else
    mv "$VHOSTDIR$1.conf" "$VHOSTDIR$1$EXTENSION.bak"
    cp "$VHOSTDIR/skeleton" "$VHOSTDIR$1$EXTENSION"
    echo "created $VHOSTDIR$1$EXTENSION and made a backup of the existing conf"
  fi
  find "$VHOSTDIR$1$EXTENSION" -type f -exec sed -i "s/SKELETON/$1/" {} \;
  if [ ! -d "$WEBROOT$1/" ]; then
    mkdir "$WEBROOT$1/"
    chown -R apache:apache "$WEBROOT$1/"
    echo "created $WEBROOT$1/"
  else
    echo "$WEBROOT$1/ already exists"
  fi
  sudo a2ensite $1
  $RESTARTCMD
  echo "reloaded apache"
elif [ "$1" = 'help' ] || [ "$1" = '' ]; then
  echo "usage:"
  echo "sudo addwebsite "
  echo "example: to create hostname.localhost just run the command 'sudo addwebsite hostname.localhost'"
fi

The addwebsite command uses a skeleton file to create new virtual hosts so create this file as well:

<VIRTUALHOST *:80>
 ServerAdmin webmaster@localhost
 ServerName SKELETON
 DocumentRoot /var/www/SKELETON
 <DIRECTORY />
 Options FollowSymLinks
 AllowOverride None
 </DIRECTORY>
 <DIRECTORY /var/www/SKELETON/>
  Options +FollowSymLinks
  AllowOverride All
 </DIRECTORY>
 ErrorLog ${APACHE_LOG_DIR}/SKELETON_error.log
 # Possible values: debug, info, notice, warn, error, crit, alert, emerg
 LogLevel warn
 CustomLog ${APACHE_LOG_DIR}/SKELETON_access.log combined
</VIRTUALHOST>

Optionally, you may also want to create a couple of scripts to make the command to create a new database and import a sql file simpler.

Create the /usr/local/bin/adddb file:

#!/bin/sh

SQLUSER=""
SQLROOTPW=""

if [ "$1" != '' ]; then
  echo "CREATE DATABASE $1" | mysql -uroot -p$SQLROOTPW
  echo "GRANT ALL ON $1.* TO '$SQLUSER'@'localhost'" | mysql -uroot -p$SQLROOTPW
  echo "flush privileges" | mysql -uroot -p$SQLROOTPW
  echo "added database."
elif [ "$1" = 'help' ] || [ "$1" = '' ]; then
  echo "usage:"
  echo "sudo adddb "
  echo "example: to create a new database just run the command 'sudo adddb mywebsite'"
fi

Create the /usr/local/bin/importdb file:

#!/bin/sh

SQLROOTPW=""
 
if [ "$1" != '' ]; then
  DB=`echo "$1" | sed 's/.sql//g'`
  mysql -uroot -p$SQLROOTPW $DB < $1
  echo "imported database."
elif [ "$1" = 'help' ] || [ "$1" = '' ]; then
  echo "usage:"
  echo "importdb "
  echo "example: to import a database just run the command 'importdb mywebsite.sql' where 'mywebsite' is the name of the database to import into"
fi

The above scripts provide new commands for common developer actions:

$ addwebsite mydomain.localhost
$ adddb mydomain
$ importdb mydomain.sql

Vagrant Commands

We're now ready to start up our vagrant instance:

$ vagrant up

The first time a vagrant instance is started it will be provisioned. You can provision your vagrant instance, which will run the bootstrap.sh script again, using the following command:

$ vagrant provision

To SSH into the vagrant instance, use the ssh command:

$ vagrant ssh

When you're ready to stop the vagrant VM, you can issue the following command:

$ vagrant halt

One interesting feature of vagrant is you can optionally remove the virtual machine entirely from disk space until you next run vagrant up again. To delete the vagrant VM issue the following command:

$ vagrant destroy

As you can see, with a little work up front vagrant can save a lot of time in the future. See the official vagrant documentation and tutorials for more information and configuration options. Please be sure and share this tutorial if you found it useful.

webSIGHTdesigns

Sunday, May 11th, 2014 at 3:43 am

You can check out the git repository for this project over at github:

https://github.com/websightdesigns/vagrant-precise64

Please Sign In

Please sign in to post a comment.

Web Development

View details »

Web Hosting

View details »

Our Portfolio

View portfolio »

WebSight Designs webSIGHTdesigns preferred email webSIGHTdesigns United States United States