How to Start Using Laravel Homestead as Development Environment
You have multiple choices for your development environment. You could just install everything on your host machine, you could use virtual machines, you could use Docker, you could use a remote server. I personally found that the easiest solution is to use Laravel Homestead which is a pre-packaged Vagrant box with most of the stuff you will need for developing in PHP. It's quick to set up, and you don't need to install all kinds of software on your host machine (something I dislike personally).
Code for this article can be found at GitHub repository.
First please make sure that you have Vagrant installed (it will be different depending on the OS).
Please keep in mind that this is for using one VM for one project. If you want to have multiple projects on a single VM check the official documentation.
Add the Homestead as the development dependency:
composer require --dev laravel/homestead
Then generate the Vagrantfile
, and Homestead.yaml
file by running:
php vendor/bin/homestead make
Open Homestead.yaml
file to add type: nfs
to folders
configuration. This option improves performance (might need additional plugins depending on the OS). Below is an example of how that configuration might look (our project will be named february
) :
# Homestead.yaml
# ...
folders:
- map: "/Users/ifdattic/projects/february" # directory on host
to: "/home/vagrant/february" # directory on VM
type: nfs # add this for performance
# ...
Next modify the sites
configuration. You will probably want to change the domain of your application by modifying map
property. If you're doing this for the Symfony project you will also need to change the to
property, and add type: symfony
. Below is an example of how that configuration might look:
# Homestead.yaml
# ...
sites:
# example of Symfony project
- map: www.february.dev
to: "/home/vagrant/february/web" # public directory on VM
type: symfony # use Symfony configuration
# example of Laravel project
- map: www.february.dev
to: "/home/vagrant/february/public" # public directory on VM
# ...
If you have multiple projects with their own VMs you will want to change the IP address to avoid conflicts (you can run php -r 'echo mt_rand(0, 255);'
to get a random number):
# Homestead.yaml
ip: "192.168.10.222" # go with 192.168.10.random-number-up-to-255
# ...
To make the domain, and IP work you will need to edit the hosts file on your OS. The location is different for each OS, on Unix like systems it's at /etc/hosts
. Inside that file add the line which contains the IP followed by domain of your project. With current example configuration it would be:
# /etc/hosts
# ...
192.168.10.222 www.february.dev
# ...
You might also want to change how much RAM virtual machine has (memory
property), how many CPUs it uses (cpus
property), or the name of the project (hostname
and name
properties).
# Homestead.yaml
# ...
memory: 2048
cpus: 1
hostname: february
name: february
# ...
The default Vagrant configuration is good enough, but I personally like to make a few changes that improve the CLI experience inside a VM.
One change I like to do is use my own .bash_aliases
file. This functionality is available by default, but I like to change the location of the file. Modify the line which has aliasesPath
variable:
# Vagrantfile
# ...
aliasesPath = ".provision/.bash_aliases"
# ...
You can make your own aliases file, here is the example of a good starting point:
# .provision/.bash_aliases
# Easier navigation
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
# Shortcuts
alias g="git"
alias h="history"
# Testing tools
alias fixtures="sf hautelook:fixtures:load --purge-with-truncate"
alias behat="vendor/bin/behat --no-snippets"
alias bjs="vendor/bin/behat --no-snippets --tags=javascript"
alias bnojs="vendor/bin/behat --no-snippets --tags=~javascript"
alias phpspec="vendor/bin/phpspec"
alias psp="vendor/bin/phpspec"
alias phpunit="vendor/bin/phpunit"
alias selenium="DISPLAY=:1 xvfb-run java -jar /var/selenium/selenium-server-standalone-2.53.1.jar"
# Symfony console
alias prod="bin/console --env=prod"
alias dev="bin/console --env=dev"
alias sf="bin/console"
# Edit hosts file
alias hosts='sudo $EDITOR /etc/hosts'
Now the following code is not aliases, but if you want to configure your development box further (in an easy way), add the following code at the end of .provision/.bash_aliases
file:
### Not aliases, but extra provisioning
if [ -f ~/.bash_extra ]; then
. ~/.bash_extra
fi
In the .provision/.bash_extra
you can put any commands you want. For example to automatically move to your project directory you could add a cd
command:
# .provision/.bash_extra
cd february
Depending on your environment you might need multiple files what configure how your environment behaves. Expand Vagrantfile
to provision development environment with additional files:
# Vagrantfile
# ...
files = {
'.provision/.inputrc' => '~/.inputrc',
'.provision/.bash_extra' => '~/.bash_extra',
'.provision/.phpspec.yml' => '~/.phpspec.yml',
}
# ...
files.each do |source, destination|
if File.exist? source then
config.vm.provision "file", source: source, destination: destination
end
end
# ...
The hash files
key contains the source file, and value
of it contains the destination of the file. Just modify it according to your needs.
Here is the .inputrc
file I like to use (it modifies the behavior of your terminal, making it easier to work with it):
# .provision/.inputrc
# Make Tab autocomplete regardless of filename case
set completion-ignore-case on
# List all matches in case multiple possible completions are possible
set show-all-if-ambiguous on
# Immediately add a trailing slash when autocompleting symlinks to directories
set mark-symlinked-directories on
# Use the text that has already been typed as the prefix for searching through
# commands (i.e. more intelligent Up/Down behavior)
"\e[B": history-search-forward
"\e[A": history-search-backward
Now that you have all the configurations ready you can start your virtual machine. It might take some time if this is the first time running it:
vagrant up
After VM finishes provisioning you should see your web application by opening an application URL (www.february.dev
in this case) in the browser. If it's a Symfony project, and you try opening a development version it will inform you that you have no access to it. Fix it by removing the code which checks that the script is being accessed from local environment. Your deployment process to production should remove app_dev.php
file to make sure no one has access to development version.
You can execute commands in your VM, for example to run the test suite. Connect to your VM by running:
vagrant ssh
If you're having issues connecting you might need to clear out your ~/.ssh/known_hosts
file.
To finish your set up copy Homestead.yaml
file to Homestead.yaml.dist
. If other people work on your project they will want to have the same configuration, but there are few options which will change for each of them. The one which will be different for everyone would be folders.map
option. In the Homestead.yaml.dist
file replace that option with an empty string:
# Homestead.yaml.dist
# ...
folders:
- map: "" # directory of the project on host machine, `pwd` command in bash
# ...
# ...
Commit Homestead.yaml.dist
file to repository, and add Homestead.yaml
file to .gitignore
file to avoid committing it accidentally. Anyone who wants to get the same environment after cloning the repository should just copy Homestead.yaml.dist
file as Homestead.yaml
file, and enter the directory of the project (most of the time it will be output of pwd
command).
If you're running a Symfony application, and need to check it with the production configuration you will need to comment out (remove) internal;
line from your NGINX configuration. The NGINX configuration can be found at /etc/nginx/sites-available
directory. The configuration file is the map
value of your site option (from Homestead.yaml
, in this case it would be www.february.dev
). Then restart NGINX service, and clear your Symfony cache:
sudo service nginx restart
sf c:c --env=prod
Now you should have an easy to reproduce development environment.