[TomatoCart] – Use vagrant with tomatocart to build development enviroment!

Vagrant is a powerful automatic tool to build development environment. It is possible to just write a programmable file to describe all of dependencies for your application. After that, you just need to run a single command – vagrant up to start a virtual machine that includes all of needed dependencies. You needn’t install them step by step, they will be installed automatically during the virtual machine startup. Once you store the vagrant file with your project code, the development environment will be same as the production environment. Your team members will have a identical development environment. Say goodbye to works on my machine.

Now, I will show you how to use vagrant for TomatoCart project:

Step 1. Create a file named Vagrantfile with following ruby script under tomatocart root directory.

require 'yaml'


vmFold = "vagrant";

configPath = vmFold + "/config.yaml"
afterScriptPath = vmFold + "/after.sh"
aliasesPath = vmFold + "/aliases"

require File.expand_path(vmFold + '/Bootstrap.rb')

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    if File.exists? aliasesPath then
        config.vm.provision "file", source: aliasesPath, destination: "~/.bash_aliases"

    if File.exists? configPath then
        Bootstrap.configure(config, YAML::load(File.read(configPath)))

    if File.exists? afterScriptPath then
        config.vm.provision "shell", path: afterScriptPath

Step 2. Create a vagrant fold under tomatocart root directory.

Step 3. Create a Bootstrap.rb with following ruby script under vagrant fold:

class Bootstrap
  def Bootstrap.configure(config, settings)
    # Set The VM Provider
    ENV['VAGRANT_DEFAULT_PROVIDER'] = settings["provider"] ||= "virtualbox"

    # Configure Local Variable To Access Scripts From Remote Location
    provisionDir = File.dirname(__FILE__) + '/provision';

    # Prevent TTY Errors
    config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"

    # Configure The Box
    config.vm.box = settings["box"] ||= "ubuntu/trusty64"
    config.vm.hostname = settings["hostname"] ||= "vagrant"

    # Configure A Private Network IP
    config.vm.network :private_network, ip: settings["ip"] ||= ""

    # Configure Additional Networks
    if settings.has_key?("networks")
      settings["networks"].each do |network|
        config.vm.network network["type"], ip: network["ip"], bridge: network["bridge"] ||= nil

    # Configure A Few VirtualBox Settings
    config.vm.provider "virtualbox" do |vb|
      vb.name = settings["name"] ||= "vagrant-vm"
      vb.customize ["modifyvm", :id, "--memory", settings["memory"] ||= "2048"]
      vb.customize ["modifyvm", :id, "--cpus", settings["cpus"] ||= "1"]
      vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
      vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
      vb.customize ["modifyvm", :id, "--ostype", "Ubuntu_64"]

    # Configure A Few VMware Settings
    ["vmware_fusion", "vmware_workstation"].each do |vmware|
      config.vm.provider vmware do |v|
        v.vmx["displayName"] = "homestead"
        v.vmx["memsize"] = settings["memory"] ||= 2048
        v.vmx["numvcpus"] = settings["cpus"] ||= 1
        v.vmx["guestOS"] = "ubuntu-64"

    # Configure A Few Parallels Settings
    config.vm.provider "parallels" do |v|
      v.update_guest_tools = true
      v.optimize_power_consumption = false
      v.memory = settings["memory"] ||= 2048
      v.cpus = settings["cpus"] ||= 1

    # Standardize Ports Naming Schema
    if (settings.has_key?("ports"))
      settings["ports"].each do |port|
        port["guest"] ||= port["to"]
        port["host"] ||= port["send"]
        port["protocol"] ||= "tcp"
      settings["ports"] = []

    # Default Port Forwarding
    default_ports = {
      80   => 8000,
      443  => 44300,
      3306 => 33060,
      5432 => 54320

    # Use Default Port Forwarding Unless Overridden
    default_ports.each do |guest, host|
      unless settings["ports"].any? { |mapping| mapping["guest"] == guest }
        config.vm.network "forwarded_port", guest: guest, host: host, auto_correct: true

    # Add Custom Ports From Configuration
    if settings.has_key?("ports")
      settings["ports"].each do |port|
        config.vm.network "forwarded_port", guest: port["guest"], host: port["host"], protocol: port["protocol"], auto_correct: true

    # Configure The Public Key For SSH Access
    if settings.include? 'authorize'
      config.vm.provision "shell" do |s|
        s.inline = "echo $1 | grep -xq \"$1\" /home/vagrant/.ssh/authorized_keys || echo $1 | tee -a /home/vagrant/.ssh/authorized_keys"
        s.args = [File.read(File.expand_path(settings["authorize"]))]

    # Copy The SSH Private Keys To The Box
    if settings.include? 'keys'
      settings["keys"].each do |key|
        config.vm.provision "shell" do |s|
          s.privileged = false
          s.inline = "echo \"$1\" > /home/vagrant/.ssh/$2 && chmod 600 /home/vagrant/.ssh/$2"
          s.args = [File.read(File.expand_path(key)), key.split('/').last]

    # Register All Of The Configured Shared Folders
    if settings.include? 'folders'
      settings["folders"].each do |folder|
        mount_opts = []

        if (folder["writable"] == "yes")
            mount_opts = ["dmode=775","fmode=775"]

        config.vm.synced_folder folder["map"], folder["to"], owner: folder["owner"], group: folder["group"], type: folder["type"] ||= nil, mount_options: mount_opts

    # #setup lamp
    config.vm.provision "shell" do |s|
      s.path = provisionDir + "/install-lamp.sh"

    # #setup site vhost
    settings["sites"].each do |site|
      config.vm.provision "shell" do |s|
        s.path = provisionDir + "/set-apache-vhosts.sh"
        s.args = [site["map"], site["to"], site["port"] ||= "80", site["ssl"] ||= "443"]

Step 4. Create a after.sh with following shell script under vagrant fold:


#Could not reliably determine the server's fully qualified domain name
if [ $(grep -c "ServerName localhost" /etc/apache2/apache2.conf) -eq 0 ]
        sudo su
        echo "ServerName localhost" >> /etc/apache2/apache2.conf

#restart apache again to ensure the virtural host added will work as espected
sudo service apache2 restart

Step 5. Create a config.yaml under vagrant fold.

Step 6. Create a provision fold under vagrant fold.

Step 7. Create a install-lamp.sh with following shell script under above provision fold:

#!/usr/bin/env bash

# Use single quotes instead of double quotes to make it work with special-character passwords

if [ ! -e $PATH_APACHE ]; then
    # update / upgrade
    sudo apt-get update
    sudo apt-get -y upgrade

    # install apache 2.5
    sudo apt-get install -y apache2

    #enable apache module rewrite
    sudo a2enmod rewrite && sudo service apache2 restart

    # php and modules
    sudo apt-get install -y php5
    sudo apt-get install -y imagemagick
    sudo apt-get install -y php5-imagick
    sudo apt-get install -y php5-curl
    sudo apt-get install -y php5-gd
    sudo apt-get install -y php5-mcrypt

    # enable php modules
    sudo php5enmod mcrypt

    # install mysql and give password to installer
    sudo debconf-set-selections <<< "mysql-server mysql-server/root_password password $PASSWORD"
    sudo debconf-set-selections <<< "mysql-server mysql-server/root_password_again password $PASSWORD"
    sudo apt-get -y install mysql-server
    sudo apt-get install -y php5-mysql

Above script is responsible for installing a lamp environment. As you can see the default root password of mysql server is root. You could change it in the file or virtual machine using ssh.

Step 8. Create a set-apache-vhosts.sh with following shell script under above provision fold:

#!/usr/bin/env bash


<VirtualHost *:80>
    ServerName $1
    ServerAlias www.$1

    ServerAdmin webmaster@localhost
    DocumentRoot $2

    ErrorLog /var/log/apache2/error.log
    CustomLog /var/log/apache2/access.log combined

    <Directory "$2">
         Options Indexes FollowSymLinks MultiViews
         AllowOverride All
         Order deny,allow
         Allow from all
         Require all granted

echo "$BLOCK" > "/etc/apache2/sites-available/$1.conf"

ln -fs "/etc/apache2/sites-available/$1.conf" "/etc/apache2/sites-enabled/$1.conf"

Above shell script is responsible for creating virtual host automatically based on the sites configured in config.yaml file.

Step 9. Put following configurations into config.yaml file created in step 5.

ip: ""
memory: 2048
cpus: 1
hostname: tomatocart
name: tocjack
provider: virtualbox
box: 'ubuntu/trusty64'

authorize: ~/.ssh/toc.pub

    - ~/.ssh/toc

    - map: /Volumes/toc
      to: /var/www
      owner: vagrant
      group: www-data

    - map: /Volumes/toc/tomatocart
      to: /var/www/tomatocart
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/admin/images
      to: /var/www/tomatocart/admin/images
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/admin/backups
      to: /var/www/tomatocart/admin/backups
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/cache
      to: /var/www/tomatocart/cache
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/download
      to: /var/www/tomatocart/download
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/images
      to: /var/www/tomatocart/images
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/includes/work
      to: /var/www/tomatocart/includes/work
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/includes/logs
      to: /var/www/tomatocart/includes/logs
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/templates
      to: /var/www/tomatocart/templates
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/admin/includes/languages
      to: /var/www/tomatocart/admin/includes/languages
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/includes/languages
      to: /var/www/tomatocart/includes/languages
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/install/includes/languages
      to: /var/www/tomatocart/install/includes/languages
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: /Volumes/toc/tomatocart/install/templates/main_page/languages
      to: /var/www/tomatocart/install/templates/main_page/languages
      owner: vagrant
      group: www-data
      writable: 'yes'

    - map: tomatocart.me
      to: /var/www/tomatocart

# ports:
#     - send: 93000
#       to: 9300
#     - send: 7777
#       to: 777
#       protocol: udp
  • authorize: The public ssh key for your virtual machine. You could generate a ssh key for it and find it under ~/.ssh fold.
  • keys: The private ssh key for your virtual machine. You could generate a ssh key for it and find it under ~/.ssh fold.
  • folders: The shared folds between your host machine and virtual machine. Use map specify the fold in your host machine. Use to specify the fold in your virtual machine. If you need to make the fold is writable, please ensure the writable is ‘yes’.

I have list the tomatocart folds need to be writable in the folders. Please change the path with your own path.

Now, you just need to go to tomatocart root directory and then run vagrant up command. You will see following content:


If you would like to access the virtual machine, please just type vagrant ssh command within your TomaToCart root directory. After that, you will be login into security shell of your virtual machine as follow:


You could verify the TomatoCart shared files under /var/www fold within your virtual machine:


Step 10. Change the /etc/hosts file of your host machine to point the domain to your virtual machine.


It means when you access www.tomatocart.me within your browser, the web server run in virtual machine whose ip is will deal with your request.


That’s it. If you are a developer, i strongly recommend you to try the vagrant for the development environment. It’s a so powerful automation tool.

Looking for quality TomatoCart hosting? Check out Arvixe Web Hosting

Tags: , | Posted under TomatoCart | RSS 2.0

Author Spotlight

Jack Yin

TomatoCart Developer & Co Founder - Arvixe Web Hosting / TomatoCart Community Liaison

Leave a Reply

Your email address will not be published. Required fields are marked *