Abstract
This article shows how to write an Azure Function App on your development computer, aka local machine and deploy it to Docker on Azure. If you're new but want to learn about Azure Function App, Docker containers on Azure, Azure Container Registries etc, and how to use all of them together, you could be overwhelmed with plenty of but disparate Azure documentation (not to mention documentation on Docker website itself), and they won't be so clear especially if you're trying to see how they all fit together. On the hand, this article hopefully provides you with the quickest, step-by-step approach. You will go from zero to deployment in x minutes. Once you see how the Function App finally runs on Azure cloud after a few steps, we will go back to the development computer, makes some changes as we often have to do in real world situations, go through all the steps again, and see the changes reflected on Azure.
Requirements
- You must already have an Azure Subscription
- Your development (dev) computer must run at least Windows 10 Pro, or latest MacOS or Ubuntu Linux (I have not tried)
Assumptions:
- We will write the sample Azure Function App in
C#/.Net
- The sample Azure Function App is
HttpTriggered
. - I will show everything using command line interface (CLI). But there's always an UI alternative.
- Naming convention: You will find I'm using name like
kleSampleResourceGroup
in the instructions of this article. Such name likekleSampleResourceGroup
can be broken in 3 parts.kle
identifies the organization.Sample
is the name of this project.ResourceGroup
identifies the thing that we are naming.
Step 1: Installation
We have to install a few software programs on the dev computer. However, these installations are extremely simple. Just follow the links listed.
NodeJS https://nodejs.org/download/release/
Docker https://www.docker.com/products/docker-desktop (Docker requires you to signup)
Azure Function Core Tools Once NodeJS
and npm
have been installed, you can run the following command
% npm install -g azure-functions-core-tools@latest
.NET Core https://dotnet.microsoft.com/download/dotnet-core (Note: I have not tried with .Net Core 3.+)
Azure CLI https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest
Step 2: Create a new Azure Function App on the dev computer
On your terminal, type
% mkdir kleSampleFuncApp
% cd kleSampleFuncApp
% func init . --docker
The last command will prompt us to select a worker runtime. Four choices are presented. As mentioned above, we will choose dotnet
. Consequently, this command will generate the following files in the directory: Dockerfile
, host.json
, kleSampleFuncApp.csproj
and local.settings.json
Next, in the newly created Function App, we will create a new Function using the HttpTriggered template. A Function App can have multiple Functions. Each Function in this context represents an URL endpoint.
% func new
This command will prompt us to pick a Function App template. Choose HttpTrigger
. It will then prompt for a function name, enter kleSampleFunc
. This will generate a file named kleSampleFunc.cs
. Open up that file, search for AuthorizationLevel.Function
and change it to AuthorizationLevel.Anonymous
Step 3: Build and run the Function App on the dev computer
% func start --build
This command will build and start the Function App. We will see that the application is listening on the default port 7071, can handle both GET and POST requests and the entire URL endpoint is http://localhost:7071/api/kleSampleFunc
If you're on Mac or Linux, you can use curl
to quickly test. Alternatively, you can use Postman
or any other similar tools.
% curl -X POST http://localhost:7071/api/kleSampleFunc -d '{"name":"kevin"}' -H "Content-Type: application/json"
Step 4: Create a Docker image of the Azure Function App on the dev computer
Earlier in step 2, we typed the command func init . --docker
. The option or flag --docker
tells Azure Function Core Tool to generate the Dockerfile
. With that, now we can create a Docker image of the Function App. This image will be uploaded to a Docker container on the Azure cloud (Azure Container Registry) later.
With Docker Desktop running, on your terminal, type
% docker build -t kle/sampledockerimg .
% docker run -p 7071:80 kle/sampledockerimg
Do not forget to type the dot at the end of the build command
Now test again:
% curl -X POST http://localhost:7071/api/kleSampleFunc -d '{"name":"kevin"}' -H "Content-Type: application/json"
If that's working, we now have created a Docker image of the Function App and run it on Docker Desktop successfully.
Step 5: Log in to Azure CLI on the dev computer
On your terminal, type
% az login
and follow the instructions.
Step 6: Create an Azure Resource Group on Azure cloud
% az group create -l westus -n kleSampleResourceGroup
Step 7: Create an Azure Container Registry on the Azure cloud
% az acr create -n kleSampleRegistry -g kleSampleResourceGroup --sku Standard --admin-enabled true
Notice the JSON output with the key loginServer
. Its value should be something like klesampleregistry.azurecr.io
Launch the Azure portal, https://portal.azure.com, then browse your Container Registries, select the Registry you just created (in my case klesampleregistry
), click on Access Key
under Settings
, and note the username
and password
.
Step 8: Create an Azure Storage Account on Azure cloud
% az storage account create -n klesamplestorage -g kleSampleResourceGroup -l westus
Step 9: Login to your Azure Container Registry
% docker login klesampleregistry.azurecr.io
When prompted, provide the username
and password
that you noted in step 7.
Step 10: Tag your Docker image
Look at step 4 when you build the docker image of your Function App (kle/sampledockerimg
), you will tag this image in the Container Registry as klesample
(note this name must be all in lower case)
% docker tag kle/sampledockerimg klesampleregistry.azurecr.io/klesample
Step 11: Push the docker image to the Container Registry
Using Docker, we can now push the image to the Container Registry on Azure
% docker push klesampleregistry.azurecr.io/klesample
Step 12: Create an Azure Function App
There is a command from Azure CLI az functionapp create
that we could use. But the problem is it does not allow the created Function App to be published from a Docker container. So we will use the UI https://portal.azure.com
Click on the big Plus button Create a Resource
under Azure Services
, search for Function App
template and click on Create
Click on Next: Hosting >
Click on Review + Create
then Create
on the last page.
Once the Function App kleSampleFuncApp
has been created, click on Platform features
, then Container Settings
as shown below
On the next screen, select Single Container
, Azure Container Registry
, the registry that we created in step 7, the image in step 10, latest
. Select On
for Continuous Deployment
, and Save it.
Once saved, you can close the blade. Back on the Overview
page, on the Right menu, click on kleSampleFuncApp
, expand kleSampleFunc
, you can run test directly from this page. Follow the screenshot below:
You can also click the Get Function URL
link next to the run button and test from Curl or Postman.
% curl -X POST https://klesamplefuncapp.azurewebsites.net/api/kleSampleFunc -d '{"name":"kevin"}' -H "Content-Type: application/json"
Continuous Deployment
Remember back on step 12, we select On
for Continuous Deployment
. We did so because if we ever need to make changes of the code, which will certainly happen, we want to push the changes up to the Function App on the Docker container on Azure.
So let's go back to the code and change from Hello
to Hi
. Save.
First let's test when we run locally. On the terminal, type
func start -build
If you get the error message
Port 7071 is unavailable. Close the process using that port, or specify another port using --port [-p].
That's because we had the Docker image still running from earlier. We need to stop it.
Type
% docker ps
Note the Container Id
in the output. Assume it's something like 87d8462f9d63
, type
% docker stop 87d8462f9d63
Again, type
% func start -build
Test as we did in step 3. This confirms the change we made is good. Now rebuild the Docker image and run it as we did in step 4.
% docker build -t kle/sampledockerimg .
% docker run -p 7071:80 kle/sampledockerimg
Test again. This confirms the new build of the Docker image contains the change that we made. Now let's tag and push it to Docker on Azure as we did in step 11.
% docker tag kle/sampledockerimg klesampleregistry.azurecr.io/klesample
% docker push klesampleregistry.azurecr.io/klesample
Top comments (0)