Deploy to Azure App Service on Linux

This tutorial walks you through using Visual Studio Code to deploy a Python application to Azure App Service on Linux using the Azure App Service extension.

Azure App Service on Linux, currently in Preview for Python, runs your source code in a pre-defined Docker container. The characteristics of this container are summarized as follows (for full documentation, see Configure Python apps for App Service on Linux):

  • Apps are run with Python 3.7 using the Gunicorn web server.
  • The container includes Flask by default but not Django.
  • To install Django and any other dependencies, you must provide a requirements.txt file and deploy to App Service using Git, as shown in this tutorial. For App Service to install dependencies, requirements.txt must be deployed to the root folder.
  • Although the container can run Django and Flask apps automatically, provided the app matches an expected structure, you can also provide a custom startup command file through which you have full control over the Gunicorn command line. A custom startup command is typically required for Flask apps, but not Django apps.
  • The container definition itself is on the

If you encounter any problems in the course of this tutorial, feel free to file an issue in the Visual Studio Code documentation repository.


To complete this tutorial, you need an Azure account, Visual Studio Code with the Azure App Service extension, a Python environment, and an app that you'd like to deploy.

Azure account

If you don't have an Azure account, sign up now for a free account with $200 in Azure credits to try out any combination of services.

Visual Studio Code, Python, and the Azure App Service extension

Install the following software:

Sign in to Azure

Once the App Service extension is installed, sign into your Azure account by navigating to the Azure: App Service explorer, select Sign in to Azure, and follow the prompts.

Sign in to Azure through VS Code

After signing in, verify that you see the email account of your Azure around in the Status Bar and your subscription(s) in the Azure: App Service explorer:

VS Code status bar showing Azure account

VS Code Azure App Service explorer showing subscriptions

Note: If you see the error "Cannot find subscription with name [subscription ID]", this may be because you are behind a proxy and unable to reach the Azure API. Configure HTTP_PROXY and HTTPS_PROXY environment variables with your proxy information in your terminal:

# macOS/Linux
export HTTPS_PROXY=https://username:password@proxy:8080
export HTTP_PROXY=http://username:password@proxy:8080

set HTTPS_PROXY=https://username:password@proxy:8080
set HTTP_PROXY=http://username:password@proxy:8080

Your application

If you don't already have an app you'd like to work with, use one of the options below. Be sure to verify that the app runs locally.

  • Create a new folder, open it in VS Code, and add a file named with the contents below, which creates a minimal Flask app as used in this walkthrough. The app object is purposely named myapp to demonstrate how the names are used in the startup command for the App Service, as you see later.

    Also follow the instructions in Flask Tutorial - Create a project environment for Flask to create a virtual environment with Flask installed within which you can run the app locally.

    from flask import Flask
    myapp = Flask(__name__)
    def hello():
        return "Hello Flask, on Azure App Service for Linux"
  • python-sample-vscode-flask-tutorial, which is the result of following the Flask Tutorial.

  • python-sample-vscode-django-tutorial, which is the result of following the Django Tutorial.

    Caveat: If your Django app uses a local SQLite database like this sample, you need to include a pre-initialized and pre-populated copy of the db.sqlite3 file in your repository. The reason for this is that, at present, the preview of App Service for Linux doesn't have a means to run Django's migrate command as part of deployment, so you must deploy a pre-made database. Even then, the database is effectively read-only; writing to the database also causes errors. The workaround is to use a database that's hosted elsewhere, in which case you would deploy and initialize that database separately before deploying the app code as described in this tutorial.

Create the App Service

  1. In the Azure: App Service explorer, select the + command to create a new App Service, or open the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)) and select Azure App Service: Create New Web App. (In App Service terminology, a "web app" is a host for web app code, not the app code itself.)

    Create new App Service button in the App Service explorer

  2. In the prompts that follow:

    • Enter a name for your app, which must be globally unique on App Service; typically you use your name or company name followed by the app name.
    • Select Linux for the operating system.
    • Select [Preview] Python 3.7 as the runtime.
  3. After a short time you see a message that the new App Service was created, along with the question Deploy to web app?. Answer No at this point because you need to change the deployment source to Git. Otherwise the "Deploy to Web App" command only copies your files to the server using a ZIP file and doesn't install your dependencies.

    Messages that appear after the App Service is created

  4. To confirm that the App Service is running properly, expand your subscription in the Azure: App Service explorer, right-click the App Service name, and select Browse website:

    Browse Website command on an App Service in the App Service explorer

  5. Because you haven't deployed your own code to the App Service yet, you should see only the default app:

    Default Python app on App Service on Linux

(Optional) Upload an environment variable definitions file

If you have an environment variable definitions file (typically with the .env extension), you can use that file to configure the App Service environment as well:

  1. In the Azure: App Service explorer, expand the node for the desired App Service, then right-click the Application Settings node and select Upload Local Settings.

  2. VS Code prompts you for the location of your .env file, then uploads it to the App Service.

  3. Once the upload is complete, you can expand the Application Settings node to see the individual values. You can also view them on the Azure portal by navigating to the App Service and selecting Configuration.

  4. If you create settings directly on the Azure portal, you can save them in a definitions file by right-clicking the Application Settings node and selecting Download Remote Settings. This process makes sure that you have those settings in your repository and not only on the portal.

Configure a custom startup file

Depending on how you've structured your app, you may need to create a custom startup command file for your app as described on Configure Python apps for App Service on Linux in the Azure docs.

The specific use cases of a custom startup command are as follows:

  • You have a Flask app whose startup file and app object are named something other than and app, respectively. In other words, unless you have an in the root folder of your project, and the Flask app object is named app, then you need a custom startup command.
  • You want to start the Gunicorn web server with additional arguments beyond the defaults, which are --bind= --timeout 600.

Django apps typically don't need customizations unless you want to provide additional arguments to Gunicorn.

If you need a custom startup file, first create the file and commit it to your repository so it can be deployed with the rest of the app code.

  1. Create a file in your project named startup.txt (or another name of your choice) that contains your startup command. For Flask, see Flask startup commands in the next section.

  2. In the Azure: App Service explorer, expand the App Service, right-click Application Settings, and select Open in Portal:

    Open Settings in Portal command in the App Service explorer

  3. In the Azure portal, sign in if necessary; then on the Application settings page, enter your startup file name (like startup.txt) under Runtime > Startup File, then select Save. (This step is the one case in which you need to visit the Azure portal.)

    Setting the startup file name in the Azure portal

  4. The App Service restarts when you save changes. Because you still haven't deployed your app code, however, visiting the site at this point shows "Application Error." This message indicates that the Gunicorn server started but failed to find the app, and therefore nothing is responding to HTTP requests.

Note: Instead of using a startup command file, you can also put the startup command directly in the Startup File field on the Azure portal. Using a file is generally preferable, however, as it keeps this bit of configuration in your repository where you can audit changes and redeploy to a different App Service instance altogether.

Flask startup commands

By default, the App Service on Linux container assumes that a Flask app's startup file is named and resides in the app's root folder. It further assumes that the Flask app object defined within that file is named app. If your app isn't structured in this exact way, then your custom startup command must identify the app object's location:

  1. Different file name and/or app object name: for example, if the app's startup file is hello.pyand the app object is named myapp, the startup command is as follows:

    gunicorn --bind= --timeout 600 hello:myapp
  2. Startup file is in a subfolder: for example, if the startup file is myapp/ and the app object is app, then use Gunicorn's --chdir argument to specify the folder and then name the startup file and app object as usual:

    gunicorn --bind= --timeout 600 --chdir myapp website:app
  3. Startup file is within a module: in the python-sample-vscode-flask-tutorial code, the startup file is contained within the folder hello_app, which is itself a module with an file. The app object is named app and is defined in and uses a relative import. Because of this arrangement, pointing Gunicorn to webapp:app produces the error, "Attempted relative import in non-package," and the app fails to start.

    In this situation, create a simple shim file that imports the app object from the module, and then have Gunicorn launch the app using the shim. The python-sample-vscode-flask-tutorial code, for example, contains with the following contents:

    # shim
    from hello_app.webapp import app

    The startup command is then the following:

    gunicorn --bind= --timeout 600 startup:app

Add the app to a Git repository

As noted earlier, you must deploy to App Service on Linux using Git in order for the container to install your dependencies in requirements.txt. The following steps make sure you have both a requirements.txt file and a repository:

  1. Create a requirements.txt file in your root folder if you don't have one already:

    1. Activate your virtual environment with the Python: Select Interpreter command on the Command Palette (⇧⌘P (Windows, Linux Ctrl+Shift+P)).
    2. Open a terminal for the environment with Terminal: Create New Integrated Terminal.
    3. Make sure you're in the root folder of the app, then run pip freeze > requirements.txt.

    Tip: be sure to place requirements.txt in the root folder, otherwise App Service won't find it and won't automatically install your dependencies.

  2. In your project folder, create a file named .gitignore with the following contents (change .venv if you're using a different folder for a virtual environment):

  3. From the Command Palette, run the Git: Initialize Repository command.

    Initialize repository command in the Command Palette

    The same command is found at the top of the Source Control explorer:

    Initialize repository command in the Source Control explorer

  4. In the prompt that appears, select your current folder for the repository, then answer Open Repository in the subsequent message"

    Selecting a repository folder

    Opening the repository after initialization

  5. In the Source Control explorer, you see your project files ready to commit to the repository. Enter a commit message like "Initial commit", then select the checkmark button:

    Commit the app code to source control

Deploy your app using Git

As mentioned earlier, you must use Git to deploy Python apps to App Service on Linux so that your dependencies in requirements.txt are installed. With Git deploy you can use either a local repository or a GitHub repository.

  1. Make sure all your code changes are committed to your repository, and pushed to GitHub if you're using that option.

  2. In the Azure: App Service explorer, right-click the App Service name, and select Configure Deployment Source:

    Configure Deployment Source command on an App Service in the App Service explorer

  3. When prompted, choose either LocalGit or GitHub as the source:

    • LocalGit: code is deployed from the currently active branch of your local copy of the repository.

    • GitHub: code is deployed from the selected branch of a GitHub repository, and happens automatically when you push commits to the repository. Selecting this option successively prompts you for the organization, repository, and branch to use.

  4. With both choices, the extension connects the App Service to the repository. You don't see indications of the connection in VS Code itself; on the Azure portal, you can examine the connect on the Azure portal in the App Service's Deployment Center page.

  5. To shorten deployment time, you can exclude VS Code files and your virtual environment by adding the following lines to the .vscode/settings.json file (replace .env with your particular virtual environment folder):

    "appService.zipIgnorePattern": [
  6. To deploy the app:

    • LocalGit: Commit your changes to your local repository, then right-click the App Service again, select Deploy to Web App, and select the project folder when prompted. (You can also select the deploy button at the top of the explorer.)

      Deploy to Web App command on an App Service in the App Service explorer

    • GitHub: Commit your changes, then do a Git push by selecting Git: Push from the Command Palette or by using the sync changes button on the status bar:

      Git sync changes button on the VS Code status bar

  7. While deployment is taking place, you see an indicator in the App Service extension explorer:

    Deployment indicator in the App Service extension explorer

    You can also observe progress in the Output panel (⇧⌘U (Windows Ctrl+Shift+U, Linux Ctrl+K Ctrl+H)) by selecting Azure App Service from the drop-down:

    Observing App Service output in the Output window

  8. After a minute or two (depending on how many dependencies are in your requirements.txt), VS Code reports that deployment is complete. To verify that your files are deployed, expand the App Service in the Azure: App Service explorer, then expand Files:

    Checking deployment files through the App Service explorer

    The antenv folder is where App Service creates a virtual environment with your dependencies. If you expand this node, you can verify that the packages you named in requirements.txt are installed in antenv/lib/python3.7/site-packages.

  9. Right-click the App Service again and select Browse Website to view your running app (you may need to refresh the browser if the previous page was cached):

    The app running successfully on App Service

Make changes and redeploy

With your App Service connected to a repository, you have a simple code-test-deploy process:

  1. Make changes and test the app locally.

  2. Commit changes to your Git repository. Always remember this step, because the App Service extension pulls your code from the repository and won't pick up uncommitted changes!

  3. Deploy the code:

    1. LocalGit: open the Azure: App Service explorer, right-click the App Service, and select Deploy to Web App.
    2. GitHub: push your changes to GitHub; App Service automatically deploys the code and restarts.
  4. Once deployment is complete, wait a few seconds for the App Service to restart, then browse the website and verify your changes.

With any deployment option, you can observe status on the Azure portal under the App Service's Deployment > Deployment options page:

Azure portal showing deployment status for an App Service

Changing the GitHub branch

When you use the App Service extension in VS Code to set GitHub as the deployment source, you're prompted for a specific branch. This branch is then directly wired into the App Service configuration. To use a different branch, you must first disconnect the existing branch, then create a new connection:

  1. In the App Service explorer in VS Code, right-click the App Service and select Open in portal.

  2. On the portal, select Deployment > Deployment options, then select Disconnect.

    Disconnecting a deployment source

  3. Once disconnected, you can configure a new connection directly on the portal, or you can use the App Service extension in VS Code to set the deployment source to GitHub again, selecting the desired branch.

Clean up resources

The App Service you created includes a backing App Service Plan that can incur costs. To clean up the resources, right-click the App Service in the Azure: App Service explorer and select Delete. You can also visit the Azure portal, select Resource groups from the left-side navigation pane, select the resource group that was created in the process of this tutorial, and then use the Delete resource group command.

Next steps

Congratulations on completing this walkthrough of deploying Python code to App Service on Linux!

As noted earlier, you can learn more about the App Service extension by visiting its GitHub repository, vscode-azureappservice. Issues and contributions are also welcome.

To learn more about Azure services that you can use from Python, including data storage along with AI and Machine Learning services, visit Azure Python Developer Center.

There are also other Azure extensions for VS Code that you may find helpful. Just search on "Azure" in the Extensions explorer:

Azure extensions for VS Code

Some popular extensions are:

And again, if you encountered any problems in the course of this tutorial, feel free to file an issue in the VS Code docs repo.