ACA Web 发布 是做什么的?
使用此技能部署私有静态内容到 Azure,同时不公开暴露 Blob 存储。默认模式如下:
- 静态内容上传到私有 Azure Blob 存储,并设置为 Cold 层。
- 一个轻量级 Docker 镜像在 Azure 容器应用(ACA)中运行。
- 该容器实现应用级身份验证,并通过 ACA 流式传输 Blob 内容。
- ACA 使用系统分配的托管身份,并授予
Storage Blob Data Reader角色。 - 浏览器用户永远不会获得 Blob 密钥、SAS URL、直接 Blob URL 或存储帐户密钥。
- 不启用 ACA Easy Auth。
强制交互模式
除非用户已明确提供所有选择,否则在实施前请使用 ask_user 工具。请收集以下信息:
| 决策 | 推荐默认值 |
|---|---|
| 身份提供商 | GitHub |
| 允许的用户 | 无默认值;如果为空,则无人可登录 |
| 注册表模式 | 如果仓库支持发布公共包,使用 GHCR 公共镜像;如果解决方案必须私有/自包含,则使用 ACR |
| 自定义 DNS | 如果用户已有 Azure DNS 区域,优先使用自定义 DNS |
| 内容目录 | 询问本地路径 |
| Azure 资源名称 | 生成安全的默认值,但在修改现有基础结构前需先询问用户 |
在询问任何 OAuth 客户端 ID 或密钥之前,首先确定最终公共主机名是否已知:
- 使用自定义 DNS 时,先询问主机名和 DNS 区域。然后,在收集客户端 ID/密钥之前,向用户提供提供商门户链接和该自定义主机名对应的确切重定向 URL。
- 使用 ACA 内置主机名时,暂时不要询问 OAuth 客户端 ID/密钥,因为 ACA 创建前主机名未知。首先创建一个引导用 ACA 端点,捕获其
https://<app>.<region>.azurecontainerapps.ioURL,然后再向用户提供提供商门户链接和确切重定向 URL,并收集客户端 ID/密钥。
切勿要求用户使用占位符 URL 创建 OAuth 应用。使用 ask_user 收集客户端 ID/密钥;切勿在最终回复中回显密钥,也切勿提交它们。
关键默认值
- 身份提供商默认为
github。 - 支持的身份提供商:
github,google,entra,none。 none仅用于明确公开或内部测试部署。- 如果启用身份认证且未配置允许的用户,则拒绝所有用户。
- 使用逗号分隔的允许用户列表:
- GitHub:用户名,例如
tkubica12,octocat。 - Google:电子邮件地址。
- Entra:对象 ID 或 UPN/电子邮件地址,具体取决于实现。
- GitHub:用户名,例如
- 对于 GitHub,可以使用可选的电子邮件允许列表作为深度防御,但用户名是主要的 GitHub 身份标识。
- 存储帐户必须保持
publicNetworkAccess=Enabled,除非 ACA 具有连接到 Blob 的 VNet/私有端点路由。保持allowBlobPublicAccess=false和allowSharedKeyAccess=false。 - ACA 应保持小型:从
0.25核心和0.5Gi内存开始。 - ACA 应缩放到零,当活跃的 ACA/KEDA CLI 接口支持时,设置 60 分钟冷却/空闲行为;否则,设置最小副本
0并记录此限制。
注册表选项
GHCR 模式
当镜像仅包含代理/身份验证代码且无内容时,使用 GHCR。镜像/包必须公开,以便 ACA 无需凭据即可拉取。从 assets/publish-web-image.yml 创建 GitHub Actions 工作流以构建并推送镜像。
ACR 模式
当用户希望获得完全私有且自包含的 Azure 解决方案时,使用 ACR。创建 ACR,在其中构建或推送镜像,并授予 ACA 托管身份 AcrPull 角色。
对于 ACR,在配置好 AcrPull 之前,避免直接从私有镜像创建 ACA。首先使用公共引导镜像和系统分配的托管身份创建应用,授予该身份 AcrPull 角色,使用 --identity system 配置注册表,然后将应用更新为使用 ACR 镜像。
从 Windows 终端使用 az acr build 时,请使用 --no-logs 参数以避免 Azure CLI 日志流式处理 Unicode/控制台编码失败;改为查询构建结果。
OAuth 主机名时机
OAuth 应用注册必须使用最终浏览器可见的主机作为主页/来源和回调 URL。
自定义 DNS 流程
- 询问自定义主机名和 DNS 区域。
- 显示提供商注册链接和确切 URL,例如
https://site.example.com和https://site.example.com/oauth/github/callback。 - 收集客户端 ID 和密钥。
- 部署 ACA、DNS、身份验证设置、内容和证书绑定。
ACA 内置主机名流程
- 首先部署引导用 ACA 端点以发现内置主机名。使用带有
-BootstrapOnly参数的部署脚本,或手动创建 ACA/容器应用外壳。 - 使用发现的主机名显示提供商注册链接和确切 URL,例如
https://<fqdn>和https://<fqdn>/oauth/github/callback。 - 收集客户端 ID 和密钥。
- 通过应用身份验证设置、上传内容并(如果应用是引导创建的)切换到代理镜像,完成部署。
需要复制或适配的文件
请使用以下资产作为实施起点:
assets/blob_proxy_app.py:带有 Blob 代理和提供商切换功能的 FastAPI 应用。assets/requirements.txt:Python 运行时依赖项。assets/Dockerfile:适用于 ACA 的最小镜像。assets/deploy-aca-web.ps1:有见解的 Azure 部署脚本。assets/publish-web-image.yml:用于 GHCR 发布的 GitHub Actions 工作流。
在需要时阅读以下参考文件:
references/architecture.md:架构、存储规则和扩展说明。references/auth.md:OAuth 注册步骤和环境变量。references/day-2.md:添加用户、轮换密钥、上传内容和故障排除。
实施检查清单
- 确认内容目录和生成的站点入口点。
- 选择自定义 DNS 或 ACA 内置主机名。
- 选择身份提供商。
- 如果主机名已知,向用户提供特定于提供商的应用注册链接和确切回调 URL;如果使用 ACA 内置主机名,先引导 ACA,然后提供这些 URL。
- 收集应用注册值。
- 收集允许的用户列表。
- 选择 GHCR 或 ACR。
- 将示例应用和 Dockerfile 复制/适配到目标仓库。
- 如果使用 GHCR 模式,添加工作流并使生成的包公开。
- 部署 ACA、私有 Blob 存储、RBAC、密钥、环境变量和可选的 DNS。
- 上传内容到 Blob 并设置为 Cold 层。
- 冒烟测试:
- 未经身份验证的请求会重定向到提供商的登录页面(除非
AUTH_PROVIDER=none); - 允许的用户可以加载
index.html; - 不允许的用户收到
403; - 媒体范围请求返回
206 Partial Content; - 直接匿名访问 Blob 失败。
- 未经身份验证的请求会重定向到提供商的登录页面(除非
第 2 天任务处理
对于“添加用户”,仅更新 ALLOWED_USERS 或特定于提供商的允许列表环境变量,然后重启/更新 ACA。
对于“上传新内容”,重新生成本地静态输出,运行 Blob 同步(仅当本地输出具有权威性时才启用删除),然后设置为 Cold 层。
对于大型站点或大量文件,优先使用 AzCopy。如果 AzCopy 不可用且站点较小,Azure CLI 的 az storage blob upload-batch --auth-mode login 是可接受的备用方案;对于大型站点,请先安装 AzCopy 或使用带 -InstallAzCopy 参数的部署脚本。
对于“切换身份提供商”,首先创建新的提供商注册,设置密钥/环境变量,验证登录,然后删除旧的提供商密钥。
对于“从 GHCR 迁移到 ACR”,部署 ACR,授予 AcrPull 角色,更新镜像引用,并保持 Blob 内容不变。