Magento 2 Tutorials

Installing Magento 2 with Composer

magento 2 and composer

Today we are hosting Tim Bezhashvyly. Not for an interview, but as guest author. He is sharing his personal experience on setting up Magento 2 with Composer and nginx. Join him, as he walks us through the process.

Introduction

Installing Magento with composer was my dream for literally years. I first got this idea when we built a Magento Composer Installer at the Magento Hackathon in Munich back in October 2012. However, for a number of reasons it is not possible to install Magento 1.X with composer completely.

Good news arrived when the Magento 2.X core team added the composer.json file to the GitHub repository. It goes without notice that I was intrigued to try and install Magento 2 using composer. Here, I will describe the process of setting up a new project with Magento 2.X as a composer module.

Let’s get started

Assuming you already have composer installed on your system, let’s initiate a blank project with the composer -n init command. This will give us a composer.json bootstrap file to work with. Secretly, Magento 2 is already available via packagist, but because it is still in its early stages, for now it’s a better idea to directly attach it to the Github repository:

{
"require": {
"magento/community-edition": "*@dev"
},
"repositories": [
{
"packagist": false
},
{
"type": "vcs",
"url": "https://github.com/magento/magento2.git"
}
]
}

This is all we need. Now let’s install Magento with the composer install –no-dev command. This will download Magento 2 to the vendor directory. Now what?

Magento 2 has a pub directory which contains files supposed to be exposed to the web. You can just copy them all to your web root but there is room for experimentation. I always try to add as little number of files to my project as necessary, so my initial idea was to symlink all of them except those which have to be modified.

In the project root, which only contains the vendor directory, composer.json and composer.lock files, the public directory is added and configured as a web root. At this point, it’s a matter of analyzing which files of Magento’s pub directory have to be copied and which can be symlinked. Here is the file listing:

errors/
media/
opt/
static/
cron.php
get.php
index.php
static.php

Copying the media directory is obvious. At this stage, I decided to symlink the opt and errors directories as I was not yet planning to do any modifications there. At the moment of writing, the pub/index.php file was broken so I had to copy it to my public directory and fix the issues. The remaining .php files, which are cron.php, get.php and static.php can be safely symlinked.

/path/to/my/project/public$ ln -s ../vendor/magento/community-edition/pub/opt/ opt
/path/to/my/project/public$ ln -s ../vendor/magento/community-edition/pub/errors/ errors
/path/to/my/project/public$ ln -s ../vendor/magento/community-edition/pub/cron.php cron.php
/path/to/my/project/public$ ln -s ../vendor/magento/community-edition/pub/get.php get.php
/path/to/my/project/public$ ln -s ../vendor/magento/community-edition/pub/static.php static.php

Because index.php has been moved, the bootstrap path inside it has to be modified from

require __DIR__ . '/../app/bootstrap.php';

to

require __DIR__ . '/../vendor/magento/community-edition/app/bootstrap.php';

The only remaining directory in pub is called static. This directory only contains a .htaccess file which redirects all static files requests to static.php. Theoretically, this directory can be symlinked too, but as long as my server runs nginx, the .htaccess file has no purpose. Ignoring this directory, the following rewrite-rule was added to the nginx configuration file of my host:

location /static {
rewrite ^/static/(.*)$ /static.php?resource=$1? last;
}

The complete configuration file looks like this:

server {
listen 80;

server_name hostname.tld;
root /path/to/my/project/public;
index index.php;

location /static {
rewrite ^/static/(.*)$ /static.php?resource=$1? last;
}

location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}

location ~ \.php$ {
try_files $uri =404;
expires off;
fastcgi_read_timeout 900s;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;

## Magento 2 Developer mode
fastcgi_param MAGE_MODE "developer";
}
}

Note that there is also a .htaccess file in the pub directory. The rule-sets in it are optional and transferring them to nginx configuration is outside the scope of this tutorial. Basically everything will work without them.

Finally, the contents of the .gitignore file are compiled which is of course a matter of preferences; there are some holy wars whether to include the vendor directory and/or composer.lock into the repository. Here is the list of files I choose to ignore:

/vendor/
/public/cron.php
/public/get.php
/public/static.php
/public/errors
/public/media/
/public/opt

Final words

And that’s all we need. Of course, this article is far from being called a guide, more like field notes. Hopefully it will be helpful for anyone getting started with using Magento 2.X with composer.

Editor’s note: Alan Kent, technical staff at Magento, notes that Magento 2 Composer integration is still under active development and might change in the future.

UPDATE

  • pub/index.php was fixed in 2.0.0.0-dev82 commit so now it can be also safely symlinked unless you want to modify something in the entry point.
  • Magento 2 is not on packagist.org so the entire “repositories” node of composer.json can be dropped.

Subscribe Newsletter

Subscribe to get latest Magento news

40% Off for 4 Months on Magento Hosting + 30 Free Migration