Deployment concepts starting from OXID eShop 6.2.0

The module system is one of the core features of the OXID eShop. Modules allow fast customization of nearly every aspect of the shop in a reusable manner. So it is not rare that actual shops have dozens of modules in them. Prior to the changes in the module system activating all these modules was a tiresome business: Each module had to be configured and activated manually in the shop backend. And this for every subshop in a multishop installation.

Default file structure for two shops without environment specific adjustments
Default file structure for two shops without environment specific adjustments

To make this cumbersome task of deploying a shop easier, the configuration of the modules has been moved out into yaml files that reside in the var/configuration/shops directory of the installation. For every shop there is a yaml file named <shopid>.yaml. This makes it easy to copy the information around and activate it on different systems, for example the CI, the testing or staging systems and finally the productive system(s).


These configuration files are the single point of truth for module configuration of a shop: The stuff in the database or the cache directory is derived from these files. Also all information from the metadata.php files of the modules will be copied here. The reason for this is: Eventually the metadata.php files will vanish in later version of the module system; currently we stick to well known system, but on installation the contents are copied immediately to the yaml files and from then on the metadata.php is ignored. In a later version of the module system an alternative for the metadata.php will be introduced – probably also a yaml file, but the exact mechanism is not yet determined.

Our recommendation is to put the var/configuration/shops directory under source control and deploy it with the shop: Just run composer install and then perform the following command of the oxid-console to have all modules up and ready:

vendor/bin/oe-console oe:module:apply-configuration

If you can’t run composer on a system due to security or other reasons, just prepare the installation by running composer install, copy it over to the system and run the console command.

Now the obvious problem is, that not every system has exactly the same configuration. URLs or passwords for external systems will likely differ from a staging to a productive system. Therefore there is the concept of an environment. You must use a directory named var/configuration/environment where you can keep files for every environment / shop combination, for example you prepare the files testing-1.yaml or productive-3.yaml. These should not contain a complete configuration, but only the values, that differ from one environment to another environment. When the shop reads the configuration, it first reads the general configuration and then applies the changes from the environment configuration.

Custom signature value for shop 1 for the staging and production system
Custom signature value for shop 1 for the staging and production system

Copied and renamed e.g. production-1.yaml to 1.yaml, will be considered as long as no changes are done in the module section of the admin area
Copied and renamed e.g. production-1.yaml to 1.yaml, will be considered as long as no changes are done in the module section of the admin area

These files should also be under version control and you should deploy them to the server. Before applying the configuration via console, you just rename the file for a certain environment to <shopid>.yaml (for example productive-3.yaml to 3.yaml in the productive environment). This way you keep the whole shop configuration for different environments in version control. And it does not make any sense to create an environment for development. During development, when you install / deinstall modules frequently and change their values via the backend, everything goes to the normal configuration file, an environment file would be pointless due to a mechanism that we will describe below. So create environment files only for hosts where you intend to use some deployment mechanism.

And you should notice, that the file names like testing-1.yaml are completely arbitrary. They are ignored by the system. The names are just to remind you, which alternative options are for which system. It is up to your deployment system, to select the correct file and rename it that the system applies the contents to the configuration.

So far, so good. But there is actually one drawback of this approach: If you configure the modules of a live system via the graphical shop backend, it gets complicated. Where should these manual changes go? In case of an active module, obviously immediately into the database; but as we have written above, this is not the single source of truth. It should be possible to recreate all the settings in the database from the configuration files. So manual changes in the backend must also go to the configuration files.

But which one? The general configuration file or the environment file? What actually happens is that the environment file is merged into the general configuration (not only in memory, but physically on disk) and the manual changes are applied on top. The environment file is now renamed with the .bak suffix and not used anymore. This behavior might appear strange, but there is a reason why we chose this strategy. Let’s get back to the question, where to put the changes, the general or the environment file. This question is by no means trivial. Regardless which file we choose: If a new deployment is executed, both files will be overwritten and changes are lost, if nobody has put the manually applied changes also to the sources. You even can’t check this on deployment. When the files in the deployment package differ from those on the host, this might be completely valid, because differences are to be expected when a new version is deployed. So the merging and renaming of the environment file is some sort of a marker, that someone has manually changed the configuration and that you should not blindly overwrite the configuration files from your sources. Your deployment script should warn you and urge you to check, what changes were made during run time on the target host.

Manual changes for module were done in admin area, 1.yaml.bak exists!
Manual changes for module were done in admin area, 1.yaml.bak exists!

So the recommended deployment works like this:

  • Put the general configuration for your shop into version control. You simply can configure the modules during development with the backend, everything goes to the general configuration files for the shops, that reside in var/configuration/shops.
  • Put different configuration options into environment files with different names for each environment into the directory var/configuration/environments, for example productive-1.shop (you will rename these files on the target host).
  • Before deployment check that there is no backup file for the environment on the target host. If there is, check what manual changes were applied and put them into your sources: Either to the general or the environment configuration, depending on where you think it should fit.
  • Deploy the shop and rename the environment files for the target host in the var/configuration/environment directory, for example productive-1.yaml to 1.yaml.
  • If you have composer on the target host, run composer there. Otherwise you need to do this before deployment on a build host.
  • Finally run the console command on the target host: vendor/bin/oe-console oe:module:apply-configuration.

That’s it!

And if you prefer to do it the old way by configuring the modules via the shop backend: Just don’t put the configuration files into version control and everything works as before.



Start the discussion at OXID forums