Deploy FastAPI on Azure with Github Actions | by Nathan Cheng | Towards Data Science

Github Actions is a new workflow automation tool for building, testing, and deploying your code directly from Github.
If you’re already using Github for your code repository, there’s no need to integrate a third-party tool to automate common developer workflows.
Simply place a Github Actions .yml file in your repository, designed to run in response to specific events. (push, pull requests, etc)
Today we’re going to go through an example workflow using Python to build a barebones API, with FastAPI as the framework of choice.
We will build and push a container image to Azure Container Registry, and pull the image into an Azure Web App for deployment.
Note that this article assumes prior knowledge of the technologies listed below.
The shell command examples given are on macOS. But you should be able to find equivalent commands if you’re developing on Windows.
The full list of packages and technologies we’ll be utilizing include:
VS Code — as the IDE of choice.
pipenv — to handle package dependencies, create virtual environments, and load environment variables.
FastAPI— Python API development framework.
Uvicorn — ASGI server for FastAPI app.
Docker Desktop— build and run Docker container images on our local machine.
Azure Container Registry — repository for storing our container image in Azure cloud.
Azure App Service — PaaS service to host our FastAPI app server.
Github Actions — automate continuous deployment workflow of FastAPI app.
Go ahead and download VS Code and Docker Desktop from the links above, as we will be needing those two programs throughout this guide.
In your terminal, navigate to a folder where you want to create your project, and run the following commands.
mkdir fastapi-cdcd fastapi-cdcode .
VS Code should start up with the project folder you created.
pipenv is a versatile package that removes the need for a requirements.txt file usually found in Python apps.
Hit Ctrl + ~ to open a VS Code terminal, and enter the commands:
sudo -H pip install -U pipenvpipenv install fastapi uvicorn
pipenv will proceed to install the libraries in a virtual environment and manage the dependencies for you in a Pipfile.
Because pipenv creates a virtual environment for your project, you don’t need to use the regular venv / virtualenv command either.
Simply use pipenv shell to activate the virtual environment.
pipenv shelluvicorn --versionexituvicorn --version
Use the exit command to exit the virtual environment.
Note that uvicorn is no longer accessible outside of the environment. It was only installed in the virtual environment accessible using pipenv shell.
Create the following files in the project directory.
touch main.py .env .gitignore .dockerignore Dockerfile
In the .gitignore and .dockerignore files, list .env as a file to ignore in your project folder.
Create a bare Github repo without any files and copy the repo URL.
Start tracking the changes from your local repo. In the VS Code terminal, run:
git initgit add .git commit -m "first commit"git remote add origin <github repo url>git push -u origin main
Head over to Docker Desktop and install the program.
This allows you to run Docker commands on your local machine.
www.docker.com
We’re finally done with the setup. Time to code. Head back to VS Code. In .env, set PORT=8000.
In main.py, enter the following code:
The default address route will now return you a success message.
Run pipenv run python main.py in the VS code terminal to start the uvicorn server:
Then go to http://localhost:8000/docs to see if FastAPI is running.
Note that pipenv loads your environment variables, PORT=8000, for you, before running main.py.
Instead of deploying our app as a package, let’s build our app as a Docker image, so that the build process is outlined in a Dockerfile.
Dockerfile makes the build process seamless and reproducible.
In the Dockerfile, write the following:
Build your container and check that the image has been created with the docker images command.
docker build . -t fastapi-cd:1.0docker images
Run your container with the image tag you specified earlier, on port 8000.
docker run -p 8000:8000 -t fastapi-cd:1.0
Check your containerized application by going to http://localhost:8000/docs.
You should see the same FastAPI application running.
Congratulations! You just built a simple FastAPI application, and containerized it using a Docker container on your local machine.
Time to deploy our application in Azure. First off, create an Azure Container Registry.
Enable the admin user option in the Access keys pane.
Going back to your VS Code terminal, log in to Azure with your account.
az loginaz acr login --name fastapicd
Build and push your Docker image to the registry server.
docker build . -t fastapicd.azurecr.io/fastapi-cd:1.0docker imagesdocker push fastapicd.azurecr.io/fastapi-cd:1.0
Check that your Docker image has been successfully pushed to a repo in the registry.
Next, create an App Service resource.
For the App Service Plan, change the size to Standard S1 SKU under the Production Workloads tab.
On the Docker configuration tab, make sure the container image you pushed earlier is selected.
Once resource deployment is complete, check that your web app is running by going to https://<your-webapp-name>.azurewebsites.net/docs.
You should see the FastAPI swagger docs page render.
Now we’re ready to create our Github Actions .yml file that will automate deployment of our FastAPI application.
In VS Code, create a .github/workflows directory and a prod.workflow.yml file within.
mkdir .githubcd .githubmkdir workflowscd ..touch .github/workflows/prod.workflow.yml
Build your prod.workflow.yml file like below:
Now, whenever we do a git push to the main branch, Github Actions will run a deployment job that consists of the 5 steps above, each with its own name.
Push this new file to Github using the git commands:
git add .git commit -m "github actions deployment workflow"git push
To automate our deployment workflow with Github Actions, we need to give the actions runner a service principal to authenticate to Azure, and perform the app deployment.
In VS Code terminal, run:
az ad sp create-for-rbac --name "github-actions" --role contributor --scopes /subscriptions/<GUID>/resourceGroups/fastapi-cd --sdk-auth
You can get the subscription GUID from the subscription you used to create the resource group.
You will get a response like below:
Copy the response and save it. You won’t be able to see it again.
Head over to Github settings, and create 3 Github Secrets:
AZURE CREDENTIALS: Entire JSON response from above.
REGISTRY_USERNAME: clientId value from JSON response.
REGISTRY_PASSWORD: clientSecret value from JSON response.
In the Deployment Center pane of the App Service, link your Github repo main branch, and configure deployment to use Github Actions.
The current app is running in a production slot. To guarantee higher-quality deployments, we will create a staging slot.
Slots are useful for multiple reasons:
Changes can be released to a smaller % of users in a staging slot, to validate new releases before swapping the staging slot with production.
Staging slot app instances are warmed up before being swapped into production, guaranteeing that the app is responsive to requests.
If something goes wrong with the new release, swaps can be performed again to roll back the changes.
Check that the staging app is running like the production app by going to https://<your-webapp-name>-staging.azurewebsites.net/docs.
Configure the same deployment center settings for the staging slot as you did for production.
In your main.py file, make a change to the return message.
return {"data": "Application ran successfully - FastAPI release v2.0"}
Do a git push to main branch to trigger the Github Actions workflow.
git add .git commit -m "FastAPI v2.0 release"git push
Github Actions will build and deploy the new version of your application to the staging slot automatically.
Check the new version of your application by going to https://<your-webapp-name>-staging.azurewebsites.net/docs.
Send a request to the default route to check the response. You should see v2.0 in the return message.
When you’re comfortable swapping the staging app over to production, simply click on Swap in the Deployment Slots pane of the App Service.
Do the same verification of the new app version as above by going to the production URL https://<your-webapp-name>.azurewebsites.net/docs.
Velocity matters when you’re developing software applications.
As developers, there’s a lot of things we have to keep up with — provisioning infrastructure, spinning up new environments, application testing, etc.
If we automate the boring stuff, we can focus our time on the most key tasks — building new features.
In this article, we automated the release and deploy phase of the DevOps lifecycle with Github Actions. This gives us confidence to release often into production without deployment failures.
All code written in this article can be found at the Github repo:
github.com
I would like to give a big shoutout to all the extensive documentation and YouTube videos that helped to complete this article:
Deploy a custom container to App Service using Github Actions
Github Action repo — deploy to App Service
Set up staging slots in App Service
Learn Docker in 7 Easy Steps — Full Beginner’s Tutorial
Containerize FastAPI app with Docker
Push Docker image to Azure Container Registry
pipenv tutorial video
How to run pipenv in Docker container