Communitygithub.com

ACA Web 发布

该技能用于将私有静态内容部署到 Azure,而无需公开暴露 Blob 存储。

ACA Web 发布 是什么?

此 AI 代理技能(Skill)实现了一种安全发布静态网站的模式。其核心架构是:将静态内容上传至私有 Azure Blob 存储(Cold 层),并利用一个在 Azure 容器应用(ACA)中运行的轻量级 Docker 镜像作为代理。该代理实现应用级别的身份验证,并通过系统分配的托管身份(拥有 Storage Blob Data Reader 角色)来读取 Blob 内容,从而确保终端用户永远不会接触到 Blob 密钥或 SAS URL。该技能支持 GitHub、Google 和 Azure AD (Entra ID) 等多种身份提供商,可根据是否使用自定义 DNS 来动态确定回调和重定向 URL,并推荐使用 GitHub Container Registry (GHCR) 发布公共镜像或使用 Azure Container Registry (ACR) 实现完全私有化部署。它详细提供了从基础设施搭建、用户管理到内容更新的完整操作指南,特别适合需要严格访问控制和私有 Azure 基础设施的生产环境。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add tkubica12/skill-aca-web-publish

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

ACA Web 发布 是做什么的?

使用此技能部署私有静态内容到 Azure,同时不公开暴露 Blob 存储。默认模式如下:

  1. 静态内容上传到私有 Azure Blob 存储,并设置为 Cold 层。
  2. 一个轻量级 Docker 镜像在 Azure 容器应用(ACA)中运行。
  3. 该容器实现应用级身份验证,并通过 ACA 流式传输 Blob 内容。
  4. ACA 使用系统分配的托管身份,并授予 Storage Blob Data Reader 角色。
  5. 浏览器用户永远不会获得 Blob 密钥、SAS URL、直接 Blob URL 或存储帐户密钥。
  6. 不启用 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.io URL,然后再向用户提供提供商门户链接和确切重定向 URL,并收集客户端 ID/密钥。

切勿要求用户使用占位符 URL 创建 OAuth 应用。使用 ask_user 收集客户端 ID/密钥;切勿在最终回复中回显密钥,也切勿提交它们。

关键默认值

  • 身份提供商默认为 github。
  • 支持的身份提供商:github, google, entra, none。
  • none 仅用于明确公开或内部测试部署。
  • 如果启用身份认证且未配置允许的用户,则拒绝所有用户。
  • 使用逗号分隔的允许用户列表:
    • GitHub:用户名,例如 tkubica12,octocat。
    • Google:电子邮件地址。
    • Entra:对象 ID 或 UPN/电子邮件地址,具体取决于实现。
  • 对于 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 流程

  1. 询问自定义主机名和 DNS 区域。
  2. 显示提供商注册链接和确切 URL,例如 https://site.example.com 和 https://site.example.com/oauth/github/callback。
  3. 收集客户端 ID 和密钥。
  4. 部署 ACA、DNS、身份验证设置、内容和证书绑定。

ACA 内置主机名流程

  1. 首先部署引导用 ACA 端点以发现内置主机名。使用带有 -BootstrapOnly 参数的部署脚本,或手动创建 ACA/容器应用外壳。
  2. 使用发现的主机名显示提供商注册链接和确切 URL,例如 https://<fqdn> 和 https://<fqdn>/oauth/github/callback。
  3. 收集客户端 ID 和密钥。
  4. 通过应用身份验证设置、上传内容并(如果应用是引导创建的)切换到代理镜像,完成部署。

需要复制或适配的文件

请使用以下资产作为实施起点:

  • 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:添加用户、轮换密钥、上传内容和故障排除。

实施检查清单

  1. 确认内容目录和生成的站点入口点。
  2. 选择自定义 DNS 或 ACA 内置主机名。
  3. 选择身份提供商。
  4. 如果主机名已知,向用户提供特定于提供商的应用注册链接和确切回调 URL;如果使用 ACA 内置主机名,先引导 ACA,然后提供这些 URL。
  5. 收集应用注册值。
  6. 收集允许的用户列表。
  7. 选择 GHCR 或 ACR。
  8. 将示例应用和 Dockerfile 复制/适配到目标仓库。
  9. 如果使用 GHCR 模式,添加工作流并使生成的包公开。
  10. 部署 ACA、私有 Blob 存储、RBAC、密钥、环境变量和可选的 DNS。
  11. 上传内容到 Blob 并设置为 Cold 层。
  12. 冒烟测试:
    • 未经身份验证的请求会重定向到提供商的登录页面(除非 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 内容不变。

相关技能