Classic Logic

Working with Homestead

Homestead is a convenient way to work with Laravel. It keeps the native OS installation uncluttered with packages such as MySQL, Apache, Laravel, Composer, and so forth.

This post is a quick-start to set up a new Laravel project using Homestead. It covers:

  • Mapping project directory from your host machine to your virtual machine
  • Creating a new Laravel project
  • Making the Laravel project accessible from your browser

Detailed steps to set up Homestead is documented extensively in the official docs. I recommended getting the bigger picture first.

Here are some preferred conditions:

  1. Only one system-wide installation of Homestead. Per-project Homestead installation is overkill unless you need different versions of same package for different projects.

  2. Per-project mapping of projects. Even though you can set Homestead to track 1 parent folder containing all your Laravel projects, the official doc mentions:

    “You should always map individual projects to their own folder mapping instead of mapping your entire ~/code folder. When you map a folder the virtual machine must keep track of all disk IO for every file in the folder. This leads to performance issues if you have a large number of files in a folder.”

On my local machine, this is the folder setup:

$ tree -L 2 laravel-projects 
laravel-projects
├── p2
│   └── site2
├── project1
│   └── foofoo
└── web-ping-project
    └── laravel-web-ping

All my Laravel projects are inside laravel-projects. Each Laravel project is contained inside an outer directory. The directory p2 contains the Laravel project site-2, project1 contains the Laravel project foofoo, and web-ping-project contains the Laravel project laravel-web-ping. These outer directories will be mapped to directories within the virtual machine.

I haven’t figured out how to directly map just the Laravel projects (avoiding the outer directory), because:

  • I cannot directly create a Laravel project from within my laravel-projects directory because Laravel is not installed on my host machine (which is the whole point)
  • I cannot directly create a Laravel project from within my virtual machine unless I’m in a mapped directory because it simply does not allow me to, and I don’t want to fight the sytem using sudo.

Hence, for each project I have to

  • Create an outer directory that will hold the Laravel project
  • Map this outer directory to my virtual machine
  • Create the Laravel project from within the VM

Steps to create a new Laravel Project

To create a new Laravel project called foo,

  1. On your host-machine, go to the directory which contains your Laravel project outer directories. Create a new outer directory, say foo-project, that would contain the Laravel project foo.

    $ cd ~/codes/laravel-projects/
    $ mkdir foo-project
    
  2. Map the project folder from your host-machine to your virtual-machine.

    Open Homestead.yaml (located where you installed Homestead) and add an entry as follows:

    folders:
        - map: ~/codes/laravel-projects/foo-project
          to: /home/vagrant/code/foo-project
    

    This maps ~/codes/laravel-projects/foo-project in your host-machine to /home/vagrant/code/foo-project in your virtual-machine.

  3. Add the entry for your site in sites section of Homestead.yaml, so that it can be accessed from your browser.

    sites:
        - map: foo.test
          to: /home/vagrant/code/foo-project/foo/public
    

    Even though we haven’t yet created the Laravel project in our VM, we create the sites: entry ahead of time to avoid re-provisioning vagrant after we create the project.

    There’s nothing wrong with the following workflow though:

    1. Log into your VM
    2. Go to the appropriate location and create the Laravel project
    3. Make changes to Homestead.yaml as shown above
    4. Re-provision the VM

    Ensure you name things properly. In this case, the Laravel project’s name would be foo, and hence I mentioned foo/public within the foo-project directory even though we are yet to create the foo Laravel project.

  4. Add the following entry in a new line in the host-machine’s /etc/hosts. This points foo.test to your VM’s IP address.

    192.168.10.10	baz.test
    192.168.10.10	foo.test
    

    Substitute the above IP address with the one specified by ip: in the Homestead.yaml file.

    baz.test above is another Laravel project. Each of your Laravel sites would have an entry – all pointing to the same IP address – in /etc/hosts.

    In vastly simplified terms, when you visit foo.test on your browser, it searches /etc/hosts to check the IP address of the URL. The request then goes to that address – your virtual machine – and your virtual machine serves your laravel project.

  5. Start your virtual-machine and force the provisioners to run.

    $ vagrant up --provision
    
  6. Get inside the VM, and create the foo project inside foo-project directory.

    $ vagrant ssh
    $ cd ~/code/foo-project
    $ laravel new foo
    

    Wait for the project to be created.

Navigate to http://foo.test/ on your browser and you’ll see the landing page of your new project. Edit your project by opening up ~/codes/laravel-projects/foo-project in your host-machine.