cloudflare
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCloudflare
Cloudflare
Workers 배포와 시크릿
Workers 部署与 Secret
DaleStudy는 오픈소스 커뮤니티라 모든 기여자에게 Cloudflare 접근 권한을 줄 수 없다. 그래서 배포와 시크릿을 GitHub 쪽에 모은다. 빌드 로그는 누구나 Actions에서 볼 수 있고, 시크릿은 GitHub secret 한 곳에서 관리한다.
DaleStudy 是一个开源社区,因此无法向所有贡献者授予 Cloudflare 访问权限。因此,我们将部署和 Secret 集中在 GitHub 侧。任何人都可以在 Actions 中查看构建日志,而 Secret 则统一在 GitHub secret 中管理。
규칙
规则
- 배포는 GitHub Actions로만 한다. 으로 배포하고, Cloudflare 대시보드의 Workers Builds(Git 연결)는 쓰지 않는다. 둘을 함께 켜면 한 번 머지에 두 번 배포된다.
cloudflare/wrangler-action - 시크릿의 원본은 GitHub secret이다. 여러 저장소가 쓰는 값은 조직 secret, 한 저장소만 쓰는 값은 저장소 secret에 둔다. 배포 워크플로우가 Worker에 넣는다.
- Worker secret을 직접 바꾸지 않는다. 이나 대시보드로 넣은 값은 같은 이름이면 다음 배포 때 GitHub 값으로 덮이고, 다른 이름이면 GitHub에 기록 없이 Worker에만 남는다.
wrangler secret put - 공개해도 되는 값은 의
wrangler.jsonc에 둔다. App ID, Client ID, 공개 URL 같은 값이다. 같은 이름을 vars와 secret에 함께 두지 않는다.vars - 로컬 개발 값은 에 둔다. 커밋하지 않는다.
.dev.vars
- 部署只能通过 GitHub Actions 进行。 使用 进行部署,不使用 Cloudflare 控制台中的 Workers Builds(Git 集成)。如果同时启用两者,一次 merge 就会导致两次部署。
cloudflare/wrangler-action - Secret 的唯一来源是 GitHub secret。 多个仓库共用的值存放在组织 secret 中,仅由单个仓库使用的值存放在仓库 secret 中。部署工作流会将它们注入 Worker。
- 不要直接修改 Worker secret。 通过 或控制台设置的值,如果在下次部署时名称相同,就会被 GitHub 中的值覆盖;如果名称不同,则只会保留在 Worker 中,并且不会记录在 GitHub 中。
wrangler secret put - 可以公开的值放在 的
wrangler.jsonc中。 例如 App ID、Client ID、公开 URL 等值。不要在 vars 和 secret 中使用相同名称。vars - 本地开发值放在 中。 不要提交到版本库。
.dev.vars
시크릿 추가 절차
添加 Secret 的流程
새 시크릿 가 필요하면:
FOO_API_KEY- 조직에서 이미 쓰는 값인지 먼저 확인한다:
gh secret list --org DaleStudy - 없으면 운영진에게 GitHub secret 등록을 요청한다. 직접 권한이 있다면 또는
gh secret set FOO_API_KEY --org DaleStudy --repos <repo>--repo DaleStudy/<repo> - 의
wrangler.jsonc에 이름을 추가한다 (쓰는 저장소만)secrets.required - 에서 Worker로 넘기는 목록에 추가한다
deploy.yml
需要新 Secret 时:
FOO_API_KEY- 首先确认组织中是否已经使用该值:
gh secret list --org DaleStudy - 如果尚未使用,请请求维护人员注册 GitHub secret。如果拥有相应权限,可以直接执行 或
gh secret set FOO_API_KEY --org DaleStudy --repos <repo>--repo DaleStudy/<repo> - 将名称添加到 的
wrangler.jsonc中(仅限使用它的仓库)secrets.required - 将其添加到 中传递给 Worker 的列表
deploy.yml
배포 워크플로우
部署工作流
yaml
undefinedyaml
undefined.github/workflows/deploy.yml
.github/workflows/deploy.yml
name: Deploy 🚀
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v{N}
- uses: oven-sh/setup-bun@v{N}
- run: bun install --frozen-lockfile
- run: bun run build
- name: Deploy
uses: cloudflare/wrangler-action@v{N}
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
packageManager: bun
secrets: |
FOO_API_KEY
env:
FOO_API_KEY: ${{ secrets.FOO_API_KEY }}
- `CLOUDFLARE_API_TOKEN`은 조직 secret이다. 저장소마다 새 토큰을 만들지 않는다.
- 시크릿이 없는 Worker는 `secrets`와 `env`를 뺀다.
- 액션 버전은 `github-actions` 스킬대로 최신 메이저를 확인해 쓴다.name: Deploy 🚀
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v{N}
- uses: oven-sh/setup-bun@v{N}
- run: bun install --frozen-lockfile
- run: bun run build
- name: Deploy
uses: cloudflare/wrangler-action@v{N}
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
packageManager: bun
secrets: |
FOO_API_KEY
env:
FOO_API_KEY: ${{ secrets.FOO_API_KEY }}
- `CLOUDFLARE_API_TOKEN` 是组织 secret。不要为每个仓库创建新的 token。
- 如果 Worker 不使用 Secret,请移除 `secrets` 和 `env`。
- 按照 `github-actions` skill 的说明确认并使用最新 major 版本的 Action。PR 미리보기
PR 预览
조직 공유 워크플로우를 부른다. PR마다 Workers Previews()로 미리보기를 띄우고 PR에 주소를 댓글로 남기며, PR이 닫히면 지운다.
wrangler preview --name pr-<번호>yaml
undefined调用组织共享工作流。为每个 PR 使用 Workers Previews()启动预览,并通过评论在 PR 中留下预览地址;PR 关闭后将其删除。
wrangler preview --name pr-<번호>yaml
undefined.github/workflows/preview.yml
.github/workflows/preview.yml
name: Preview 🔍
on:
pull_request:
types: [opened, synchronize, reopened, closed]
concurrency:
group: preview-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
preview:
# 포크 PR에는 secret이 전달되지 않으므로 같은 저장소의 PR만 미리보기를 만든다
if: >
github.event.pull_request.head.repo.full_name == github.repository &&
github.actor != 'dependabot[bot]'
permissions:
contents: read
pull-requests: write
uses: DaleStudy/.github/.github/workflows/workers-preview.yml@main
secrets:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
미리보기는 운영 설정을 상속하지 않는다. `wrangler.jsonc`에 `previews` 블록을 두고, 미리보기에 필요한 `vars`와 바인딩을 다시 적는다. 필요한 게 없으면 빈 블록(`"previews": {}`)을 둔다. 운영 D1을 미리보기와 같이 써도 되면 같은 데이터베이스를 바인딩하고, 분리해야 하면 미리보기용 D1을 따로 둔다 ([feedback](https://github.com/DaleStudy/feedback/blob/main/.github/workflows/preview.yml) 참고). 미리보기에는 운영 시크릿도 들어가지 않는다. 미리보기에 시크릿이 필요하면 공유 워크플로우 대신 `wrangler preview --secrets-file`로 넣는다 (feedback 참고). Workers Previews는 wrangler 4.135.0 이상이 필요하다.
`versions upload`로 미리보기를 만들지 않는다. 운영 Worker에 배포되지 않은 버전이 쌓여, `secrets:` 입력으로 배포할 때 `code 10214`로 실패한다.
웹훅·봇 서버처럼 미리보기로 확인할 화면이 없는 Worker는 미리보기를 두지 않는다.name: Preview 🔍
on:
pull_request:
types: [opened, synchronize, reopened, closed]
concurrency:
group: preview-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
preview:
# 포크 PR에는 secret이 전달되지 않으므로 같은 저장소의 PR만 미리보기를 만든다
if: >
github.event.pull_request.head.repo.full_name == github.repository &&
github.actor != 'dependabot[bot]'
permissions:
contents: read
pull-requests: write
uses: DaleStudy/.github/.github/workflows/workers-preview.yml@main
secrets:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
预览不会继承生产配置。在 `wrangler.jsonc` 中设置 `previews` 块,并重新声明预览所需的 `vars` 和绑定。如果不需要任何配置,则保留空块(`"previews": {}`)。如果预览可以使用生产 D1,则绑定同一个数据库;如果需要隔离,则为预览单独配置 D1(参考 [feedback](https://github.com/DaleStudy/feedback/blob/main/.github/workflows/preview.yml))。生产 Secret 也不会传入预览。如果预览需要 Secret,请使用 `wrangler preview --secrets-file` 注入,而不是使用共享工作流(参考 feedback)。Workers Previews 要求 wrangler 4.135.0 或更高版本。
不要使用 `versions upload` 创建预览。否则,未部署到生产 Worker 的版本会不断累积,之后使用 `secrets:` 输入进行部署时,会因 `code 10214` 而失败。
对于网页钩子、机器人服务器等无法通过预览确认界面的 Worker,不要创建预览。안티 패턴
反模式
bash
undefinedbash
undefined❌ Worker secret을 직접 넣기 - 다음 배포 때 덮이고, 다른 운영진은 값의 출처를 모른다
❌ Worker secret을 직접 넣기 - 다음 배포 때 덮이고, 다른 운영진은 값의 출처를 모른다
wrangler secret put FOO_API_KEY
- ❌ Cloudflare 대시보드에서 저장소를 연결해 Workers Builds 켜기
- ❌ 저장소마다 Cloudflare API 토큰 새로 만들기
- ❌ 공개 값(Client ID 등)을 secret으로 두기 - `vars`로 충분하다
> 참고: [GitHub Actions로 배포](https://developers.cloudflare.com/workers/ci-cd/external-cicd/github-actions/), [wrangler deploy](https://developers.cloudflare.com/workers/wrangler/commands/workers/#deploy)wrangler secret put FOO_API_KEY
- ❌ 在 Cloudflare 控制台中连接仓库并启用 Workers Builds
- ❌ 为每个仓库创建新的 Cloudflare API token
- ❌ 将公开值(如 Client ID)保存为 secret——使用 `vars` 即可
> 参考:[使用 GitHub Actions 部署](https://developers.cloudflare.com/workers/ci-cd/external-cicd/github-actions/)、[wrangler deploy](https://developers.cloudflare.com/workers/wrangler/commands/workers/#deploy)URL 형식 (트레일링 슬래시)
URL 格式(trailing slash)
DaleStudy 사이트의 정규 URL은 슬래시 없는 형태다 (, 도메인 루트 만 예외). API·웹훅·OAuth 콜백 경로가 모두 이 형태로 외부에 등록되어 있고, 앱 프레임워크(TanStack, React Router)도 이 형태로 링크를 만들기 때문이다.
/about/정적 파일로 서빙하는 페이지는 Cloudflare 기본값이 을 에서 서빙하므로, 설정으로 맞춘다.
about/index.html/about/| 구성 | 설정 |
|---|---|
| Workers 정적 에셋 (prerender, SPA, Astro 모두) | |
| Astro | 위 설정과 함께 |
| TanStack Start·Router, React Router (SSR) | 기본값 그대로 |
- canonical, sitemap, 내부 링크는 모두 슬래시 없는 형태로 쓴다.
- Workers 정적 에셋의 리다이렉트는 307(임시)이고 바꿀 수 없다. 리다이렉트가 일어날 일 자체를 줄이도록 링크를 정규 형태로 맞춘다.
- 확인: 로 주요 페이지를 두 형태로 요청해, 슬래시 없는 쪽만 200이고 슬래시 있는 쪽은 그쪽으로 리다이렉트되는지 본다.
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n'
DaleStudy 站点的规范 URL 采用不带 trailing slash 的形式(,仅域名根路径 例外)。API、网页钩子和 OAuth 回调路径都以外部注册为这种形式,应用框架(TanStack、React Router)也会生成这种形式的链接。
/about/对于以静态文件形式提供的页面,Cloudflare 默认会在 下提供 ,因此需要通过配置使其保持一致。
/about/about/index.html| 配置 | 设置 |
|---|---|
| Workers 静态资产(prerender、SPA、Astro 均适用) | |
| Astro | 上述设置,并在 |
| TanStack Start·Router、React Router(SSR) | 保持默认值 |
- canonical、sitemap 和内部链接全部使用不带 trailing slash 的形式。
- Workers 静态资产的重定向为 307(临时重定向),且无法更改。应将链接调整为规范形式,以尽量避免发生重定向。
- 检查:使用 分别以两种形式请求主要页面,确认只有不带 trailing slash 的形式返回 200,而带 trailing slash 的形式会重定向到不带 trailing slash 的版本。
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n'