This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Note
Access to this page requires authorization. You can trysigning in orchanging directories.
Access to this page requires authorization. You can trychanging directories.
Use the GitHub Actions continuous integration and continuous delivery (CI/CD) platform to deploy a Python web app to Azure App Service on Linux. Your GitHub Actions workflow automatically builds the code and deploys it to the App Service whenever there's a commit to the repository. You can add other automation in your GitHub Actions workflow, such as test scripts, security checks, and multistages deployment.
If you already have a Python web app to use, make sure it's committed to a GitHub repository.
If you need an app to work with, you can fork and clone the repository athttps://github.com/Microsoft/python-sample-vscode-flask-tutorial. The code is from the tutorialFlask in Visual Studio Code.
Note
If your app uses Django and a SQLite database, it won't work for this tutorial. If your Django app uses a separate database like PostgreSQL, you can use it with this tutorial. For more information about Django, seeconsiderations for Django later in this article.
The quickest way to create an App Service instance is to use theAzure command-line interface (CLI) through the interactiveAzure Cloud Shell. The Cloud Shell includesGit and Azure CLI. In the following steps, you'll useaz webapp up to both create the App Service and do the first deployment of your app.
Step 1. Sign in to the Azure portal athttps://portal.azure.com.
Step 2. Open the Azure CLI by selecting the Cloud Shell icon on the portal toolbar.
Step 3. In the Cloud Shell, select Bash from the dropdown.
Step 4. In the Cloud Shell, clone your repository usinggit clone. For example, if you're using the Flask sample app the command is:
git clone https://github.com/<github-username>/python-sample-vscode-flask-tutorial.git
Replace <github-username> with the name of the GitHub account where you forked the repo. If you're using a different app repo, this repo is where you'll set up GitHub Actions.
Note
The Cloud Shell is backed by an Azure Storage account in a resource group calledcloud-shell-storage-<your-region>. That storage account contains an image of the Cloud Shell's file system, which stores the cloned repository. There's a small cost for this storage. You can delete the storage account at the end of this article, along with other resources you create.
Tip
To paste into the Cloud Shell, useCtrl+Shift+V, or right-click and selectPaste from the context menu.
Step 5. In the Cloud Shell, change directory into the repository folder that has your Python app so theaz webapp up command will recognize the app as Python. For the example, for the Flask sample app:
cd python-sample-vscode-flask-tutorial
Step 6. In the Cloud Shell, useaz webapp up to create an App Service and initially deploy your app.
az webapp up --name <app-service-name> --runtime "PYTHON:3.9"
Specify an App Service name that is unique in Azure. The name must be 3-60 characters long and can contain only letters, numbers, and hyphens. The name must start with a letter and end with a letter or number.
Useaz webapp list-runtimes
to get a list of available runtimes. Use thePYTHON|X.Y
format, whereX.Y
is the Python version.
You can also specify the location of the App Service with the--location
parameter. Use theaz account list-locations --output table
command to get a list of available locations.
Step 7. If your app uses a custom startup command, then use theaz webapp config use that command. If your app doesn't have a custom startup command, skip this step.
For example, thepython-sample-vscode-flask-tutorial app contains a file namedstartup.txt that contains a startup command that you can use as follows:
az webapp config set \ --resource-group <resource-group-name> \ --name <app-service-name> \ --startup-file startup.txt
You can find the resource group name from the output from the previousaz webapp up
command. The resource group name will start with<azure-account-name>_rg_.
Step 8. To see the running app, open a browser and go tohttp://<app-service-name>.azurewebsites.net.
If you see a generic page, wait a few seconds for the App Service to start, and refresh the page. If you continue to see the generic page, check that you deployed from the correct folder. For example, if you're using the Flask sample app, the folder ispython-sample-vscode-flask-tutorial. Also, for the Flask sample app, check that you set the startup command correctly.
In the steps below, you'll set up continuous deployment (CD), which means a new code deployment happens when a workflow is triggered. The trigger in this tutorial is any change to the main branch of your repository, such as with a pull request (PR).
Step 1. Add GitHub Action with theaz webapp deployment github-actions add command.
az webapp deployment github-actions add \ --repo "<github-username>/<github-repo>" \ --resource-group <resource-group-name> \ --branch <branch-name> \ --name <app-service-name> \ --login-with-github
The--login-with-github
parameter uses an interactive method to retrieve a personal access token. Follow the prompts to complete the authentication.
If there's an existing workflow file that conflicts with the name App Service uses, you'll be asked to choose whether to overwrite. Use the--force
parameter to overwrite without asking.
What the add command does:
Step 2. Get the details of a source control deployment configuration with theaz webapp deployment source show command.
az webapp deployment source show \ --name <app-service-name> \ --resource-group <resource-group-name>
In the output from the command, confirm the values for therepoUrl
andbranch
properties. These values should match the values you specified in the previous step.
A workflow is defined by a YAML (.yml) file in the/.github/workflows/ path in your repository. This YAML file contains the various steps and parameters that make up the workflow, an automated process that associated with a GitHub repository. You can build, test, package, release, and deploy any project on GitHub with a workflow.
Each workflow is made up of one or more jobs. Each job in turn is a set of steps. And finally, each step is a shell script or an action.
In terms of the workflow set up with your Python code for deployment to App Service, the workflow has the following actions:
Action | Description |
---|---|
checkout | Check out the repository on arunner, a GitHub Actions agent. |
setup-python | Install Python on the runner. |
appservice-build | Build the web app. |
webapps-deploy | Deploy the web app using a publish profile credential to authenticate in Azure. The credential is stored in aGitHub secret. |
The workflow template that is used to create the workflow isAzure/actions-workflow-samples.
The workflow is triggered on push events to the specified branch. The event and branch are defined at the beginning of the workflow file. For example, the following code snippet shows the workflow is triggered on push events to themain branch:
on: push: branches: - main
When you set up continuous deployment, you authorize Azure App Service as an authorized OAuth App for your GitHub account. App Service uses the authorized access to create a GitHub action YML file in.github/workflows/<workflow-name>.yml. You can see your authorized apps and revoke permissions under your GitHub accountsSettings, underIntegrations/Applications.
In the.github/workflows/<workflow-name>.yml workflow file that was added to the repo, you'll see a placeholder for publish profile credentials that are needed for the deploy job of the workflow. The publish profile information is stored encrypted in the repositorySettings, underSecurity/Actions.
In this article, the GitHub action authenticates with a publish profile credential. There are other ways to authenticate such as with a service principal or OpenID Connect. For more information, seeDeploy to App Service using GitHub Actions.
Now you'll test the workflow by making a change to the repo.
Step 1. Go to your fork of the sample repository (or the repository you used) and select the branch you set as part of the trigger.
Step 2. Make a small change.
For example, if you used the VS Code Flask tutorial, you can
Step 3. Commit the change directly to the branch you're working in.
You can also kick off the workflow manually.
Step 1. Go to theActions tab of the repo set up for continuous deployment.
Step 2. Select the workflow in the list of workflows and then selectRun workflow.
To check a workflow's status, go to the Actions tab of the repo. When you drill into the workflow file created in this tutorial, you'll see two jobs "build", and "deploy". For a failed job, look at the output of job tasks for an indication of the failure. Some common issues are:
If the app fails because of a missing dependency, then yourrequirements.txt file wasn't processed during deployment. This behavior happens if you created the web app directly on the portal rather than using theaz webapp up
command as shown in this article.
If you provisioned the app service through the portal, the build action SCM_DO_BUILD_DURING_DEPLOYMENT setting may not have been set. This setting must be set totrue
. Theaz webapp up
command sets the build action automatically.
If you see an error message with "TLS handshake timeout", run the workflow manually by selecting Trigger auto deployment under the Actions tab of the repo to see if the timeout is a temporary issue.
If you set up continuous deployment for the container app as shown in this tutorial, the workflow file (.github/workflows/<workflow-name>.yml) is initially created automatically for you. If you modified it, remove the modifications to see if they're causing the failure.
A post-deployment script can, for example, define environment variables expected by the app code. Add the script as part of the app code and execute it using startup command.
To avoid hard-coding variable values in your workflow YML file, you can instead them in the GitHub web interface and then refer to the variable name in the script. You can create encrypted secrets for a repository or for an environment (account repository). For more information, seeEncrypted secrets in GitHub Docs.
As noted earlier in this article, you can use GitHub Actions to deploy Django apps to Azure App Service on Linux, if you're using a separate database. You can't use a SQLite database, because App Service locks the db.sqlite3 file, preventing both reads and writes. This behavior doesn't affect an external database.
As described in the articleConfigure Python app on App Service - Container startup process, App Service automatically looks for awsgi.py file within your app code, which typically contains the app object. When you used thewebapp config set
command to set the startup command, you used the--startup-file
parameter to specify the file that contains the app object. Thewebapp config set
command isn't available in the webapps-deploy action. Instead, you can use thestartup-command
parameter to specify the startup command. For example, the following code snippet shows how to specify the startup command in the workflow file:
startup-command: startup.txt
When using Django, you typically want to migrate the data models usingpython manage.py migrate
command after deploying the app code. You can run the migrate command in a post-deployment script.
Disconnecting GitHub Actions from your App Service allows you to reconfigure the app deployment. You can choose what happens to your workflow file after you disconnect, whether to save or delete the file.
Disconnect GitHub Actions with Azure CLIaz webapp deployment github-actions remove command.
az webapp deployment github-actions remove \ --repo "<github-username>/<github-repo>" \ --resource-group <resource-group-name> \ --branch <branch-name> \ --name <app-service-name> \ --login-with-github
To avoid incurring charges on the Azure resources created in this tutorial, delete the resource group that contains the App Service and the App Service Plan.
Anywhere the Azure CLI is installed including the Azure Cloud Shell, you can use theaz group delete command to delete the resource group.
az group delete --name <resource-group-name>
To delete the storage account that maintains the file system for Cloud Shell, which incurs a small monthly charge, delete the resource group that begins withcloud-shell-storage-. If you're the only user of the group, it's safe to delete the resource group. If there are other users, you can delete a storage account in the resource group.
If you deleted the Azure resource group, consider also making the following modifications to the GitHub account and repo that was connected for continuous deployment:
Was this page helpful?