Magento Cloud: Create a New Integration Environment

What if you need to create a new Integration environment in Magento Cloud? In this article, I will detail the process of creating a new Integration environment from the Staging branch.

You already noted that the Magento Cloud UI interface is very easy to use; making you feel confident that creating a new Integration Environment is just as performing simple “delete” and “branch from Staging” operations; however you will find out soon that this is not the case.

After deleting the Integration environment you will realize that there are no available options for creating a new branch from the Staging site. If this is your case, don’t panic. Magento Cloud CLI comes to the rescue.

For creating a new Integration Environment from Staging, just follow these steps:

  1. Clone or checkout to the latest Staging git repository

$ git checkout staging -f

  1. Create a new branch based on Staging, better to call it Integration for keeping the same naming convention

$ git checkout -b integration

  1. Push to Magento Cloud for creating the new environment. 

$ git push magento integration

  1. After this, the new environment will be displayed as a child of Master, however, we can change this environment parent by using the Magento Cloud CLI and editing its parent info like this:

$ magento cloud environment:info -e integration parent staging 

  1. By using the command above we are telling Magento Cloud that we want the Staging server to be the parent of our new Integration environment. After this, if you refresh the Magento Cloud Web you will see that Integration is correctly begin displayed as a direct child of Staging, meaning that you are able to continue using the integrated CI/CD provided by Magento Cloud. You just need to activate the new environment.

$ magento cloud environment:activate integration 

  1. Also the CLI will show the correct info as well:

Deploying PHP extensions to Magento Cloud

By design, Magento Cloud clouds provide an “out of the box” environment structure, containing all the libraries and settings necessary to run Magento, without needing to spend time in finding the correct configuration and specifications. However from time to time, due to technology changes, extra PHP extensions might be required to be installed.

The most common extensions required to be added are those related to security; just like new encryption algorithms that enhance the security of cloud environments. Also, there might be a chance that a new module has been added and requires one of these new PHP extensions. 

In this article, it is assumed that a new module was installed and require to use PHP Libsodium extension; and because the Libsodium extension doesn’t exist in the environment Magento might face exceptions, with errors similar like the following appearing in logs:

Since a Magento Cloud environment cannot be changed manually on CLI, the only accepted procedure is to add the library in the .magento.app.yml  file, included in every Magento Cloud environment.

Adding Libsodium is as simple as adding in the “extensions” section as follows:

# Enable extensions required by Magento 2

runtime:

    extensions:

        – redis

        – xsl

        – json

        – blackfire

        – newrelic

        – sodium

After pushing the changes into the environment and SSH into it, the new extension will be visible and fully configured.

Although Magento Cloud does not allow direct changes to the environment by CLI, it still provides a very flexible mechanism for customizing any environment by utilizing the embedded CI/CD, providing a robust flow for avoiding misconfigurations and human errors; and the same procedure is safe to be applied to any other PHP extensions required over the time.

Rerouting Magento Cloud Request to Another CMS

Magento Cloud, as the name suggests, runs on cloud. Means that, they already have all the network and infrastructure configured for you and they work great. You don’t need to worry about those things, and you as a Magento developer, can just focus on developing your site.

Since it runs on the “cloud”, then you may not have all the flexibility to customize your nginx, firewall, and other infrastructure aspects. There might be cases where you need to integrate some third party apps to your Magento. One example is you usually need to have a wordpress blog running under /blog of your Magento installation.

In order to do this on Magento Cloud, you need to utilize the Fastly module. Fastly comes by default with your Magento Cloud, so you don’t need to pay anything extra for that.

In order to route specific path to an external service, you need to do the following on your Magento admin:

  1. Enable Fastly CDN
  2. Enable Fastly Edge Modules
  3. Create Edge Dictionary
  4. Add new Fastly Backend Service
  5. Configure Other CMS / backend integration Edge Module

Magento cloud documentation and it’s Github has already covered most of the aspects I mentioned above. However, there are some details that haven’t been explained clearly for the Edge Dictionary. For example, if you want to route /blog to your wordpress site, then you will need to add a dictionary item with key blog and value 1. This is very important to highlight otherwise your custom route won’t work. Overall, to enable this function, you will only need less than 15 minutes to configure everything. But if you miss a step (like us!), then it might get you two days!

Fixing 502 Error on Magento Cloud

Fixing 502 Error on Magento Cloud

502 Bad Gateway error might be an error that could happen especially, in a particular Integration (Development) environment. This error could be very hard to analyze if after checking the Magento Cloud configuration and Internet speed, the Engineering team is still not able to determine the root cause of this error.  

This article is intended to briefly summarize the possible root cause of error 502 and the recommended solutions to mitigate it. 

Most of the time, and in some particular Magento Cloud Integration/Development  environments, error 502 is caused by the following reasons.

  1. Overloaded database.
  2. Too many cron jobs running simultaneously.

Overloaded database

Integration and other environments than Production and Staging, are supposed to be used for developing and/or testing, so a database trim might (products deletion mostly) might be necessary in order to have only a representative sample for developing/testing.

Too many cron jobs running simultaneously

Cron jobs might reduce memory performance in an environment that is not fully optimized to be used for production. So the best idea here would be to run them in  groups in order to avoid missed or pending jobs.

A database check would be necessary in advance for getting a clearer idea on the current cron jobs status. For example:

MariaDB [main]> select status, count(*) from cron_schedule group by status;

+———+———-+

| status  | count(*) |

+———+———-+

| error   |      535 |

| missed  |     5392 |

| pending |      574 |

| running |        1 |

| success |      852 |

+———+———-+

MariaDB [main]> select job_code, status, count(*) from cron_schedule where date(created_at) = CURDATE() and status = ‘missed’ group by job_code, status;

+———————————————–+——–+———-+

| job_code                                      | status | count(*) |

+———————————————–+——–+———-+

| catalog_event_status_checker                  | missed |      107 |

| catalog_product_frontend_actions_flush        | missed |        6 |

| catalog_product_outdated_price_values_cleanup | missed |        5 |

| consumers_runner                              | missed |       75 |

| indexer_reindex_all_invalid                   | missed |      130 |

| indexer_update_all_views                      | missed |      138 |

+———————————————–+——–+———-+

As seen in these examples, many cron jobs are not being executed, so splitting the cron jobs and running them in groups can be done by updating in .magento.app.yaml. This is to avoid serial execution and to further reduce memory consumption. An splitting example would be as follows:

First identify the current groups that can be utilized in the system:

[email protected]:~$ find . -name cron_groups.xml

./vendor/amasty/base/etc/cron_groups.xml

./vendor/magento/module-message-queue/etc/cron_groups.xml

./vendor/magento/module-staging/etc/cron_groups.xml

./vendor/mailchimp/mc-magento2/etc/cron_groups.xml

Based on the output above, the cron jobs can easily splitted into groups:

# Default Magento 2 cron jobs

default:

        spec: “*/10 * * * *”

        cmd: “php bin/magento cron:run –group=default”

    …

consumers:

        spec: “*/19 * * * *”

        cmd: “php bin/magento cron:run –group=consumers”

    staging:

        spec: “*/21 * * * *”

        cmd: “php bin/magento cron:run –group=staging”

The above suggestion is only for some particular Integration/Development environments.  How granulated the jobs group should be splitted is up to every scenario and environment.

In this particular example, after grouping the cron jobs, pushing the changes and clearing out the cron job tables, the changes will be reflected in the database.

MariaDB [main]> select status, count(*) from cron_schedule group by status;

BeforeAfter
+———+———-+| status  | count(*) |+———+———-+| error   |      535 || missed  |     5392 || pending |      574 || running |        1 || success |      852 |+———+———-+
+———+———-+| status  | count(*) |+———+———-+| error   |        0 || missed  |        0 || pending |        0 || running |       12 || success |      24 |+———+———-+

Note: The database info is accumulative over the time.

And finally, it is worth mentioning that this configuration is defined at the file app/etc/env.php, and each environment can have its own env.php with its own configuration.