In 2019, I dmed Azure Support to ask about how we can run serverless containerized workloads on Azure.
After two years, Microsoft Azure has finally released Azure Container apps. Azure Container apps allow you to deploy containers the serverless way at scale. Now, you don’t have to worry about the underlying infrastructure and you don’t even need to know Kubernetes. It supports any programming language and framework, autoscales on demand, and even more powerful features.
If you can write a Dockerfile, then you can use the Azure container apps. In this article, we are going to deploy a Nodejs app to Azure Container apps from GitHub. So let’s get right into it!
Install and run express application generator following the steps below:
Run the command below to install it
mkdir container-svc && cd container-svc && npx express-generator
Install the npm dependencies
npm install
Start the application
npm start
You should see an output that looks similar to this:
localhost:3000
. You should see the output look like this:Well done. You are awesome! Let’s keep going!
Create a Public repository to push your Node.js code to GitHub following the steps below:
Copy and paste this command below:
echo "# Nodejs-azure-container-app" >> README.md
git init
echo "node_modules" > .gitignore
git add .
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/nerdeveloper/nodejs-azure-container-app.git # add your repo URL here
git push -u origin main
The image below shows the structure git push
Nodejs app on GitHub.
Let’s create a Dockerfile for our Node.js app and Push it to GitHub following the steps below:
Create a Dockerfile in the root of the folder.
touch Dockerfile
Copy and paste the following commands to the Dockerfile
.
FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Run this command to exclude node_modules
in the .dockerignore
when building the docker image.
echo "node_modules" > .dockerignore
Push the updated code back to GitHub.
git add .
git commit -am "add docker components."
git push origin main
Build the image and Push it to a Docker Registry following the steps below:
Log into your docker Registry.
docker login
This command shows a prompt for a username and password. If you don’t have a docker account, kindly create one here
Let’s build the image
docker build -t nerdeveloper/nodejs-containerapp . # Change nerdeveloper to your docker username
Finally, we will push the image to our docker registry
docker push nerdeveloper/nodejs-containerapp # change nerdeveloper to your docker username
If you are not familiar with docker or creating Dockerfile(s). Please check out this article.
Create a Resource Group on Azure by running the command below. The command will create a group in North Europe.
az group create -l northeurope -n nodejs-container-app
You will see the output below
{
"id": "/subscriptions/786180ec-7ebe-4ada-8cd4-4201fd5a426c/resourceGroups/nodejs-container-app",
"location": "northeurope",
"managedBy": null,
"name": "nodejs-container-app",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
Create an Azure container registry. It is the service that will store your docker images. Run the following command below:
az acr create --resource-group nodejs-container-app \
--name NodejsExpressAcr --sku Basic
You will see the output below:
{
"adminUserEnabled": false,
"anonymousPullEnabled": false,
"creationDate": "2021-11-04T01:20:04.834773+00:00",
"dataEndpointEnabled": false,
"dataEndpointHostNames": [],
"encryption": {
"keyVaultProperties": null,
"status": "disabled"
},
"id": "/subscriptions/786180ec-7ebe-4ada-8cd4-4201fd5a426c/resourceGroups/nodejs-container-app/providers/Microsoft.ContainerRegistry/registries/NodejsExpressAcr",
"identity": null,
"location": "northeurope",
"loginServer": "nodejsexpressacr.azurecr.io",
"name": "NodejsExpressAcr",
"networkRuleBypassOptions": "AzureServices",
"networkRuleSet": null,
"policies": {
"exportPolicy": {
"status": "enabled"
},
"quarantinePolicy": {
"status": "disabled"
},
"retentionPolicy": {
"days": 7,
"lastUpdatedTime": "2021-11-04T01:20:08.687607+00:00",
"status": "disabled"
},
"trustPolicy": {
"status": "disabled",
"type": "Notary"
}
},
"privateEndpointConnections": [],
"provisioningState": "Succeeded",
"publicNetworkAccess": "Enabled",
"resourceGroup": "nodejs-container-app",
"sku": {
"name": "Basic",
"tier": "Basic"
},
"status": null,
"systemData": {
"createdAt": "2021-11-04T01:20:04.834773+00:00",
"createdBy": "odirionye@gmail.com",
"createdByType": "User",
"lastModifiedAt": "2021-11-04T01:20:04.834773+00:00",
"lastModifiedBy": "odirionye@gmail.com",
"lastModifiedByType": "User"
},
"tags": {},
"type": "Microsoft.ContainerRegistry/registries",
"zoneRedundancy": "Disabled"
}
Setup the Azure container app and deploy the Nodejs app following the steps below:
Install the Azure Container apps extension.
az extension add --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.0-py2.py3-none-any.whl
Register the Microsoft.Web
namespace.
az provider register --namespace Microsoft.Web
Export the following enviroment variables.
export RESOURCE_GROUP=nodejs-container-app
export LOCATION=northeurope
export LOG_ANALYTICS_WORKSPACE=nodejs-container-app-logs
export CONTAINERAPPS_ENVIRONMENT=container-app-env
Create an app environment for the Nodejs app following the steps below:
Create a new Log Analytics workspace.
az monitor log-analytics workspace create --resource-group $RESOURCE_GROUP --workspace-name $LOG_ANALYTICS_WORKSPACE
Get the Log Analytics Client ID and client secret.
Run this command first
LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`az monitor log-analytics workspace show --query customerId -g $RESOURCE_GROUP -n $LOG_ANALYTICS_WORKSPACE --out tsv`
Run this command next
LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET=`az monitor log-analytics workspace get-shared-keys --query primarySharedKey -g $RESOURCE_GROUP -n $LOG_ANALYTICS_WORKSPACE --out tsv`
Create the environment.
az containerapp env create \
--name $CONTAINERAPPS_ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--logs-workspace-id $LOG_ANALYTICS_WORKSPACE_CLIENT_ID \
--logs-workspace-key $LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET \
--location "$LOCATION"
You should see an output like this:
Command group 'containerapp env' is in preview and under development. Reference and support levels: https://aka.ms/CLI_refstatus
{
"aksResourceId": null,
"appLogsConfiguration": {
"destination": "log-analytics",
"logAnalyticsConfiguration": {
"customerId": "1b409e45-6bdb-496a-9f6c-78446cdf07b3",
"sharedKey": null
}
},
"arcConfiguration": null,
"containerAppsConfiguration": {
"aciSubnetResourceName": null,
"appSubnetResourceId": null,
"controlPlaneSubnetResourceId": null,
"daprAIInstrumentationKey": null,
"subnetResourceId": null
},
"defaultDomain": "politesky-63867f57.northeurope.azurecontainerapps.io",
"deploymentErrors": null,
"extendedLocation": null,
"id": "/subscriptions/786180ec-7ebe-4ada-8cd4-4201fd5a426c/resourceGroups/nodejs-container-app/providers/Microsoft.Web/kubeEnvironments/nodejs-container-app-env",
"internalLoadBalancerEnabled": null,
"kind": "containerenvironment",
"kubeEnvironmentType": "managed",
"location": "northeurope",
"name": "nodejs-container-app-env",
"provisioningState": "Succeeded",
"resourceGroup": "nodejs-container-app",
"staticIp": "13.74.44.20",
"tags": null,
"type": "Microsoft.Web/kubeenvironments"
}
Now! we can fire up the container app following the steps below:
Run the following command.
az containerapp create \
--name container-app \
--resource-group $RESOURCE_GROUP \
--environment $CONTAINERAPPS_ENVIRONMENT \
--image docker.io/nerdeveloper/nodejs-containerapp \ # Replace with your image name
--target-port 3000 \ # Replace with your custom port
--ingress 'external' \
--query configuration.ingress.fqdn
This command should return a URL similar to this:
"container-app.victoriousocean-4a8f30a3.northeurope.azurecontainerapps.io"
Copy the URL into your browser and you should now see an express homepage
Destroy all the services when you are done.
az group delete --name $RESOURCE_GROUP
You should note that Azure Container Apps is not production-ready, but you can still play around with it. Yes! We were able to deploy a simple Nodejs/express app to Azure Container apps and I am as excited you are about this serverless service. You should check out the Docs to learn more. I’d love to hear from you about your experience. Cheerio!
— Nov 12, 2021
Made with ❤ and on Netlify.