本文介绍如何部署使用mssql-django后端Azure 应用服务的 Django 应用程序,包括 ODBC 驱动程序配置、基于环境的机密和托管标识身份验证。
先决条件
- Azure 订阅服务
- 可从Azure访问的Azure SQL 数据库或SQL Server实例
- 一个配置了
mssql-django的 Django 项目 - 已安装 Azure CLI
Azure 应用服务上的 ODBC 驱动程序
Azure 应用服务 Linux 实例包括 Microsoft ODBC Driver for SQL Server。 可以通过运行以下命令来验证已安装的驱动程序版本:
az webapp ssh --resource-group <your-rg> --name <your-app>
odbcinst -j
Note
Azure 应用服务通常包括 LINUX 计划中预安装的 ODBC 驱动程序 17 和/或 18。 Windows 应用服务计划还包括 ODBC 驱动程序。
使用环境变量存储敏感信息
不要在settings.py中硬编码数据库凭据。 使用环境变量并将其配置为应用服务应用程序设置:
import os
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": os.environ.get("DB_NAME", "<your-database>"),
"USER": os.environ.get("DB_USER", ""),
"PASSWORD": os.environ.get("DB_PASSWORD", ""),
"HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
"PORT": os.environ.get("DB_PORT", "1433"),
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
},
},
}
Tip
对于像 DB_NAME 和 DB_HOST 这样的必需值,建议考虑使用 os.environ["DB_NAME"](即不提供默认值),这样一来,如果缺少环境变量,应用程序会立即失败,并显示清晰的 KeyError。
在Azure 应用服务中设置环境变量:
az webapp config appsettings set \
--resource-group <your-rg> \
--name <your-app> \
--settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net DB_USER=<your-username> DB_PASSWORD=<your-password>
使用托管标识身份验证
对于生产部署,请使用托管标识来避免存储凭据。 在应用服务上启用系统分配的托管标识:
az webapp identity assign --resource-group <your-rg> --name <your-app>
授予托管标识对 Azure SQL 数据库的访问权限:
CREATE USER [<your-app-name>] FOR EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [<your-app-name>];
ALTER ROLE db_datawriter ADD MEMBER [<your-app-name>];
ALTER ROLE db_ddladmin ADD MEMBER [<your-app-name>];
Note
仅授予应用程序所需的角色。 仅当应用程序运行迁移时,才需要 db_ddladmin 固定数据库角色。 对于只读工作负荷, db_datareader 已足够。
如果您的服务器配置为仅限 Microsoft Entra 的身份验证,则 FROM EXTERNAL PROVIDER 会因 Msg 33130 而失败,因为服务器无法访问 Microsoft Graph 来解析该标识名称。 使用 CREATE USER [<your-app-name>] WITH SID = 0x<sid-hex>, TYPE = E 手动创建用户,其中 <sid-hex> 派生自托管标识 的应用程序(客户端)ID,而不是其对象 ID。 有关转换步骤,请参阅Azure SQL中授予标识访问权限。
将 settings.py 配置为使用托管标识:
import os
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": os.environ.get("DB_NAME", "<your-database>"),
"HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
"PORT": "1433",
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"extra_params": "Authentication=ActiveDirectoryMsi",
},
},
}
将访问令牌与 ManagedIdentityCredential 配合使用
或者,配合 azure.identity 使用 TOKEN 设置:
注意
该值 TOKEN 在进程启动时提取一次,并在 60-90 分钟后过期。 对于运行时间较长的 App Service 部署,仅当你还实现了令牌刷新逻辑或短生命周期工作进程回收时,才使用此方法。 如果直接使用 ActiveDirectoryMsi 模式在您的环境中可行,就可以避免启动时的令牌问题。
import os
from azure.identity import ManagedIdentityCredential
credential = ManagedIdentityCredential()
token = credential.get_token("https://database.windows.net/.default").token
DATABASES = {
"default": {
"ENGINE": "mssql",
"NAME": os.environ.get("DB_NAME", "<your-database>"),
"HOST": os.environ.get("DB_HOST", "<your-server>.database.windows.net"),
"PORT": "1433",
"TOKEN": token,
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
},
},
}
Tip
DefaultAzureCredential对于开发和共享代码库来说很方便,因为它会自动尝试多个凭据类型,因此相同的代码适用于笔记本电脑、CI 和 Azure。 但是,不应用的每个凭据类型都会增加几秒钟的超时时间,这会减慢启动速度。 由于应用服务始终提供可用的托管标识,ManagedIdentityCredential 无需经过探测链即可立即完成身份验证。 在要求文件中安装 azure-identity : pip install azure-identity。
在部署期间执行迁移
添加部署后脚本或启动命令以自动运行迁移:
az webapp config set \
--resource-group <your-rg> \
--name <your-app> \
--startup-file "python manage.py migrate && gunicorn myproject.wsgi"
收集静态文件
为生产配置静态文件处理:
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
在部署过程中运行 collectstatic:
python manage.py collectstatic --noinput
部署到应用服务
应用服务可以通过两种方式托管 Django 应用:
- 内置 Linux Python映像:应用服务从源代码生成代码,并提供Python运行时。
- 自定义 Docker 映像:自行生成映像,并从容器注册表引用该映像。
这两个路径都可以使用系统分配的托管标识对Azure SQL进行身份验证,但方案有所不同。 选择与部署匹配的选项卡。
使用内置的 Linux Python 镜像,App Service 的 Oryx 生成器会自动安装 requirements.txt,并在 gunicorn 下启动你的 Django 应用。 本地托管身份 HTTP 代理使 Authentication=ActiveDirectoryMsi 可直接在 ODBC 连接字符串中使用。 使用使用托管标识身份验证中所示的settings.py。
使用 az webapp up、启用系统分配的托管标识部署代码,并设置数据库环境变量:
az webapp up \
--resource-group <your-rg> \
--name <your-app> \
--runtime "PYTHON:3.12" \
--sku B1
az webapp identity assign --resource-group <your-rg> --name <your-app>
az webapp config appsettings set \
--resource-group <your-rg> \
--name <your-app> \
--settings DB_NAME=<your-database> DB_HOST=<your-server>.database.windows.net
然后,如 使用托管标识身份验证中所述,在 SQL 中授予托管标识访问权限。
使用 Docker Compose 进行本地开发
对于本地开发和测试,请使用 Docker Compose 与 SQL Server 容器一起运行 Django 应用:
# docker-compose.yml
services:
db:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "<password>" # Must meet SQL Server complexity requirements
ports:
- "1433:1433"
web:
build: .
ports:
- "8000:8000"
environment:
DB_HOST: db
DB_NAME: mydb
DB_USER: sa
DB_PASSWORD: "<password>"
depends_on:
- db
Tip
SQL Server容器不会自动创建应用程序数据库。 启动容器后,创建数据库并运行迁移:
docker compose exec db /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "<password>" -No -Q "CREATE DATABASE mydb"
docker compose exec web python manage.py migrate
SQL Server 容器镜像需要 ACCEPT_EULA=Y 和高强度的 SA 密码。 对于生产环境,请使用 Azure SQL 数据库,并使用托管标识而不是 SQL Server 凭据。 请参阅 使用托管标识进行身份验证。