├── .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 | ![image](https://user-images.githubusercontent.com/16258478/161338149-52febed8-d9b9-4e95-ba9d-60b999627aa5.png) 17 | magento/module-deploy/Model/Plugin/ConfigChangeDetector.php 18 | ![image](https://user-images.githubusercontent.com/16258478/161338272-f72b6d73-3763-42d4-a684-1450a47290b8.png) 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 | ![zdd](https://user-images.githubusercontent.com/16258478/82318767-b361cd80-99d0-11ea-86f2-7b032ad29744.png) 30 | 31 | With this module installed:
32 | ![zdd_module](https://user-images.githubusercontent.com/16258478/82321492-32590500-99d5-11ea-9c84-53756715e8d7.png) 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 | ![418](https://user-images.githubusercontent.com/16258478/133935969-7b38f61f-67e2-486c-9dd6-a836688704d5.png) 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 | --------------------------------------------------------------------------------