Magento 2 deployment process

Agree 100% with claudiu-creanga on not committing vendor and also avoiding running composer install in production.

The way we have handled this is to have a live folder and a release-candidate folder. It is in the release-candidate folder that we run git pull commands and composer install --no-dev. Our process can be summed up like this:

  1. In release-candidate folder:

    • Check for unexpected changes
    • Update repo
    • Composer install
  2. Sync files to live site folder

  3. In live site folder:
    • Deploy static files
    • Enable maintenance mode
    • Enable modules
    • Run setup scripts
    • Compile DI
    • Clear cache
    • Disable maintenance mode
    • Update permissions

I've written a longer blog article giving the actual commands and reasoning behind this: https://www.c3media.co.uk/blog/c3-news/deploying-magento-2-production-environment/

UPDATE: We now copy the live database to a staging database and use this to run setup scripts, deploy static files and compile DI all offline. This can then be deployed to live including pub/static files and var. We still briefly take the site down if setup scripts are being run, but otherwise the site is left up. More details at https://www.c3media.co.uk/blog/c3-news/magento-2-deployment-without-downtime/

UPDATE: I've changed my mind about committing the vendor folder - by committing the folder you gain the ability to track the history of how these files change, see if you've accidentally changed anything, and most importantly you avoid having to run composer at deployment time. The latter is vital now that we are relying on external suppliers of repositories. What if one of them is not available? Suddenly you cannot deploy. The downsides are a larger repository, the risk of committing core hacks, and the knee-jerk distain of developers like me :)


So far we also commit the vendor folder, which of course adds a whole lot of files to your repo. (Be sure to remove any .git folders in the vendor composer files, as otherwise the folders content will not be committed - firegento for example). But symlinking the vendor folder does not work, editing the path in the vendor_path.php file also doesn't work and we havn't had time to look for a better solution so far.

We do not have a build server and we do not run composer on the server, we run and test all updates locally and commit them. This in turn triggers our deployment script.

Our deployment script replaces the env.php file, does a few custom things and then also triggers setup:upgrade and setup:static-content:deploy prior to switching the live link to the new folder.

The only folder we symlink is pub/media.


Finally we opted out for a service like deploybot (http://deploybot.com/). You can use capistrano which is free. Deploybot creates a docker container while the composer install is running and if the command is successful then it deploys the code, otherwise it will not deploy anything so your production environment will be safe.

I consider this the best approach because:

1) having the vendor folder in your git repo is not recommended by the composer guys for good reasons:

The general recommendation is no. The vendor directory (or wherever your dependencies are installed) should be added to .gitignore/svn:ignore/etc.

More info: https://getcomposer.org/doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md

2) Running composer install in production with no safety nets is risky, packages could be down (see npm), you could run into memory issues or whatever error could be happening while composer generates files and you will have to deal with a broken production environment.