├── .gitignore
├── registration.php
├── composer.json
├── etc
├── module.xml
├── config.xml
├── di.xml
└── adminhtml
│ └── system.xml
├── LICENSE
├── Config
└── Flag.php
├── Model
└── ChangeDetector.php
├── Plugin
└── DbStatusValidator.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
15 |
16 |
17 |
18 | 0
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Zepgram - Benjamin Calef
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
15 |
16 |
17 | Zepgram\ZeroDowntimeDeployment\Model\ChangeDetector
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Magento\Framework\App\Cache\Type\Config
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
15 |
16 |
17 |
19 |
20 |
22 |
23 | This option enable zero downtime on developer mode and default mode instead of having it enabled only on production mode.
24 | Magento\Config\Model\Config\Source\Yesno
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Config/Flag.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 2021 Zepgram Copyright (c) (https://github.com/zepgram)
11 | * @license MIT License
12 | */
13 |
14 | declare(strict_types=1);
15 |
16 | namespace Zepgram\ZeroDowntimeDeployment\Config;
17 |
18 | use Magento\Framework\App\Config\ScopeConfigInterface;
19 | use Magento\Framework\App\State;
20 |
21 | class Flag
22 | {
23 | /**
24 | * @var string
25 | */
26 | public const ZERO_DOWNTIME_IS_ALWAYS_ENABLED = 'dev/zero_downtime_deployment/is_always_enabled';
27 |
28 | /**
29 | * @var ScopeConfigInterface
30 | */
31 | private $scopeConfig;
32 |
33 | /**
34 | * @var State
35 | */
36 | private $state;
37 |
38 | /**
39 | * @var bool
40 | */
41 | private $flagRegistry;
42 |
43 | /**
44 | * Config constructor.
45 | *
46 | * @param ScopeConfigInterface $scopeConfig
47 | */
48 | public function __construct(
49 | ScopeConfigInterface $scopeConfig,
50 | State $state
51 | ) {
52 | $this->scopeConfig = $scopeConfig;
53 | $this->state = $state;
54 | }
55 |
56 | /**
57 | * Is Zero Downtime Enabled
58 | *
59 | * @return bool
60 | */
61 | public function isZeroDowntimeEnabled()
62 | {
63 | if ($this->flagRegistry === null) {
64 | $this->flagRegistry = $this->scopeConfig->isSetFlag(self::ZERO_DOWNTIME_IS_ALWAYS_ENABLED)
65 | || $this->state->getMode() === State::MODE_PRODUCTION;
66 | }
67 |
68 | return $this->flagRegistry;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Model/ChangeDetector.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 2020 Zepgram Copyright (c) (https://github.com/zepgram)
11 | * @license MIT License
12 | */
13 |
14 | declare(strict_types=1);
15 |
16 | namespace Zepgram\ZeroDowntimeDeployment\Model;
17 |
18 | use Magento\Deploy\Model\DeploymentConfig\ChangeDetector as MagentoChangeDetector;
19 | use Magento\Deploy\Model\DeploymentConfig\DataCollector;
20 | use Magento\Deploy\Model\DeploymentConfig\Hash;
21 | use Magento\Deploy\Model\DeploymentConfig\Hash\Generator as HashGenerator;
22 | use Zepgram\ZeroDowntimeDeployment\Config\Flag;
23 |
24 | /**
25 | * Class ChangeDetector
26 | * Disable change detection in configuration.
27 | */
28 | class ChangeDetector extends MagentoChangeDetector
29 | {
30 | /**
31 | * @var Flag
32 | */
33 | private $flag;
34 |
35 | /**
36 | * ChangeDetector constructor.
37 | * @param Hash $configHash
38 | * @param HashGenerator $hashGenerator
39 | * @param DataCollector $dataConfigCollector
40 | * @param Flag $flag
41 | */
42 | public function __construct(
43 | Hash $configHash,
44 | HashGenerator $hashGenerator,
45 | DataCollector $dataConfigCollector,
46 | Flag $flag
47 | ) {
48 | $this->flag = $flag;
49 | parent::__construct($configHash, $hashGenerator, $dataConfigCollector);
50 | }
51 |
52 | /**
53 | * @param null $sectionName
54 | * @return bool
55 | */
56 | public function hasChanges($sectionName = null)
57 | {
58 | if ($this->flag->isZeroDowntimeEnabled()) {
59 | return false;
60 | }
61 |
62 | return parent::hasChanges($sectionName);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Plugin/DbStatusValidator.php:
--------------------------------------------------------------------------------
1 |
10 | * @copyright 2020 Zepgram Copyright (c) (https://github.com/zepgram)
11 | * @license MIT License
12 | */
13 |
14 | declare(strict_types=1);
15 |
16 | namespace Zepgram\ZeroDowntimeDeployment\Plugin;
17 |
18 | use Magento\Framework\App\FrontController;
19 | use Magento\Framework\App\RequestInterface;
20 | use Magento\Framework\Cache\FrontendInterface as FrontendCacheInterface;
21 | use Magento\Framework\Module\Plugin\DbStatusValidator as MagentoDbStatusValidator;
22 | use Zepgram\ZeroDowntimeDeployment\Config\Flag;
23 |
24 | /**
25 | * Class DbStatusValidator
26 | * Disable change detection in module version.
27 | */
28 | class DbStatusValidator
29 | {
30 | /**
31 | * @var FrontendCacheInterface
32 | */
33 | private $cache;
34 |
35 | /**
36 | * @var Flag
37 | */
38 | private $flag;
39 |
40 | /**
41 | * DbStatusValidator constructor.
42 | * @param FrontendCacheInterface $cache
43 | * @param Flag $flag
44 | */
45 | public function __construct(
46 | FrontendCacheInterface $cache,
47 | Flag $flag
48 | ) {
49 | $this->cache = $cache;
50 | $this->flag = $flag;
51 | }
52 |
53 | /**
54 | * @param MagentoDbStatusValidator $subject
55 | * @param FrontController $frontController
56 | * @param RequestInterface $request
57 | */
58 | public function beforeBeforeDispatch(
59 | MagentoDbStatusValidator $subject,
60 | FrontController $frontController,
61 | RequestInterface $request
62 | ) {
63 | if ($this->flag->isZeroDowntimeEnabled()) {
64 | $this->cache->save('true', 'db_is_up_to_date');
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Zero Downtime Deployment #
2 |
3 | ## Magento 2.4.4 - @deprecated
4 |
5 | On version 2.4.4, Magento is able to handle blue/green deployment, making this module no more required.
6 | To enable blue/green deployment you can add the deployment config `deployment/blue_green/enabled` in file app/etc/env.php:
7 | ```php
8 | 'deployment' => [
9 | 'blue_green' => [
10 | 'enabled' => true
11 | ]
12 | ]
13 | ```
14 |
15 | magento/framework/Module/Plugin/DbStatusValidator.php
16 | 
17 | magento/module-deploy/Model/Plugin/ConfigChangeDetector.php
18 | 
19 |
20 | Related commit is here: https://github.com/magento/magento2/commit/c241e11adf59baeca9d9e66cdbd726e4b0b88b21
21 |
22 | ⚠ Consequently, this module is now deprecated.
23 |
24 | ## Purpose
25 |
26 | Disable native change detection from Magento2 to allow Zero Downtime Deployment (ZDD).
27 |
28 | Normal behavior:
29 | 
30 |
31 | With this module installed:
32 | 
33 |
34 | ## Installation
35 | ```
36 | composer require zepgram/module-zero-downtime-deployment
37 | bin/magento module:enable Zepgram_ZeroDowntimeDeployment
38 | bin/magento setup:upgrade
39 | ```
40 |
41 | ## Configuration
42 |
43 | By default, Zero Downtime is enabled on production mode and disabled on Magento's developer and default modes.
44 | However, you can enable it for those modes from configuration path: `dev/zero_downtime_deployment/is_always_enabled`
45 | 
46 | > This section is only visible on developer mode from back-office
47 |
48 | For example, it can be useful to display errors when you roll-back your code while your database is ahead.
49 |
50 | ## Server
51 |
52 | ZDD enables you to deploy your website without any downtime.
53 | However, this module contains only necessary changes to make it possible on Magento2.
54 |
55 | To be able to perform a complete ZDD you'll need a
56 | blue/green deployment strategy.
57 | Which depends on your hosting provider.
58 |
59 | For example:
60 | - AWS: https://aws.amazon.com/fr/quickstart/architecture/blue-green-deployment/
61 | - Kubernetes: https://kubernetes.io/blog/2018/04/30/zero-downtime-deployment-kubernetes-jenkins/
62 |
63 | The mainly steps to reach the ZDD with Magento2:
64 | 1. Start the deployment: green pods are the old one, for now they must stay active while creating blue pods.
65 | 1. You must set your blue pods to a dedicated redis database and keep the green pods on their own redis db (avoiding cache corrupting).
66 | 1. Run `bin/magento setup:upgrade --keep-generated` to upgrade your database.
67 | 1. Upgrading is done: now green pods must be killed and replaced by blue pods based on health check statement.
68 |
69 | You can find a lot of articles detailling the procedure:
70 | - https://inviqa.com/blog/how-achieve-zero-downtime-deployments-magento-2
71 | - https://elogic.co/blog/how-to-achieve-zero-downtime-deployment-with-magento
72 |
--------------------------------------------------------------------------------