|
| 1 | +--- |
| 2 | +title: How to deploy applications in Azure Spring Cloud with a custom container image (Preview) |
| 3 | +description: How to deploy applications in Azure Spring Cloud with a custom container image |
| 4 | +author: karlerickson |
| 5 | +ms.author: xiangy |
| 6 | +ms.topic: how-to |
| 7 | +ms.service: spring-cloud |
| 8 | +ms.date: 4/28/2022 |
| 9 | +--- |
| 10 | + |
| 11 | +# Deploy an application with a custom container image (Preview) |
| 12 | + |
| 13 | +**This article applies to:** ✔️ Standard tier ✔️ Enterprise tier |
| 14 | + |
| 15 | +This article explains how to deploy Spring Boot applications in Azure Spring Cloud using a custom container image. Deploying an application with a custom container supports most features as when deploying a JAR application. Other Java and non-Java applications can also be deployed with the container image. |
| 16 | + |
| 17 | +## Prerequisites |
| 18 | + |
| 19 | +* A container image containing the application. |
| 20 | +* The image is pushed to an image registry. For more information, see [Azure Container Registry](/azure/container-instances/container-instances-tutorial-prepare-acr). |
| 21 | + |
| 22 | +> [!NOTE] |
| 23 | +> The web application must listen on port `1025` for Standard tier and on port `8080` for Enterprise tier. The way to change the port depends on the framework of the application. For example, specify `SERVER_PORT=1025` for Spring Boot applications or `ASPNETCORE_URLS=http://+:1025/` for ASP.Net Core applications. The probe can be disabled for applications that do not listen on any port. |
| 24 | +
|
| 25 | +## Deploy your application |
| 26 | + |
| 27 | +To deploy an application to a custom container image, use the following steps: |
| 28 | + |
| 29 | +# [Azure CLI](#tab/azure-cli) |
| 30 | + |
| 31 | +To deploy a container image, use one of the following commands: |
| 32 | + |
| 33 | +* To deploy a container image to the public Docker Hub to an app, use the following command: |
| 34 | + |
| 35 | + ```azurecli |
| 36 | + az spring-cloud app deploy \ |
| 37 | + --resource-group <your-resource-group> \ |
| 38 | + --name <your-app-name> \ |
| 39 | + --container-image <your-container-image> \ |
| 40 | + --service <your-service-name> |
| 41 | + ``` |
| 42 | + |
| 43 | +* To deploy a container image from ACR to an app, or from another private registry to an app, use the following command: |
| 44 | + |
| 45 | + ```azurecli |
| 46 | + az spring-cloud app deploy \ |
| 47 | + --resource-group <your-resource-group> \ |
| 48 | + --name <your-app-name> \ |
| 49 | + --container-image <your-container-image> \ |
| 50 | + --service <your-service-name> |
| 51 | + --container-registry <your-container-registry> \ |
| 52 | + --registry-password <your-password> | |
| 53 | + --registry-username <your-username> |
| 54 | + ``` |
| 55 | + |
| 56 | +To overwrite the entry point of the image, add the following two arguments to any of the above commands: |
| 57 | + |
| 58 | +```azurecli |
| 59 | + --container-command "java" \ |
| 60 | + --container-args "-jar /app.jar -Dkey=value" |
| 61 | +``` |
| 62 | + |
| 63 | +To disable listening on a port for images that aren't web applications, add the following argument to the above commands: |
| 64 | + |
| 65 | +```azurecli |
| 66 | + --disable-probe true |
| 67 | +``` |
| 68 | + |
| 69 | +# [Portal](#tab/azure-portal) |
| 70 | + |
| 71 | +1. Open the [Azure portal](https://portal.azure.com). |
| 72 | +1. Open your existing Spring Cloud service instance. |
| 73 | +1. Select **Apps** from left the menu, then select **Create App**. |
| 74 | +1. Name your app, and in the **Runtime platform** pulldown list, select **Custom Container**. |
| 75 | + |
| 76 | + :::image type="content" source="media/how-to-deploy-with-custom-container-image/create-app-custom-container.png" alt-text="Azure portal screenshot of Create App page with Runtime platform dropdown showing and Custom Container selected." lightbox="media/how-to-deploy-with-custom-container-image/create-app-custom-container.png"::: |
| 77 | + |
| 78 | +1. Select **Edit** under *Image*, then fill in the fields as shown in the following image: |
| 79 | + |
| 80 | + :::image type="content" source="media/how-to-deploy-with-custom-container-image/custom-image-settings.png" alt-text="Azure portal screenshot showing the Custom Image Settings pane." lightbox="media/how-to-deploy-with-custom-container-image/custom-image-settings.png"::: |
| 81 | + |
| 82 | + > [!NOTE] |
| 83 | + > The **Commands** and **Arguments** field are optional, which are used to overwrite the `cmd` and `entrypoint` of the image. |
| 84 | + > |
| 85 | + > You need to also specify the **Language Framework**, which is the web framework of the container image used. Currently, only **Spring Boot** is supported. For other Java applications or non-Java (polyglot) applications, select **Polyglot**. |
| 86 | +
|
| 87 | +1. Select **Save**, then select **Create** to deploy your application. |
| 88 | + |
| 89 | +--- |
| 90 | + |
| 91 | +## Feature Support matrix |
| 92 | + |
| 93 | +The following matrix shows what features are supported in each application type. |
| 94 | + |
| 95 | +| Feature | Spring Boot Apps - container deployment | Polyglot Apps - container deployment | Notes | |
| 96 | +|---|---|---|---| |
| 97 | +| App lifecycle management | ✔️ | ✔️ | | |
| 98 | +| Support for container registries | ✔️ | ✔️ | | |
| 99 | +| Assign endpoint | ✔️ | ✔️ | | |
| 100 | +| Azure Monitor | ✔️ | ✔️ | | |
| 101 | +| APM integration | ✔️ | ✔️ | Supported by [manual installation](#install-an-apm-into-the-image-manually) | |
| 102 | +| Blue/green deployment | ✔️ | ✔️ | | |
| 103 | +| Custom domain | ✔️ | ✔️ | | |
| 104 | +| Scaling - auto scaling | ✔️ | ✔️ | | |
| 105 | +| Scaling - manual scaling (in/out, up/down) | ✔️ | ✔️ | | |
| 106 | +| Managed Identity | ✔️ | ✔️ | | |
| 107 | +| Spring Cloud Eureka & Config Server | ✔️ | ❌ | | |
| 108 | +| API portal for VMware Tanzu® | ✔️ | ✔️ | Enterprise tier only | |
| 109 | +| Spring Cloud Gateway for VMware Tanzu® | ✔️ | ✔️ | Enterprise tier only | |
| 110 | +| Application Configuration Service for VMware Tanzu® | ✔️ | ❌ | Enterprise tier only | |
| 111 | +| VMware Tanzu® Service Registry | ✔️ | ❌ | Enterprise tier only | |
| 112 | +| VNET | ✔️ | ✔️ | Add registry to [allowlist in NSG or Azure Firewall](#avoid-not-being-able-to-connect-to-the-container-registry-in-a-vnet) | |
| 113 | +| Outgoing IP Address | ✔️ | ✔️ | | |
| 114 | +| E2E TLS | ✔️ | ✔️ | Trust a self-signed CA is supported by [manual installation](#trust-a-certificate-authority-in-the-image) | |
| 115 | +| Liveness and readiness settings | ✔️ | ✔️ | | |
| 116 | +| Advanced troubleshooting - thread/heap/JFR dump | ✔️ | ❌ | The image must include `bash` and JDK with `PATH` specified. | |
| 117 | +| Bring your own storage | ✔️ | ✔️ | | |
| 118 | +| Integrate service binding with Resource Connector | ✔️ | ❌ | | |
| 119 | +| Availability Zone | ✔️ | ✔️ | | |
| 120 | +| App Lifecycle events | ✔️ | ✔️ | | |
| 121 | +| Reduced app size - 0.5 vCPU and 512 MB | ✔️ | ✔️ | | |
| 122 | +| Automate app deployments with Terraform | ✔️ | ✔️ | | |
| 123 | +| Soft Deletion | ✔️ | ✔️ | | |
| 124 | +| Interactive diagnostic experience (AppLens-based) | ✔️ | ✔️ | | |
| 125 | +| SLA | ✔️ | ✔️ | | |
| 126 | + |
| 127 | +> [!NOTE] |
| 128 | +> Polyglot apps include non-Spring Boot Java, NodeJS, AngularJS, Python, and .NET apps. |
| 129 | +
|
| 130 | +## Common points to be aware of when deploying with a custom container |
| 131 | + |
| 132 | +The following points will help you address common situations when deploying with a custom image. |
| 133 | + |
| 134 | +### Trust a Certificate Authority in the image |
| 135 | + |
| 136 | +To trust a CA in the image, set the following variables depending on your environment: |
| 137 | + |
| 138 | +* You must import Java applications into the trust store by adding the following lines into your *Dockerfile*: |
| 139 | + |
| 140 | + ```dockerfile |
| 141 | + ADD EnterpriseRootCA.crt /opt/ |
| 142 | + RUN keytool -keystore /etc/ssl/certs/java/cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias EnterpriseRootCA -file /opt/EnterpriseRootCA.crt |
| 143 | + ``` |
| 144 | + |
| 145 | +* For Node.js applications, set the `NODE_EXTRA_CA_CERTS` environment variable: |
| 146 | + |
| 147 | + ```dockerfile |
| 148 | + ADD EnterpriseRootCA.crt /opt/ |
| 149 | + ENV NODE_EXTRA_CA_CERTS="/opt/EnterpriseRootCA.crt" |
| 150 | + ``` |
| 151 | + |
| 152 | +* For Python, or other languages relying on the system CA store, on Debian or Ubuntu images, add the following environment variables: |
| 153 | + |
| 154 | + ```dockerfile |
| 155 | + ADD EnterpriseRootCA.crt /usr/local/share/ca-certificates/ |
| 156 | + RUN /usr/sbin/update-ca-certificates |
| 157 | + ``` |
| 158 | + |
| 159 | +* For Python, or other languages relying on the system CA store, on CentOS or Fedora based images, add the following environment variables: |
| 160 | + |
| 161 | + ```dockerfile |
| 162 | + ADD EnterpriseRootCA.crt /etc/pki/ca-trust/source/anchors/ |
| 163 | + RUN /usr/bin/update-ca-trust |
| 164 | + ``` |
| 165 | + |
| 166 | +### Avoid unexpected behavior when images change |
| 167 | + |
| 168 | +When your application is restarted or scaled out, the latest image will always be pulled. If the image has been changed, the newly started application instances will use the new image while the old instances will continue to use the old image. Avoid using the `latest` tag or overwrite the image without a tag change to avoid unexpected application behavior. |
| 169 | + |
| 170 | +### Avoid not being able to connect to the container registry in a VNet |
| 171 | + |
| 172 | +If you deployed the instance to a VNet, make sure you allow the network traffic to your container registry in the NSG or Azure Firewall (if used). For more information, see [Customer responsibilities for running in VNet](/azure/spring-cloud/vnet-customer-responsibilities) to add the needed security rules. |
| 173 | + |
| 174 | +### Install an APM into the image manually |
| 175 | + |
| 176 | +The installation steps vary on different APMs and languages. The following steps are for New Relic with Java applications. You must modify the *Dockerfile* using the following steps: |
| 177 | + |
| 178 | +1. Download and install the agent file into the image by adding the following to the *Dockerfile*: |
| 179 | + |
| 180 | + ```dockerfile |
| 181 | + ADD newrelic-agent.jar /opt/agents/newrelic/java/newrelic-agent.jar |
| 182 | + ``` |
| 183 | + |
| 184 | +1. Add the environment variables required by the APM: |
| 185 | + |
| 186 | + ```dockerfile |
| 187 | + ENV NEW_RELIC_APP_NAME=appName |
| 188 | + ENV NEW_RELIC_LICENSE_KEY=newRelicLicenseKey |
| 189 | + ``` |
| 190 | + |
| 191 | +1. Modify the image entry point by adding: `java -javaagent:/opt/agents/newrelic/java/newrelic-agent.jar` |
| 192 | + |
| 193 | +To install the agents for other languages, refer to the official documentation for the other agents: |
| 194 | + |
| 195 | +New Relic: |
| 196 | + |
| 197 | +* Python: [Standard Python agent install](https://docs.newrelic.com/docs/apm/agents/python-agent/installation/standard-python-agent-install/) |
| 198 | +* Node.js: [Install the Node.js agent](https://docs.newrelic.com/docs/apm/agents/nodejs-agent/installation-configuration/install-nodejs-agent/) |
| 199 | + |
| 200 | +Dynatrace: |
| 201 | + |
| 202 | +* Python: [Instrument Python applications with OpenTelemetry](https://www.dynatrace.com/support/help/extend-dynatrace/opentelemetry/opentelemetry-traces/opentelemetry-ingest/opent-python) |
| 203 | +* Node.js: [Instrument Node.js applications with OpenTelemetry](https://www.dynatrace.com/support/help/extend-dynatrace/opentelemetry/opentelemetry-traces/opentelemetry-ingest/opent-nodejs) |
| 204 | + |
| 205 | +AppDynamics: |
| 206 | + |
| 207 | +* Python: [Install the Python Agent](https://docs.appdynamics.com/4.5.x/en/application-monitoring/install-app-server-agents/python-agent/install-the-python-agent) |
| 208 | +* Node.js: [Installing the Node.js Agent](https://docs.appdynamics.com/4.5.x/en/application-monitoring/install-app-server-agents/node-js-agent/install-the-node-js-agent#InstalltheNode.jsAgent-install_nodejsInstallingtheNode.jsAgent) |
| 209 | + |
| 210 | +### View the container logs |
| 211 | + |
| 212 | +To view the console logs of your container application, the following CLI command can be used: |
| 213 | + |
| 214 | +```azurecli |
| 215 | +az spring-cloud app logs \ |
| 216 | + --resource-group <your-resource-group> \ |
| 217 | + --name <your-app-name> \ |
| 218 | + --service <your-service-name> \ |
| 219 | + --instance <your-instance-name> |
| 220 | +``` |
| 221 | + |
| 222 | +To view the container events logs from the Azure Monitor, enter the query: |
| 223 | + |
| 224 | +```query |
| 225 | +AppPlatformContainerEventLogs |
| 226 | +| where App == "hw-20220317-1b" |
| 227 | +``` |
| 228 | + |
| 229 | +:::image type="content" source="media/how-to-deploy-with-custom-container-image/container-event-logs.png" alt-text="Screenshot of the container events log."::: |
| 230 | + |
| 231 | +### Scan your image for vulnerabilities |
| 232 | + |
| 233 | +We recommend that you use Microsoft Defender for Cloud with ACR to prevent your images from being vulnerable. For more information, see [Microsoft Defender for Cloud] (/azure/defender-for-cloud/defender-for-containers-introduction?tabs=defender-for-container-arch-aks#scanning-images-in-acr-registries) |
| 234 | + |
| 235 | +### Switch between JAR deployment and container deployment |
| 236 | + |
| 237 | +You can switch the deployment type directly by redeploying using the following command: |
| 238 | + |
| 239 | +```azurecli |
| 240 | +az spring-cloud app deploy \ |
| 241 | + --resource-group <your-resource-group> \ |
| 242 | + --name <your-app-name> \ |
| 243 | + --container-image <your-container-image> \ |
| 244 | + --service <your-service-name> |
| 245 | +``` |
| 246 | + |
| 247 | +### Create another deployment with an existing JAR deployment |
| 248 | + |
| 249 | +You can create another deployment using an existing JAR deployment using the following command: |
| 250 | + |
| 251 | +```azurecli |
| 252 | +az spring-cloud app deployment create \ |
| 253 | + --resource-group <your-resource-group> \ |
| 254 | + --name <your-deployment-name> \ |
| 255 | + --app <your-app-name> \ |
| 256 | + --container-image <your-container-image> \ |
| 257 | + --service <your-service-name> |
| 258 | +``` |
| 259 | + |
| 260 | +> [!NOTE] |
| 261 | +> Automating deployments using Azure Pipelines Tasks or GitHub Actions are not currently supported. |
| 262 | +
|
| 263 | +## Next steps |
| 264 | + |
| 265 | +* [How to capture dumps](/azure/spring-cloud/how-to-capture-dumps) |
0 commit comments