Create your first containerized Azure Functions
In this article, you create a function app running in a Linux container and deploy it to Azure Functions.
Deploying your function code to Azure Functions in a container requires Premium plan or Dedicated (App Service) plan hosting.
Other options for deploying your function app container to Azure include:
Create a function app in a container
First, you use Azure Functions tools to create your project code as a function app in a Docker container using a language-specific Linux base image. Make sure to select your language of choice at the top of the article.
Important
When creating your own containers, you are required to keep the base image of your container updated to the latest supported base image. Supported base images for Azure Functions are language-specific and are found in the Azure Functions base image repos.
The Functions team is committed to publishing monthly updates for these base images. Regular updates include the latest minor version updates and security fixes for both the Functions runtime and languages. For containers, you should regularly update the base image in the Dockerfile, rebuild, and redeploy updated versions of your containers.
Configure your local environment
Before you begin, you must have the following requirements in place:
The .NET 6 SDK.
Azure Functions Core Tools version 4.x.
- Azure Functions Core Tools version 4.x.
- A version of Node.js that is supported by Azure Functions.
- A version of Python that is supported by Azure Functions.
- The .NET 6 SDK.
A version of the Java Developer Kit that is supported by Azure Functions.
Apache Maven version 3.0 or above.
- Azure CLI version 2.4 or a later version.
If you don't have an Azure subscription, create an Azure Trial before you begin.
To publish the containerized function app image you create to a container registry, you need a Docker ID and Docker running on your local computer. If you don't have a Docker ID, you can create a Docker account.
You also need to complete the Create a container registry section of the Container Registry quickstart to create a registry instance. Make a note of your fully qualified login server name.
Create and activate a virtual environment
In a suitable folder, run the following commands to create and activate a virtual environment named .venv
. Ensure that you use Python 3.8, 3.7 or 3.6, which are supported by Azure Functions.
python -m venv .venv
source .venv/bin/activate
If Python didn't install the venv package on your Linux distribution, run the following command:
sudo apt-get install python3-venv
You run all subsequent commands in this activated virtual environment.
Create and test the local functions project
In a terminal or command prompt, run the following command for your chosen language to create a function app project in the current folder:
func init --worker-runtime dotnet-isolated --docker
func init --worker-runtime node --language javascript --docker
func init --worker-runtime powershell --docker
func init --worker-runtime python --docker
func init --worker-runtime node --language typescript --docker
In an empty folder, run the following command to generate the Functions project from a Maven archetype:
mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8 -Ddocker
The -DjavaVersion
parameter tells the Functions runtime which version of Java to use. Use -DjavaVersion=11
if you want your functions to run on Java 11. When you don't specify -DjavaVersion
, Maven defaults to Java 8. For more information, see Java versions.
Important
The JAVA_HOME
environment variable must be set to the install location of the correct version of the JDK to complete this article.
Maven asks you for values needed to finish generating the project on deployment. Follow the prompts and provide the following information:
Prompt | Value | Description |
---|---|---|
groupId | com.fabrikam |
A value that uniquely identifies your project across all projects, following the package naming rules for Java. |
artifactId | fabrikam-functions |
A value that is the name of the jar, without a version number. |
version | 1.0-SNAPSHOT |
Select the default value. |
package | com.fabrikam.functions |
A value that is the Java package for the generated function code. Use the default. |
Type Y
or press Enter to confirm.
Maven creates the project files in a new folder named artifactId, which in this example is fabrikam-functions
.
The --docker
option generates a Dockerfile for the project, which defines a suitable container for use with Azure Functions and the selected runtime.
Navigate into the project folder:
cd fabrikam-functions
Use the following command to add a function to your project, where the --name
argument is the unique name of your function and the --template
argument specifies the function's trigger. func new
creates a C# code file in your project.
func new --name HttpExample --template "HTTP trigger" --authlevel anonymous
Use the following command to add a function to your project, where the --name
argument is the unique name of your function and the --template
argument specifies the function's trigger. func new
creates a subfolder matching the function name that contains a configuration file named function.json.
func new --name HttpExample --template "HTTP trigger" --authlevel anonymous
To test the function locally, start the local Azure Functions runtime host in the root of the project folder.
func start
func start
npm install
npm start
mvn clean package
mvn azure-functions:run
After you see the HttpExample
endpoint written to the output, navigate to that endpoint. You should see a welcome message in the response output.
After you see the HttpExample
endpoint written to the output, navigate to http://localhost:7071/api/HttpExample?name=Functions
. The browser must display a "hello" message that echoes back Functions
, the value supplied to the name
query parameter.
Press Ctrl+C to stop the host.
Build the container image and test locally
(Optional) Examine the Dockerfile in the root of the project folder. The Dockerfile describes the required environment to run the function app on Linux. The complete list of supported base images for Azure Functions can be found in the Azure Functions base image page.
In the root project folder, run the docker build command, provide a name as azurefunctionsimage
, and tag as v1.0.0
. Replace <DOCKER_ID>
with your Docker Hub account ID. This command builds the Docker image for the container.
docker build --tag <DOCKER_ID>/azurefunctionsimage:v1.0.0 .
When the command completes, you can run the new container locally.
To test the build, run the image in a local container using the docker run command, replace <docker_id>
again with your Docker Hub account ID, and add the ports argument as -p 8080:80
:
docker run -p 8080:80 -it <docker_id>/azurefunctionsimage:v1.0.0
After the image starts in the local container, browse to http://localhost:8080/api/HttpExample
, which must display the same greeting message as before. Because the HTTP triggered function you created uses anonymous authorization, you can call the function running in the container without having to obtain an access key. For more information, see authorization keys.
After the image starts in the local container, browse to http://localhost:8080/api/HttpExample?name=Functions
, which must display the same "hello" message as before. Because the HTTP triggered function you created uses anonymous authorization, you can call the function running in the container without having to obtain an access key. For more information, see authorization keys.
After verifying the function app in the container, press Ctrl+C to stop the docker.
Publish the container image to a registry
To make your container image available for deployment to a hosting environment, you must push it to a container registry.
Docker Hub is a container registry that hosts images and provides image and container services.
If you haven't already signed in to Docker, do so with the
docker login
command, replacing<docker_id>
with your Docker Hub account ID. This command prompts you for your username and password. A "sign in Succeeded" message confirms that you're signed in.docker login
After you've signed in, push the image to Docker Hub by using the
docker push
command, again replace the<docker_id>
with your Docker Hub account ID.docker push <DOCKER_ID>/azurefunctionsimage:v1.0.0
Depending on your network speed, pushing the image for the first time might take a few minutes. Subsequent changes are pushed faster.
Create supporting Azure resources for your function
Before you can deploy your container to Azure, you need to create three resources:
- A resource group, which is a logical container for related resources.
- A Storage account, which is used to maintain state and other information about your functions.
- A function app, which provides the environment for executing your function code. A function app maps to your local function project and lets you group functions as a logical unit for easier management, deployment, and sharing of resources.
Use the following commands to create these items. Both Azure CLI and PowerShell are supported. To create your Azure resources using Azure PowerShell, you also need the Az PowerShell module, version 5.9.0 or later.
If you haven't done already, sign in to Azure.
az login
The
az login
command signs you into your Azure account.Create a resource group named
AzureFunctionsContainers-rg
in your chosen region.az group create --name AzureFunctionsContainers-rg --location <REGION>
The
az group create
command creates a resource group. In the above command, replace<REGION>
with a region near you, using an available region code returned from the az account list-locations command.Create a general-purpose storage account in your resource group and region.
az storage account create --name <STORAGE_NAME> --location <REGION> --resource-group AzureFunctionsContainers-rg --sku Standard_LRS
The
az storage account create
command creates the storage account.In the previous example, replace
<STORAGE_NAME>
with a name that is appropriate to you and unique in Azure Storage. Storage names must contain 3 to 24 characters numbers and lowercase letters only.Standard_LRS
specifies a general-purpose account supported by Functions.Use the command to create a Premium plan for Azure Functions named
myPremiumPlan
in the Elastic Premium 1 pricing tier (--sku EP1
), in your<REGION>
, and in a Linux container (--is-linux
).az functionapp plan create --resource-group AzureFunctionsContainers-rg --name myPremiumPlan --location <REGION> --number-of-workers 1 --sku EP1 --is-linux
We use the Premium plan here, which can scale as needed. For more information about hosting, see Azure Functions hosting plans comparison. For more information on how to calculate costs, see the Functions pricing page.
The command also creates an associated Azure Application Insights instance in the same resource group, with which you can monitor your function app and view logs. For more information, see Monitor Azure Functions. The instance incurs no costs until you activate it.
Create and configure a function app on Azure with the image
A function app on Azure manages the execution of your functions in your Azure Functions hosting plan. In this section, you use the Azure resources from the previous section to create a function app from an image in a container registry and configure it with a connection string to Azure Storage.
Create a function app using the following command, depending on your container registry:
az functionapp create --name <APP_NAME> --storage-account <STORAGE_NAME> --resource-group AzureFunctionsContainers-rg --plan myPremiumPlan --image <LOGIN_SERVER>/azurefunctionsimage:v1.0.0 --registry-username <USERNAME> --registry-password <SECURE_PASSWORD>
In this example, replace
<STORAGE_NAME>
with the name you used in the previous section for the storage account. Also, replace<APP_NAME>
with a globally unique name appropriate to you and<DOCKER_ID>
or<LOGIN_SERVER>
with your Docker Hub account ID or Container Registry server, respectively. When you're deploying from a custom container registry, the image name indicates the URL of the registry.When you first create the function app, it pulls the initial image from your Docker Hub. You can also Enable continuous deployment to Azure from your container registry.
Tip
You can use the
DisableColor
setting in the host.json file to prevent ANSI control characters from being written to the container logs.Use the following command to get the connection string for the storage account you created:
az storage account show-connection-string --resource-group AzureFunctionsContainers-rg --name <STORAGE_NAME> --query connectionString --output tsv
The connection string for the storage account is returned by using the
az storage account show-connection-string
command.Replace
<STORAGE_NAME>
with the name of the storage account you created earlier.Use the following command to add the setting to the function app:
az functionapp config appsettings set --name <APP_NAME> --resource-group AzureFunctionsContainers-rg --settings AzureWebJobsStorage=<CONNECTION_STRING>
The
az functionapp config appsettings set
command creates the setting.In this command, replace
<APP_NAME>
with the name of your function app and<CONNECTION_STRING>
with the connection string from the previous step. The connection should be a long encoded string that begins withDefaultEndpointProtocol=
.The function can now use this connection string to access the storage account.
Verify your functions on Azure
With the image deployed to your function app in Azure, you can now invoke the function through HTTP requests.
Run the following
az functionapp function show
command to get the URL of your new function:az functionapp function show --resource-group AzureFunctionsContainers-rg --name <APP_NAME> --function-name HttpExample --query invokeUrlTemplate
Replace
<APP_NAME>
with the name of your function app.
- Use the URL you just obtained to call the
HttpExample
function endpoint, appending the query string?name=Functions
.
- Use the URL you just obtained to call the
HttpExample
function endpoint.
When you navigate to this URL, the browser must display similar output as when you ran the function locally.
Clean up resources
If you want to continue working with Azure Function using the resources you created in this article, you can leave all those resources in place. Because you created a Premium Plan for Azure Functions, you'll incur one or two USD per day in ongoing costs.
To avoid ongoing costs, delete the AzureFunctionsContainers-rg
resource group to clean up all the resources in that group:
az group delete --name AzureFunctionsContainers-rg