﻿#### 

This article describes the infrastructure changes that you have to apply when you want to deploy a rendering host app into the Sitecore Managed Cloud containers environment.

The following steps need to be done to add a node.js based rendering host to Sitecore Managed Cloud:

- Prepare the Docker files
- Push the images to the Azure Container Registry (ACR)
- Define the Rendering host configuration files
- Create Rendering Host configuration overlays
- Add the image in the Application repository
- Register a domain name
- Extend the Front Door configuration
- Configure Ingress
- Enable the Rendering Host component
- Apply the changes

#### Prepare the Docker files

Refer to the [Running node.js based rendering host in AKS](https://www.brimit.com/blog/running-node-js-based-rendering-host-in-aks)  guide for instructions on how to build corresponding custom images. 

#### Push the images to the Azure Container Registry (ACR)

To push the images to the ACR:

- In PowerShell, [execute the docker push command](https://docs.docker.com/engine/reference/commandline/push). You must push all images to the pre-provisioned ACR: *{infrastructure\_id}acr*. Also, you can configure your Azure DevOps to push images in Sitecore Managed Cloud ACR.

#### Define the Rendering host configuration files

To create the Rendering configuration files:

1. Navigate locally to the Application repository folder and create a folder with the following path:

***Roles\sitecore-{topology}\bases\components\rendering***

2. Create the following Rendering Host configuration files into the folder that you created earlier:

- *rendering.yaml*, with the following content:

| apiVersion: v1<br>
            kind: Service<br>
            metadata:<br>
              name: rendering<br>
            spec:<br>
              selector:<br>
                app: rendering<br>
              ports:<br>
              - protocol: TCP<br>
                port: 80<br>
            ---<br>
            apiVersion: apps/v1<br>
            kind: Deployment<br>
            metadata:<br>
              name: rendering<br>
              labels:<br>
                app: rendering<br>
            spec:<br>
              replicas: 1<br>
              selector:<br>
                matchLabels:<br>
                  app: rendering<br>
              template:<br>
                metadata:<br>
                  labels:<br>
                    app: rendering<br>
                spec:<br>
                  nodeSelector:<br>
                    kubernetes.io/os: windows<br>
                  containers:<br>
                  - name: demo-rendering<br>
                    image: demo-rendering<br>
                    ports:<br>
                    - containerPort: 80<br>
                    imagePullPolicy: Always<br>
                    env:<br>
                    - name: SITECORE\_API\_HOST<br>
                      value: http://cd<br>
                    - name: NEXTJS\_DIST\_DIR<br>
                      value: .next<br>
                    - name: PORT<br>
                      value: '80'<br>
                  imagePullSecrets:<br>
                  - name: regcred |
| --- |

- *kustomization.yaml*:

| apiVersion: kustomize.config.k8s.io/v1alpha1<br>
            kind: Component<br>
            <br>
            resources:<br>
            - rendering.yaml |
| --- |

#### Create Rendering Host configuration overlays

To integrate any module configuration with the Managed Cloud Containers environment, you must define an overlay layer on top of the base configuration added above. It will simplify the upgrade process in the future as well as it is a good kubernetes practice in general.

To define the overlays:

1. Create the *roles\sitecore-{topology}\overlays\components\rendering\cm.yaml* file with the following content: 

| ---<br>
            apiVersion: apps/v1<br>
            kind: Deployment<br>
            metadata:<br>
              name: cm<br>
            spec:<br>
              progressDeadlineSeconds: 3600<br>
              template:<br>
                spec:<br>
                  containers:<br>
                  - name: sitecore-xm1-cm<br>
                    image: "{{ docker\_images.sitecore.cm }}"<br>
                    env:<br>
                    - name: JSS\_DEMO\_DEPLOYMENT\_SECRET<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: jss-deployment-secret<br>
                          name: demo-common<br>
                    - name: SITECORE\_JSS\_EDITING\_SECRET<br>
                      valueFrom: <br>
                        secretKeyRef:<br>
                          key: jss-editing-secret<br>
                          name: demo-common<br>
                    - name: RENDERING\_HOST<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: rendering<br>
                          name: sitecore-hostname<br>
                    - name: RENDERING\_HOST\_PUBLIC\_URI<br>
                      value: "https://$(RENDERING\_HOST)" |
| --- |

2. Create the *roles\sitecore-{topology}\overlays\components\rendering\rendering.yaml* file with the following content:

| ---<br>
            apiVersion: apps/v1<br>
            kind: Deployment<br>
            metadata:<br>
              name: rendering<br>
            spec:<br>
              progressDeadlineSeconds: 3600<br>
              template:<br>
                spec:<br>
                  containers:<br>
                  - name: demo-rendering<br>
                    image: "{{ docker\_images.sitecore.rendering }}"<br>
                    env:<br>
                    - name: RENDERING\_HOST<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: rendering<br>
                          name: sitecore-hostname<br>
                    - name: SITECORE\_API\_KEY<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: demo-jss-api-key<br>
                          name: demo-common<br>
                    - name: JSS\_APP\_NAME<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: demo-jss-app-name<br>
                          name: demo-common<br>
                    - name: JSS\_EDITING\_SECRET<br>
                      valueFrom:<br>
                        secretKeyRef:<br>
                          key: jss-editing-secret<br>
                          name: demo-common<br>
                    - name: PUBLIC\_URL<br>
                      value: "https://$(RENDERING\_HOST)" |
| --- |

3.  Create the *roles\sitecore-{topology}\overlays\components\rendering\kustomization.yaml* file with the following content:

| ---<br>
            apiVersion: kustomize.config.k8s.io/v1beta1<br>
            kind: Kustomization<br>
            <br>
            resources:<br>
            - sitecore-roles.yaml<br>
            <br>
            patchesStrategicMerge:<br>
            - cm.yaml<br>
            <br>- rendering.yaml |
| --- |

4. To execute the overlays, navigate to *roles\sitecore-{topology}\tasks\main.yaml* and add the following:

| - name: Copy Sitecore roles configuration into Rendering Host overlay<br>
              template:<br>
                src: roles/sitecore-xm/templates/sitecore-roles.yaml<br>
                dest: roles/sitecore-xm/overlays/components/rendering/sitecore-roles.yaml<br>
            <br>
            - name: Run Kustomization for Rendering Host integration<br>
              shell: |<br>
                  kustomize build roles/sitecore-xm/overlays/components/rendering &gt; roles/sitecore-xm/templates/sitecore-roles.yaml |
| --- |

#### Add the image in the Application repository

Now you need to add the rendering host image to the Application repository.

To change the images in the Application repository navigate to *config/docker-images* and edit the *docker-images.json* file as follows:

- Add the rendering property, and point it to the rendering image that we have pushed to the ACR on earlier steps.

For Sitecore XM, docker-images.json will look like below:

| {<br>
                "sitecore": {<br>
                    "cm": "{infrastructure-id}.azurecr.io/xm1-cm:20221109.3-1.0.0",<br>
                    "cd": "{infrastructure-id}.azurecr.io/xm1-cd:20221109.3-1.0.0",<br>
                    "id": "{infrastructure-id}.azurecr.io/id6:20221109.3-1.0.0",<br>
                    "rendering": "{infrastructure-id}.azurecr.io/rendering:20221031.4",<br>
                    "mssql\_init": "{infrastructure-id}.azurecr.io/xm1-mssql-init:latest",<br>
                    "solr\_init": "{infrastructure-id}.azurecr.io/xm1-solr-init:latest"<br>
                },<br>
                "external": {<br>
                    "windowsservercore": "mcr.microsoft.com/powershell:lts-windowsservercore-1809"<br>
                }<br>
            } |
| --- |

#### Register a domain name

Because Rendering Host is a publicly available service, you must register a domain name for it.

To register a domain name:

1. Navigate to the portal where your DNS name is managed from.

2. Create an additional CNAME record for Rendering Host that points to Azure Front Door: *{infrastructure\_id}fdr.azurefd.net*,

where *infrastructureId* is your environment identifier that starts with mcc.

3. Navigate to the Azure Portal and create a secret within the Key Vault for the environment:

- Secret *name - sitecore-rendering-host-name*
- Secret value - the Rendering Host hostname that you created in the previous step.

#### Extend the Front Door configuration

You must extend the Front Door configuration with an additional public-facing service name.

To extend the Front Door configuration:

1. Navigate locally to the Application repository folder.

Open to edit the *frontdoor\backend-config.json* and define the rendering back-end config:

| {<br>
                    "name": "rendering-ingress",<br>
              "probe\_path": "/api/healthz",<br>
                    "backend\_list": [<br>
                        {<br>
                            "host\_header": "rendering.sitecore"<br>
                        }<br>
                      ]<br>
             } |
| --- |

2. Navigate to *frontdoor\main.tf* and in the locals section, add a new variable to "*sitecore\_rendering\_host\_name*“:

| sitecore\_rendering\_host\_name          = data.azurerm\_key\_vault\_secret.sitecore\_rendering\_host\_name.value |
| --- |

and

| sitecore\_rendering\_frontend\_endpoint\_name    = replace("${local.sitecore\_rendering\_host\_name}-endpoint", ".", "-") |
| --- |

3. Define the data resource to retrieve the Horizon host name from the Key Vault:

| data "azurerm\_key\_vault\_secret" "sitecore\_rendering\_host\_name" {<br>
            name         = "sitecore-rendering-host-name"<br>
            key\_vault\_id = data.azurerm\_key\_vault.this.id<br>
            } |
| --- |

4. In the "*azurerm\_frontdoor*" resource, define an additional *routing\_rule*:

| routing\_rule {<br>
                name               = "HTTPS-rendering"<br>
                accepted\_protocols = ["Https"]<br>
                patterns\_to\_match  = ["/\*"]<br>
                frontend\_endpoints = [local.sitecore\_rendering\_frontend\_endpoint\_name]<br>
                forwarding\_configuration {<br>
                  forwarding\_protocol = "MatchRequest"<br>
                  backend\_pool\_name   = "rendering-ingress"<br>
                }<br>
              } |
| --- |

5. In the "*azurerm\_frontdoor*" resource, define the *frontend\_endpoint*:

| frontend\_endpoint {<br>
                 name                                  = local.sitecore\_rendering\_frontend\_endpoint\_name<br>
                 host\_name                               = local.sitecore\_rendering\_host\_name<br>
                 web\_application\_firewall\_policy\_link\_id = azurerm\_frontdoor\_firewall\_policy.front.id<br>
            } |
| --- |

6. Adjust HttpToHttps so that it covers the HTTPS-rendering routing rule:

![Azure Front Door for Sitecore Managed Cloud](https://www.brimit.com/-/media/project/brimit/blog/2022/rh-in-aks/afd_rh_smc_2.png)

7. You must now apply the changes with a pull request to the Infrastructure repository before you can continue with the next steps.

8. Run the [FrontDoor pipeline](https://doc.sitecore.com/xp/en/developers/102/managed-cloud/the-managed-cloud-standard-pipelines.html) to apply the changes and wait until the pipeline is executed successfully.

Define the “*azurerm\_frontdoor\_custom\_https\_configuration*” resource:

| resource "azurerm\_frontdoor\_custom\_https\_configuration" "rendering\_host\_https\_configuration" {<br>
               frontend\_endpoint\_id              = azurerm\_frontdoor.this.frontend\_endpoints[local.sitecore\_rendering\_frontend\_endpoint\_name]<br>
               custom\_https\_provisioning\_enabled = true<br>
            <br>
               custom\_https\_configuration {<br>
                 certificate\_source                         = "AzureKeyVault"<br>
                 azure\_key\_vault\_certificate\_secret\_name    = data.azurerm\_key\_vault\_certificate.sitecore\_ingress\_certificate.name<br>
                 azure\_key\_vault\_certificate\_vault\_id       = data.azurerm\_key\_vault.this.id<br>
                 azure\_key\_vault\_certificate\_secret\_version = data.azurerm\_key\_vault\_certificate.sitecore\_ingress\_certificate.version<br>
               }<br>
            <br>
               depends\_on = [azurerm\_frontdoor.this]<br>
            } |
| --- |

9. Apply the changes to the environment with a pull request to the infrastructure repository.

10. Run the [FrontDoor pipeline](https://doc.sitecore.com/xp/en/developers/102/managed-cloud/the-managed-cloud-standard-pipelines.html) to apply the changes and wait until the pipeline is executed successfully.

#### Configure Ingress

Next you must define and apply the Ingress configuration and define the secrets.

To configure Ingress:

1. In the Application repository, navigate to the *roles\sitecore-{topology}\templates\* folder and create the *ingress-rendering.yaml* file with the following content:

| ---<br>
            kind: Service<br>
            apiVersion: v1<br>
            metadata:<br>
              name: rendering-external<br>
            spec:<br>
              type: ExternalName<br>
              externalName: rendering.{{ solution\_id }}.svc.cluster.local<br>
              ports:<br>
              - port: 80<br>
            ---<br>
            apiVersion: networking.k8s.io/v1<br>
            kind: Ingress<br>
            metadata:<br>
              name: sitecore-rendering-ingress<br>
              annotations:<br>
                kubernetes.io/ingress.class: "nginx"<br>
                nginx.ingress.kubernetes.io/force-ssl-redirect: "false"<br>
                nginx.ingress.kubernetes.io/rewrite-target: /<br>
                nginx.ingress.kubernetes.io/proxy-buffering: "on"<br>
                nginx.ingress.kubernetes.io/proxy-buffers-number: "4"<br>
                nginx.ingress.kubernetes.io/proxy-buffer-size: "256k"<br>
            spec:<br>
              rules:<br>
              - host: "rendering.sitecore"<br>
                http:<br>
                  paths:<br>
                  - path: /<br>
                    pathType: Prefix<br>
                    backend:<br>
                      service:<br>
                        name: rendering-external<br>
                        port:<br>
                          number: 80 |
| --- |

2. To define secrets, navigate to *roles\sitecore-{topology}\templates\secrets.yaml* and define the *sitecore-rendering-host-name* secret with *sitecore-secret-provider*. Extend the *sitecore-hostname* secret:

| - key: rendering<br>
                  objectName: sitecore-rendering-host-name |
| --- |

3. Add sitecore-rendering-host-name as a secret-provider parameter:

| - |<br>
                      objectName: sitecore-rendering-host-name<br>
                      objectType: secret |
| --- |

4. Add the new task to *roles\sitecore-{topology}\tasks\main.yaml*:

| - name: Install external Rendering ingress service<br>
              k8s:<br>
                apply: true<br>
                namespace: "nginx"<br>
                state: present<br>
                definition: "{{ lookup('template', 'ingress-rendering.yaml') }}"<br>
                validate:<br>
                  fail\_on\_error: yes |
| --- |

	

#### 
Enable the Rendering Host component

To enable the Horizon component:

- In the Application repository, navigate to the *roles\sitecore-{topology}\overlays\platform\kustomization.yaml* file and enable Rendering with the *components* element, pointing to the Rendering module configuration scripts folder.

| components:<br>
            - ../../bases/components/rendering |
| --- |

#### Apply the changes

To apply the changes:

- Apply the application changes to the environment with a pull request to the application repository.

###### More from author

[##### Deploy custom headless Sitecore solution in Sitecore XM Cloud
November 10, 2022](https://www.brimit.com/blog/deploy-custom-headless-sitecore-solution-in-sitecore-xm-cloud)[##### Running custom next.js editing host in Sitecore XM Cloud
September 29, 2022](https://www.brimit.com/blog/running-custom-next-js-editing-host-in-sitecore-xm-cloud)[##### Running node.js based rendering host in AKS
June 17, 2022](https://www.brimit.com/blog/running-node-js-based-rendering-host-in-aks)

###### Author

[!\[artsiom-photo\](https://www.brimit.com/-/jssmedia/feature/blogs/authors/artsiom-200.jpg?h=202&amp;iar=0&amp;w=200&amp;hash=41797D2540DF6EB6FDF558360F6F62B8)
Artsem Prashkovich
Sitecore MVP/ Solution Architect](https://www.brimit.com/blog/author?authors=Artsem%20Prashkovich)

###### More by category

[#Events](https://www.brimit.com/blog?categories=#Events)[#How-to](https://www.brimit.com/blog?categories=#How-to)[#News](https://www.brimit.com/blog?categories=#News)[#Guides](https://www.brimit.com/blog?categories=#Guides)

###### More by platform

[DXP](https://www.brimit.com/blog?platforms=DXP)[Sales and marketing automation](https://www.brimit.com/blog?platforms=Sales%20and%20marketing%20automation)[Application innovation](https://www.brimit.com/blog?platforms=Application%20innovation)

#### More on Sitecore

[!\[How Vercel Will Help You Save Effort When Deploying Sophisticated Sitecore Projects\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2024/vercel_cover-image.png)
#Guides#How-toDXPE-commerce
##### How Vercel Will Help You Save Effort When Deploying Sophisticated Sitecore Projects
Optimize and accelerate the development and deployment of complex multisite Sitecore projects.
Alexei Vershalovich on July 17, 2024](https://www.brimit.com/blog/how-vercel-will-help-you-save-effort-when-deploying-sophisticated-sitecore-projects)

[!\[Training Up Tomorrow's Sitecore MVPs: a Mentoring Success Story\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2023/sitecore-mentoring---cover-image.png)
#How-toDXP
##### Training Up Tomorrow's Sitecore MVPs: a Mentoring Success Story
How to participate in the Sitecore Mentor program and help younger colleagues jump-start a career in Sitecore development.
Sergey Baranov on October 2, 2023](https://www.brimit.com/blog/training-up-tomorrows-sitecore-mvps)

[!\[Going Headless. Part 2: When a Headless CMS Is Your Best Bet (if you have Sitecore)\](https://www.brimit.com/-/jssmedia/project/brimit/blog/2022/headless/adobestock_456986731.jpg)
#How-toDXPE-commerce
##### Going Headless. Part 2: When a Headless CMS Is Your Best Bet (if you have Sitecore)
Discover how a headless CMS can benefit organizations that use Sitecore.
Daniil Raschupkin, Palina Trokhautsava on September 15, 2022](https://www.brimit.com/blog/going-headless-part-2-when-a-headless-cms-is-your-best-bet-if-you-have-sitecore)

![](https://bat.bing.net/action/0?ti=187017043&amp;tm=gtm002&amp;Ver=2&amp;mid=26911449-942e-4d9d-94c0-75e4885bbcd8&amp;bo=2&amp;gtm_tag_source=1&amp;pi=0&amp;lg=en-US&amp;sw=800&amp;sh=600&amp;sc=24&amp;nwd=1&amp;tl=Running%20node.js%20based%20rendering%20host%20in%20Sitecore%20Managed%20Cloud&amp;kw=Kubernetes,AKS,JSS,Sitecore,Rendering,Cloud&amp;p=https%3A%2F%2Fwww.brimit.com%2Fblog%2Frunning-node-js-based-rendering-host-in-sitecore-managed-cloud&amp;r=&amp;lt=338&amp;evt=pageLoad&amp;sv=2&amp;asc=D&amp;cdb=AQAY&amp;rn=632164)