8

Currently we commit composer.lock to the repository and then run composer install --no-dev on the production server. I don't think this is the best way to do it because it takes a few minutes for composer to generate all the files and it is risky.

I wonder if it is better to commit to the repo all files needed for running in production mode.

How do others manage the deployment process with magento 2?

  • Why is it risky? It only needs to be done once per install/set up, and once composer has downloaded a package it's cached. – user3668514 Feb 18 '16 at 22:30
  • maybe I'm missing something but if you don't have the vendor folder in the repository how would you install new modules without running composer install on production? letscodejavascript.com/v3/blog/2014/03/the_npm_debacle – Claudiu Creanga Feb 22 '16 at 14:08
  • The point is to run composer install. Have you looked into a git hook to automate the process? – user3668514 Feb 23 '16 at 15:17
  • @user3668514 what if, when you run composer install on production, some remote packages are down, like it happened with npm? – Claudiu Creanga Feb 23 '16 at 15:56
  • how often does that happen? Magento2 now comes with a .gitignore which explicitly ignores /vendor amongst others. As this is the new 'Magento way', I'm following it to ensure other developers can work on the project without issue – user3668514 Feb 24 '16 at 10:08
5

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 :)

  • We've also started committing app/etc/config.php. This is by default ignored by Magento 2's .gitignore, but by committing this enabling and disabling is done during development and that decision is then committed and can be propagated and tested via CI. – Robert Egginton Jun 8 '16 at 8:53
  • You seriously turn your website offline? That is not an option for us. Our company is actually making money – TheBlackBenzKid Aug 3 '16 at 4:41
  • At present, yes we put sites offline briefly as we are not 100% certain that users would not see a partially operative site. With our greater experience of M1, we know with a high degree of certainty what changes can go live without taking the site down. Not so with M2 yet. – Robert Egginton Aug 11 '16 at 11:00
  • Up-voted. However, like @TheBlackBenzKid, I'd like to see something that doesn't take your website offline, especially since DI compilation takes a bit of time. I think understanding what DI compilation actually does is key - it would be great if that step could be done in the release-candidate folder. Any progress in the meantime since you've posted this @Robert? – Erfan Dec 1 '16 at 8:27
  • 1
    Interesting edit @RobertEgginton - I am currently exploring this and have followed your posts and discussions. I share the reservations about using composer at deploy time and potential unavilability of third-party repos, although I assume this is less of a concern with packagist repos. Committing ./vendor seems less than ideal too but at least it gives you a complete release that can be deployed independent of 3rd party repos. Have you tried Capistrano Magento2 extension? This uses composer install but I like the cap workflow github.com/davidalger/capistrano-magento2 – BlueC Jan 25 '17 at 9:32
3

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.

  • thanks for the input. besides changing the env.php what are other changes that you would want to make? – Claudiu Creanga Feb 17 '16 at 15:22
  • That all depends on your own server and project setup i guess. For the dev & staging branches, we also delete the .htaccess and copy our own .htaccess & htpassword files into the directory, we make sure bin/magento is executable just as a precaution prior to running cli commands on it, which we make sure we run as the magento file owner (deployment user is root) and we symlink the media folder into the pub folder. Of course you could add anything else as well which you prefer to do when deploying rather than prior. – tecjam Feb 17 '16 at 15:35
  • Committing files in /vendor is generally advised against as it defeats the objective of a component manager. See composer documentation. – user3668514 Feb 18 '16 at 22:30
  • That much is clear. So how do you manage your deployment then? – tecjam Feb 19 '16 at 9:28
  • 1
    Careful @user3668514 - I think you mean composer install. It's easy to accidentally run update and actually modify components rather than install them. – Robert Egginton Mar 18 '16 at 9:58
2

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.

1

I'm also looking into this, the approach I have taken thus far is:

Bootstrapping the server:

  1. Setup the project with composer --create-project ... --no-dev into a src folder (though I still see a lot of dev cruft coming through)
  2. Setup app, Compile static files, upgrade db etc.
  3. Set all correct permissions

Which will give me a stock, running store from my src directory (but my webroot is not pointing there)

Then my deployment process:

  1. Make a new release folder
  2. rsync the src files into my release (excluding the cruft)
  3. deploy and unpack my customisations over the top (a handful of theme files, and modules)
  4. install any third party magento modules through magento connect
  5. point my hosts webroot to my new release (with a symlink)
  6. gracefully reload my webserver

This allows me to maintain Magento core code separate from my own, use composer to keep it up to date.. and I don't need to ship 39,102!!! files with each deploy, or run composer commands at deploy time..

...Keen to hear of other approaches or for best practice on this, and id also love to know what files are actually required for production and which are dev.. so I can keep my webroot clean.

Once I'm finished, ill have an ansible playbook and some Fabric commands to orchestrate configuration and deployment, which I'm happy to share.

Hope that helps

  • I'd love to see the playbooks, and scripts. – J. M. Becker Dec 16 '18 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.