Recent Posts


Using Magento 2 with Laravel Homestead


Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

For over a decade I’ve kept most my development work confined to the physical Macintosh OS X laptop I use every day, running server software using the OS X unix/bsd/darwin internals. I pick a stable version of PHP and install the php-osx package (previously the package), install MySQL via MySQL/Oracle’s OS X installer, use brew (previously ports) to install any unix packages I need, and compile the occasional thing from source as needed.

This stable set of software has served me well, and by side-stepping virtual machine/vagrant/version-managers it’s kept my code on the straight and narrow – i.e. applicable to generic PHP versions and not shutting people out who don’t have the liberty of choosing their hosting environment.

Magento 2 present a challenge to this, since I’d prefer to run PHP 5.6 for a while longer. Magento 2, however, is likely to see massive adoption with PHP 7 as the target platform. If you’re bleeding edge enough for Magento 2, you’re bleeding edge enough for PHP 7. PHP 7 code breaks from PHP 5.x in major ways. Ways that are good for the long term health of PHP, but ways that still aren’t well known. i.e. working in PHP 5.6 and deploying to PHP 7 isn’t going to be as smooth as working in PHP 5.6 and deploying to 5.4 or 5.5.

For the time being I’m allowing vagrant into my workflow, and I’m using the Laravel Homestead project to get a “modern” environment. Most of my non-Magento PHP freelance/consulting work is Laravel based, so it makes sense to use the development environment they’re promoting.

The homestead VM needed a little tweaking to work with Magento 2 – this is what worked for me on February 3, 2016. The longer you get away from this date, the more chance there is something might not work as it did below. Also, this isn’t a well tested setup so YMMV. Give a shout out on the Magento Stack Exchange if you’re having trouble.

Step 1 was installing Virtual Box and Vagrant. Virtual Box is a program for running virtual machines on a computer (i.e. run a fake computer using linux on your Mac/Window machine), and vagrant is a program for managing virtual machines via the command line.

Step 2 was installing Homestead. Homestead is a laravel project that provides you with a base virtual machine image with server software preinstalled, and some configuration/shell scripts that make setting up new website on that virtual machine much easier.

Step 3 – the homestead VM is setup to work with Laravel out of the box. Magento 2 uses a few extra PHP extensions that you’ll need to install. You can do that with the following commands. You need to run these after connecting to the virtual machine (vagrant ssh)

sudo apt-get install mcrypt php7.0-mcrypt
sudo apt-get install php7.0-intl
sudo apt-get install php7.0-xsl

The mcrypt php7.0-mcrypt line installs PHP functions used for encrypting and decrypting data. The php7.0-intl line installs PHP functions used for internationalization. The php7.0-xsl line installs PHP functions used for processing XML with XSL stylesheets.

Step 4 – I downloaded Magento 2’s source using the composer meta package, (again, after running vagrant ssh to ssh into the virtual machine). You’ll need to log into the Magento website and generate username/password keys to install this way, since you’re using Magento’s private composer repository.

composer create-project --repository-url= magento/project-community-edition

It’s important to do this from the VM, and not from your local computer. The vagrant VM has composer and everything else it needs installed already, you computer may not.

Also, I ran this from the ~/Code directory, if you’re keeping vagrant files somewhere else, run them from there.

Step 5 – After the composer command finished running (which will take a bit), I ran the Magento CLI command that installs the sample data modules

cd project-community-edition    
php bin/magento sampledata:deploy

The bin/magento command seems to be (at least partially) available prior to Magento being installed fully. The sampledata:deploy command will modify your composer.json file and add the sample data packages, and then run composer update. The sample data module contains migration scripts that will install Magento’s sample data for you when you install via the command line. They also should make the sample data option available for GUI based installations.

Step 6 – I created a MySQL database with the create database magento2_php7 command. You can log into mysql on the homestead box with the username/password homestead/secret.

Step 7 – I installed Magento using the bin/magento command with the following options. You’ll probably want to change many of these for your own install.

php bin/magento setup:install 
--admin-firstname Alan 
--admin-lastname Storm 
--admin-password passwordsinplaintextwooooooospringbreak 
--admin-user astorm 
--backend-frontname admin 
--db-name magento2_php7 
--db-password secret 
--db-user homestead 
--session-save files 
--use-rewrites 1 
--use-secure 0

Step 8 – Back on my real laptop, I added the following to my hosts file. This pointed the fake TLD domain (used when installing Magento 2 above) at my VM. The IP address comes from homestead magic

Again, this is the hosts file on your physical machine, not the virtual machine.

Step 9 – Back on my real laptop, I used homestead to setup an nginx site by editing the following file. The ~/Code business is Larvel’s default. I turned on nfs file sharing, and added the sites configuration that pointed at the folder where composer downloaded Magento 2

#File: ~/.homestead/Homestead.yaml    
    - map: ~/Code
      to: /home/vagrant/Code
      type: "nfs"

    - map:
      to: /home/vagrant/Code/project-community-edition/pub/    

Then, I needed to re-run vagrant provision for my homestead virtual machine so it picked up these changes and created an nginx configuration file (/etc/nginx/sites-available/

Step 10 – The nginx web server doesn’t read .htaccess files, which means you’ll need to configure nginx’s site configuration file in /etc/nginx/sites-available/ I used the following. I’m not sure if this will survive a homestead re-provision or not

upstream fastcgi_backend {
    server unix:/var/run/php/php7.0-fpm.sock;

server {
    set $MAGE_MODE developer;
    set $MAGE_ROOT /home/vagrant/Code/project-community-edition;
    include /home/vagrant/Code/project-community-edition/nginx.conf.sample;

    listen 80;
    listen 443 ssl;
    #root "/home/vagrant/Code/project-community-edition/pub/";

    index index.html index.htm index.php;

    #charset utf-8;

    #location / {
    #    try_files $uri $uri/ /index.php?$query_string;

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/ error;

    sendfile off;

    client_max_body_size 100m;

    location ~ .php$ {
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;

    location ~ /.ht {
        deny all;

    ssl_certificate     /etc/nginx/ssl/;
    ssl_certificate_key /etc/nginx/ssl/;


High level, this adds this code snippet.

set $MAGE_MODE developer;
set $MAGE_ROOT /home/vagrant/Code/project-community-edition;
include /home/vagrant/Code/project-community-edition/nginx.conf.sample;

Which sets two variables, and then includes the nginx configuration that ships with Magento 2.

It also defines this at the top

upstream fastcgi_backend {
    server unix:/var/run/php/php7.0-fpm.sock;

because the nginx.conf.sample file is looking for a fastcgi_backend definition.

Finally, we comment out the following in the stock homestead config

#root "/home/vagrant/Code/project-community-edition/pub/";

#charset utf-8;

#location / {
#    try_files $uri $uri/ /index.php?$query_string;

This avoids duplicates with the Magento provided configuration.

This got me a working install. Initial page hits were slow as all get out – my guess is cache generating and static asset generating consume resources in a way that’s not VM friendly. Subsequent page hits were OK.

All of this took the better part of a full workday. Pulling down a new VM over an average network, a few false starts until a figured out how homestead did things, and then a lot of glopping to get nginx working with Magento’s configuration.

Call me an old man, but I miss the days where web application development meant working with a stable set of tools across a variety of projects.

Copyright © Alan Storm 1975 – 2019 All Rights Reserved

Originally Posted: 4th February 2016