You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this walkthrough, I will deploy the app rx_shout to Azure, using an Azure Container App to host the backend and an Azure Static Web App to host the frontend.
Docker installation and a Docker Hub account registered to push the container image that we will build. (Alternatively you can use an Azure Container Registry, but that will not be covered here)
I had to specify the --platform linux/amd64 otherwise my Mac will build an arm image, which will not run in Azure Container App.
Resources
Resource Group
In Azure portal, create a new Resource Group that will hold all objects related to this app deployment.
Virtual Network
In Azure portal, create a new Virtual Network that will link the redis cache, app containers, and database.
On the IP Addresses tab, create a 10.0.0.0/16 network with 2 subnets, default and database.
Redis
In a multi-container deployment, it is essential to use redis so the same user retains their state when moving between application instances. Azure does provide managed redis clusters, which may provide better performance and reliability, at a significant cost.
In this deployment, I will go with the low cost option of running the redis container as a Container Instances resource type.
Flip over to the Networking tab and assign it to the default subnet of the vnet we previously created. Ensure the redis port, 6379, is allowed.
After the container is created, take note of the private IP address it was assigned:
REDIS_URL=redis://10.0.0.4
Database
We will use the Azure Database for PostgreSQL resource type to easily deploy the database. For this example, I'm using "development mode" because it's much cheaper. Adjust accordingly for heavier workloads.
Set the database superuser name and password and retain this information for later.
Username: reflex
Password: wowjyg-civgy7-nYxpis
On the Networking tab, select Private Access and assign the server to the existing vnet and database subnet that were created earlier.
After the resource is created, create a new database for the app, called rx_shout.
With the new database created, we can formulate the DB_URL which should be passed to the app
Containers are ephemeral and cannot store persistent data. Since this app accepts user uploads, it needs a place to save them.
We will create a new Storage Account resource to store our app's files. Ensure that the storage account is created in the same resource group created earlier.
Flip over to the Networking tab. Select "Enable public access from selected virtual networks and IP addresses".
After the resource is created, add a new File Share that will store the uploaded files from the app.
While we're here, open the Access Keys page and copy down the access key for this storage account.
Now it's time to create the Azure Container App, and link it up with the redis, database, and storage that we just created.
Select the resource group that we created earlier, and choose the appropriate Region.
Important: Under Container Apps Environment, click "Create New" to customize the environment. This is needed to link up the container with the vnet that we created earlier.
In the new Container Apps Environment, flip over to the Networking tab. Select Yes to use your own virtual network and select the vnet1 that we created earlier.
For Infrastructure Subnet select Create New.
Create a new /24 subnet in the existing address space. I'm calling this one container-env.
If you already created a "container-env" subnet earlier, just create a new one now.
Save the Subnet and create the Container Apps Environment.
On the Container Apps, select the Container tab. Uncheck "Use quickstart image". Enter the details of the container that was previously uploaded to the registry.
At the bottom of this tab, enter the Environment Variables that were noted earlier.
REDIS_URL=redis://10.0.0.4
We will enter the db url later as a secret.
On the Ingress tab, enable Ingress. Accept traffic from anywhere. Ignore Client Certificate. Set target port to 8000 (Reflex default backend), and enable Session affinity.
Linkages
Now that the Container App and Environment are created, we need to make a few tweaks to the other resources to enable communications.
Go back to the resource group, open the Storage account resource, and open the Networking panel. Select "Add Existing Virtual Network" and select the vnet and newly created container-env subnet. Click Enable. Then click Add. Then click Save again after the virtual network modal closes.
Go back to the resource group, open the Container Apps Environment resource, and open the Azure Files panel. Click Add. Enter a name for the volume, the name of the Storage account (why is this not a dropdown??), the Storage Key that we copied earlier, and the name of the share that we created earlier.
Ensure Access mode is set to Read/Write
Go back to the resource group, open the Container App resource, and open the Secrets panel and add a new secret for db-url
Open the Volumes tab. Click Add. Enter the Azure Files information that we added earlier. Click Add, then Save as a New Revision.
Open the Containers tab and click Edit and Deploy.
Click the name of the container in the bottom half of the page.
Scroll down to the environment variables and add DB_URL referencing the secret that we created earlier.
Switch over to the Volume mounts tab. Select the Volume created earlier. Set Mount path to /app/uploaded_files
Click Save. Click Create.
It will take a moment to deploy. When the replica is reported as "Running", we can check the backend status.
Open the Overview panel, copy the application URL and add /ping to the end. The browser should display "pong"
Take note of the application URL as this will need to be passed as API_URL when exporting the frontend.
For this deployment, I have chosen "Other" as the source, because I will be pushing the static files manually using the @azure/static-web-apps-cli utility.
Export
Back to the app directory on your development machine, run the following command to create the static files for export.
(.venv) masenf@minicone deploy-azure2 % API_URL=https://rx-shout-backend.gentlemushroom-01fc3053.eastus.azurecontainerapps.io reflex export --frontend-only --no-zip
Info: Overriding config value api_url with env var API_URL=https://rx-shout-backend.gentlemushroom-01fc3053.eastus.azurecontainerapps.io
───────────────────────────────────────────────────────────────────────────────── Initializing rx_shout ─────────────────────────────────────────────────────────────────────────────────
[10:29:22] Initializing the web directory. console.py:95
Success: Initialized rx_shout
────────────────────────────────────────────────────────────────── Compiling production app and preparing for export. ───────────────────────────────────────────────────────────────────
DeprecationWarning: rx.input.root has been deprecated in version 0.5.0 use rx.input without the .root suffix. It will be completely removed in 0.6.0
Compiling: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 13/13 0:00:00
Creating Production Build: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 9/9 0:00:16
Enable 404 Redirect
For dynamic routes to work properly, the static frontend needs to redirect missing pages to /404.html. Add staticwebapps.config.json inside .web/_static in your project directory:
Get the deploy key from the Static Web App resource Overview tab
Run the following command inside the app directory
npx @azure/static-web-apps-cli deploy --env production --app-location .web/_static --deployment-token d1c0c7a28b86b435d5c53730fc7022bbf3e0afcdfcd1856c410ca87d6984f8b05-4970f971-091b-456f-95a7-e0ce1a98285300f231962
If successful, it should print a line like
✔ Project deployed to https://gentle-cliff-0d983f20f.5.azurestaticapps.net 🚀
Testing
Open the frontend in the browser and check that the functionality is working.
Google Sign In
Because this app uses Sign in with Google for authentication, I need to go to my Google Cloud account and enable the frontend address for this Oauth integration. Then I need to add GOOGLE_CLIENT_ID as an env var for the container, similarly to how the DB_URL was added.
Copy the Client ID in the upper right corner and add it as an Environment Variable.
Click Save. Click Create.
Check Again
Once the new replica/revision is deployed, open the frontend URL again and check that the app is functional.
Done
At this point, the app is deployed on Azure with persistent database and uploaded files. The number of backend replicas may be scaled up as traffic to the app increases.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
In this walkthrough, I will deploy the app rx_shout to Azure, using an Azure Container App to host the backend and an Azure Static Web App to host the frontend.
We will go step by step.
Prerequisites
Dockerfile
fromdocker-examples/production-app-platform
into the project root.Workaround no per-message-deflate
Azure Container App load balancers do not support per-message-deflate on the websocket, so we have to update the
rxconfig.py
to disable this feature.Publish Container
In your app directory, build a docker container image and publish it to the registry of your choice.
I had to specify the
--platform linux/amd64
otherwise my Mac will build an arm image, which will not run in Azure Container App.Resources
Resource Group
In Azure portal, create a new Resource Group that will hold all objects related to this app deployment.
Virtual Network
In Azure portal, create a new Virtual Network that will link the redis cache, app containers, and database.
On the IP Addresses tab, create a 10.0.0.0/16 network with 2 subnets, default and database.
Redis
In a multi-container deployment, it is essential to use redis so the same user retains their state when moving between application instances. Azure does provide managed redis clusters, which may provide better performance and reliability, at a significant cost.
In this deployment, I will go with the low cost option of running the
redis
container as a Container Instances resource type.Flip over to the Networking tab and assign it to the default subnet of the vnet we previously created. Ensure the redis port, 6379, is allowed.
After the container is created, take note of the private IP address it was assigned:
Database
We will use the Azure Database for PostgreSQL resource type to easily deploy the database. For this example, I'm using "development mode" because it's much cheaper. Adjust accordingly for heavier workloads.
Set the database superuser name and password and retain this information for later.
On the Networking tab, select Private Access and assign the server to the existing vnet and database subnet that were created earlier.
After the resource is created, create a new database for the app, called
rx_shout
.With the new database created, we can formulate the
DB_URL
which should be passed to the appFile Storage
Containers are ephemeral and cannot store persistent data. Since this app accepts user uploads, it needs a place to save them.
We will create a new Storage Account resource to store our app's files. Ensure that the storage account is created in the same resource group created earlier.
Flip over to the Networking tab. Select "Enable public access from selected virtual networks and IP addresses".
After the resource is created, add a new File Share that will store the uploaded files from the app.
While we're here, open the Access Keys page and copy down the access key for this storage account.
Container App
Now it's time to create the Azure Container App, and link it up with the redis, database, and storage that we just created.
Select the resource group that we created earlier, and choose the appropriate Region.
Important: Under Container Apps Environment, click "Create New" to customize the environment. This is needed to link up the container with the vnet that we created earlier.
In the new Container Apps Environment, flip over to the Networking tab. Select Yes to use your own virtual network and select the vnet1 that we created earlier.
For Infrastructure Subnet select Create New.
Create a new /24 subnet in the existing address space. I'm calling this one
container-env
.If you already created a "container-env" subnet earlier, just create a new one now.
Save the Subnet and create the Container Apps Environment.
On the Container Apps, select the Container tab. Uncheck "Use quickstart image". Enter the details of the container that was previously uploaded to the registry.
At the bottom of this tab, enter the Environment Variables that were noted earlier.
We will enter the db url later as a secret.
On the Ingress tab, enable Ingress. Accept traffic from anywhere. Ignore Client Certificate. Set target port to 8000 (Reflex default backend), and enable Session affinity.
Linkages
Now that the Container App and Environment are created, we need to make a few tweaks to the other resources to enable communications.
Go back to the resource group, open the Storage account resource, and open the Networking panel. Select "Add Existing Virtual Network" and select the vnet and newly created container-env subnet. Click Enable. Then click Add. Then click Save again after the virtual network modal closes.
Go back to the resource group, open the Container Apps Environment resource, and open the Azure Files panel. Click Add. Enter a name for the volume, the name of the Storage account (why is this not a dropdown??), the Storage Key that we copied earlier, and the name of the share that we created earlier.
Ensure Access mode is set to Read/Write
Go back to the resource group, open the Container App resource, and open the Secrets panel and add a new secret for
db-url
Open the Volumes tab. Click Add. Enter the Azure Files information that we added earlier. Click Add, then Save as a New Revision.
Open the Containers tab and click Edit and Deploy.
Click the name of the container in the bottom half of the page.
Scroll down to the environment variables and add DB_URL referencing the secret that we created earlier.
Switch over to the Volume mounts tab. Select the Volume created earlier. Set Mount path to
/app/uploaded_files
Click Save. Click Create.
It will take a moment to deploy. When the replica is reported as "Running", we can check the backend status.
Open the Overview panel, copy the application URL and add
/ping
to the end. The browser should display"pong"
Take note of the application URL as this will need to be passed as
API_URL
when exporting the frontend.Frontend
Create a new Static Web App resource type.
For this deployment, I have chosen "Other" as the source, because I will be pushing the static files manually using the
@azure/static-web-apps-cli
utility.Export
Back to the app directory on your development machine, run the following command to create the static files for export.
Enable 404 Redirect
For dynamic routes to work properly, the static frontend needs to redirect missing pages to
/404.html
. Addstaticwebapps.config.json
inside.web/_static
in your project directory:Upload To Azure
Get the deploy key from the Static Web App resource Overview tab
Run the following command inside the app directory
If successful, it should print a line like
Testing
Open the frontend in the browser and check that the functionality is working.
Google Sign In
Because this app uses Sign in with Google for authentication, I need to go to my Google Cloud account and enable the frontend address for this Oauth integration. Then I need to add
GOOGLE_CLIENT_ID
as an env var for the container, similarly to how theDB_URL
was added.Copy the Client ID in the upper right corner and add it as an Environment Variable.
Click Save. Click Create.
Check Again
Once the new replica/revision is deployed, open the frontend URL again and check that the app is functional.
Done
At this point, the app is deployed on Azure with persistent database and uploaded files. The number of backend replicas may be scaled up as traffic to the app increases.
Beta Was this translation helpful? Give feedback.
All reactions