magento / community-features

Magento Features Development is an Initiative to Allows Community Memebers Join to Development of Magento Features
46 stars 18 forks source link

[2.2.x] How to disable modules per environment? #126

Open jahvi opened 6 years ago

jahvi commented 6 years ago

As of 2.2 it is recommended to include the config.php file in version control as it provides common settings that are shared across environments. The problem is that sometimes you want to install extension only for development so if this is the case then you'll get an error if the module is included in the config.php file but not actually installed.

Preconditions

  1. Magento 2.2.1
  2. PHP 7.0

Steps to reproduce

  1. Install fresh version of Magento 2.2.1
  2. Install development only extension as a dev dependency, eg: composer require honl/magento2-templatehints --dev
  3. Run php bin/magento setup:upgrade, the config.php file gets updated with the new extension and everything works as expected.
  4. Mimic a "production" environment by deleting the vendor folder and running composer install --no-dev and deleting the Ho_Templatehints row in the setup_module table.
  5. Clear cache.

Expected result

  1. Website should load normally with extension disabled.

Actual result

  1. You get a Setup version for module 'Ho_Templatehints' is not specified error.

The error is to be expected because Magento is trying to load a module that hasn't been installed, I though I could only enable the module in the env.php file since this is environment specific but that didn't work.

renttek commented 6 years ago

I see 2 Options to implement this requirement:

  1. Add a modules key to env.php

2.Add an 'modules-{mode}' key in config.php, where mode is the run mode of magento (developer, production, default, ...)

Personally I'd prefer option 2, because you only have to look at 1 file to determine which modules are enabled/disabled in which environment/mode.

Another question is: should this be done in core?

jahvi commented 6 years ago

I though option 1 was already supported but it didn't work in my case, I tried manually adding the modules key to this file but they were not being picked up by Magento.

I personally prefer that option just because it's the way settings work now so it would make it consistent, but any fix or workaround would help. As it is now I have to install dev dependencies on the live environment which is not ideal.

orlangur commented 6 years ago

--dev in Composer should not be mixed with developer mode in Magento.

I believe you are supposed to have separate config.php for each environment if you need separate sets of modules. Generally, I don't think it's a good idea, better option is to disable unneeded modules in production (or make modules disactivate automatically in production mode).

jahvi commented 6 years ago

Generally, I don't think it's a good idea, better option is to disable unneeded modules in production (or make modules disactivate automatically in production mode)

@orlangur I agree, however how can we manage to do that if the config.php file is encouraged to keep under version control?

Are separate config.php files per environment supported now? I couldn't find anything about that in the docs.

orlangur commented 6 years ago

how can we manage to do that if the config.php file is encouraged to keep under version control?

Right, so we can have only 0 or 1 for each module which means disabled/enabled. Overlooked this.

Are separate config.php files per environment supported now?

I don't think so, just that you can do it a part of your custom deployment process (copy config.dev.php or config.prod.php to config.php).

jahvi commented 6 years ago

I don't think so, just that you can do it a part of your custom deployment process (copy config.dev.php or config.prod.php to config.php).

I see, that's a good workaround thanks for the recommendation.

ishakhsuvarov commented 6 years ago

@jahvi Looks like issue is solved, can we close the ticket now?

jahvi commented 6 years ago

Well there is a workaround, still would be nice if there was a built in way of dealing with this but this can be closed now.

peterjaap commented 6 years ago

It would be great to have a --env option on bin/magento module:disable (and enable) so we can do bin/magento module:enable Ho_Templatehints --env and that this would end up in app/etc/env.php instead of app/etc/config.php.

PR for this is easily made I guess. I'm adding the up for grabs label.

jahvi commented 6 years ago

@peterjaap Does this mean that if I manually add:

'modules' => [
    'Ho_Templatehints' => 0,
]

To my env.php file it will take precedence over the one in the config.php file, or will that also need to be part of the PR?

peterjaap commented 6 years ago

Yes that already works so your local env.php it will look like this;

$ head -n 10 app/etc/env.php
<?php
return array (
  'modules' => 
  array (
    'Ho_Templatehints' => 1
  ),
  'cache_types' => 
... etc
wujku commented 6 years ago

@peterjaap but after setup:upgrade modules from env.php goes to config.php.

peterjaap commented 6 years ago

@wujku then don't commit config.php to git in that case.

magento-engcom-team commented 5 years ago

Hi @engcom-backlog-tomash. Thank you for working on this issue. Looks like this issue is already verified and confirmed. But if your want to validate it one more time, please, go though the following instruction:

ghost commented 5 years ago

Thank you for reporting this issue. As I could understood from this thread something similar to bin/magento module:enable Ho_Templatehints --env <environment> is missing to satisfy some needs in development/deployment process.

Do not see any reasons against implementing this feature in Magento Core as we already have lot of tooling included, however it seem like the chances are low for this feature to be implemented by internal team. Let's move it to Community Features Request repository.

sdzhepa commented 5 years ago

Hello @jahvi

According to the comment above, this ticket is moved to feature-requests track

Thank you for collaboration and feedback

lewisvoncken commented 3 years ago

@peterjaap , @jahvi

What about this solution which is possible in Shopware?

<?php declare(strict_types=1);

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
    Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
    Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
    Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
    Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
    Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
    Enqueue\Bundle\EnqueueBundle::class => ['all' => true],
    Enqueue\MessengerAdapter\Bundle\EnqueueAdapterBundle::class => ['all' => true],
    Shopware\Core\Framework\Framework::class => ['all' => true],
    Shopware\Core\System\System::class => ['all' => true],
    Shopware\Core\Content\Content::class => ['all' => true],
    Shopware\Core\Checkout\Checkout::class => ['all' => true],
    Shopware\Core\Profiling\Profiling::class => ['dev' => true],
    Shopware\Administration\Administration::class => ['all' => true],
    Shopware\Docs\Docs::class => ['all' => true],
    Shopware\Storefront\Storefront::class => ['all' => true],
    Shopware\Elasticsearch\Elasticsearch::class => ['all' => true],
];
ProxiBlue commented 3 years ago

Ok, although this ticket has been moved to feature requests, but since i is still open, I will post my 2c and workaround.

I don't think so, just that you can do it a part of your custom deployment process (copy config.dev.php or config.prod.php to config.php).

First having separate config.php files like this becomes a bit of a nightmare, as you end up with out-of-sync base modules that are enabled/disabled, and it becomes a nightmare to manage.

The trick is to keep one config.php, version controlled. Then exclude env.php from version control Have separate environment based env.[ENV_TYPE].php config files. so env.dev.php, env.live.php and env.uat.php etc. These are version controlled. In your deploy pipeline, you copy the correct env.[ENV_TYPE].php file into place to env.php as part of the initial artifact build process. On your lcoal dev you can just use a symlink of env.dev.php -> env.php, so editing is simplified locally (and if magento injects stuff in) If you set this up properly, the pipeline name/variables can be used to pick up the correct file for that deploy, so you don't run into potentials for mismatched files. (so pipeline is named LIVE, it will copy env.live.php)

Now, in each environment based env.php file you can use:

'modules' => [
        'Magento_TwoFactorAuth' => 0|1
    ],

Depending on what the env needs (as an example the 2fa is not wanted locally, or on a fire walled UAT) The separate env.php files also allows you to set specific DB and cache options, as well as set each environments URL's as needed.

I have used this process fine for some time. The only issue is when you purposely lock something to env.php, but that is a lot easier to manage than config.php modules going out of sync, especially if you work on many branches with different modules installed on each, and merge them randomly into live/uat

onlinebizsoft commented 3 years ago

I think the best practice is following what Shopware is doing. Having different files make it hard for maintance.