Publishing to Azure as an Azure Web App¶
This page describes how to publish Rundata-net to Azure as a Linux
Azure Web App (App Service). It covers forking the repository on
GitHub, wiring up a GitHub Actions workflow for continuous
deployment, and configuring the environment variables expected by
the Django production settings.
Prerequisites¶
An Azure subscription with permissions to create resource groups, App Service plans and Web Apps.
A GitHub account that will host your fork of Rundata-net.
A PostgreSQL database reachable from the Web App. In production Rundata-net runs against Azure Database for PostgreSQL Flexible Server, but any PostgreSQL instance accepted by
dj-database-urlworks.Optionally, an Application Insights resource for monitoring.
1. Fork the repository on GitHub¶
Open https://github.com/ and sign in.
Navigate to the upstream Rundata-net repository and click Fork to create a copy under your own account or organization.
Clone your fork locally if you want to make changes before the first deployment:
$ git clone https://github.com/<your-account>/rundata-net.git $ cd rundata-net
All deployments to Azure will be triggered from pushes to this fork, so make sure it is the repository you configure below.
2. Create the Azure Web App¶
Create a Linux App Service running Python 3.12. Reproduce the following configuration through the Azure Portal, the Azure CLI, or Infrastructure-as-Code of your choice:
Kind: Linux Web App (
app,linux).Runtime stack:
PYTHON|3.12.App Service plan: a Linux plan sized for your workload.
HTTPS Only: enabled.
Minimum TLS version:
1.2; disable FTP/FTPS.VNet integration (optional): attach the Web App to a subnet if you need private connectivity to PostgreSQL or other backend resources.
Custom domains: bind your apex domain and
wwwsubdomain (for exampleexample.comandwww.example.com) with SNI SSL certificates.
Example using the Azure CLI:
$ az group create --name <rg> --location <region>
$ az appservice plan create \
--name <plan-name> \
--resource-group <rg> \
--is-linux --sku B1
$ az webapp create \
--name <your-app-name> \
--resource-group <rg> \
--plan <plan-name> \
--runtime "PYTHON:3.12"
3. Configure GitHub Actions for deployment¶
The recommended deployment method is the built-in Deployment Center → GitHub Actions integration of App Service:
In the Azure Portal, open your Web App.
Go to Deployment Center.
Choose GitHub as the source and authorize Azure to access your fork.
Select the organization, repository (your fork) and branch (typically
main).For the build provider, choose GitHub Actions and pick the Python 3.12 runtime stack.
Click Save.
Azure will:
commit a workflow file under
.github/workflows/in your fork that builds the project and deploys it with theazure/webapps-deployaction;add a publish profile (or a federated OIDC credential) as a GitHub Actions secret used by the workflow.
From that point on, every push to the configured branch triggers a new build and deploy.
If you prefer to manage the workflow yourself, copy the generated
file into your fork and keep it under version control. A minimal
workflow installs Python 3.12, installs
requirements/production.txt, collects static files and deploys:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements/production.txt
- run: python manage.py collectstatic --noinput
env:
DJANGO_SETTINGS_MODULE: config.settings.production
DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }}
- uses: azure/webapps-deploy@v3
with:
app-name: <your-app-name>
publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE }}
4. Configure environment variables on Azure¶
Rundata-net uses django-environ to read configuration from the
process environment. On Azure, set these values under
Configuration → Application settings of the Web App (or via
az webapp config appsettings set). They are injected as
environment variables at runtime.
Required¶
DJANGO_SETTINGS_MODULEMust be
config.settings.production.DJANGO_SECRET_KEYA long random string used by Django for cryptographic signing.
SCM_DO_BUILD_DURING_DEPLOYMENTSet to
1so Oryx installs Python dependencies during deployment.CUSTOM_REQUIREMENTSTXT_PATHSet to
requirements/production.txtto have the App Service Oryx build step install the production dependencies during deployment.POST_BUILD_COMMANDSet to
python manage.py migrateto have the App Service Oryx build step run database migrations after deployment.
Database¶
Either provide an Azure PostgreSQL connection string (preferred when using the Azure PostgreSQL + App Service integration) or a generic database URL:
AZURE_POSTGRESQL_CONNECTIONSTRINGlibpq keyword/value string, for example
dbname=rundata host=<server>.postgres.database.azure.com user=<user> password=<password>. When this variable is set, it takes precedence overDATABASE_URL.DATABASE_URLFallback in the form
postgres://<user>:<password>@<host>:5432/<dbname>.CONN_MAX_AGEOptional, defaults to
60seconds.
Hostnames and HTTPS¶
WEBSITE_HOSTNAMEAutomatically provided by App Service (for example
<your-app-name>.azurewebsites.net). No action required; the production settings read it to populateALLOWED_HOSTSandCSRF_TRUSTED_ORIGINS.CANONICAL_DOMAINApex domain used for 301 redirects from
wwwand the*.azurewebsites.nethostname. Defaults torundata.info; override it when deploying your own fork (for exampleexample.com).DJANGO_ALLOWED_HOSTSComma-separated list of additional hostnames to allow.
DJANGO_SECURE_SSL_REDIRECTDefaults to
true. Keep it enabled once a valid certificate is bound to your custom domain.DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINSOptional override; defaults to
true.DJANGO_SECURE_HSTS_PRELOADOptional override; defaults to
true.DJANGO_SECURE_CONTENT_TYPE_NOSNIFFOptional override; defaults to
true.
Optional integrations¶
AZURE_BLOB_BASE_URLSet to
https://files.rundata.info/sveriges_runinskrifter. This is the public URL of the Azure Blob Storage container that serves runic inscription images. In the future, you can set up your own container and provide its URL here.MODEL_KEYSet to a non-empty value to enable the AI features. This is Azure Foundry API.
APPLICATIONINSIGHTS_CONNECTION_STRINGEnable Application Insights telemetry when set.
USE_GASet to
trueto enable Google Analytics tracking in the frontend.
5. First deployment checklist¶
Verify the Web App starts under
PYTHON|3.12(Log stream → Log stream in the portal).If your
POST_BUILD_COMMANDalready runspython manage.py migrate, do not run migrations manually again. Use SSH from the Kudu console forcollectstatic(and only runmigratemanually if you did not configure it inPOST_BUILD_COMMAND):$ python manage.py collectstatic --noinput $ python manage.py migrate # only if POST_BUILD_COMMAND does not run it
Open
https://<your-app-name>.azurewebsites.netand confirm the site responds.Configure your custom domain and TLS binding, then set
CANONICAL_DOMAINaccordingly so thewwwandazurewebsites.nethostnames redirect to the apex domain.
See also
Installation for a generic installation guide.
Development with Docker for running the project locally in containers before deploying.