cloudflare

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Cloudflare

Cloudflare

Workers 배포와 시크릿

Workers 部署与 Secret

DaleStudy는 오픈소스 커뮤니티라 모든 기여자에게 Cloudflare 접근 권한을 줄 수 없다. 그래서 배포와 시크릿을 GitHub 쪽에 모은다. 빌드 로그는 누구나 Actions에서 볼 수 있고, 시크릿은 GitHub secret 한 곳에서 관리한다.
DaleStudy 是一个开源社区,因此无法向所有贡献者授予 Cloudflare 访问权限。因此,我们将部署和 Secret 集中在 GitHub 侧。任何人都可以在 Actions 中查看构建日志,而 Secret 则统一在 GitHub secret 中管理。

규칙

规则

  1. 배포는 GitHub Actions로만 한다.
    cloudflare/wrangler-action
    으로 배포하고, Cloudflare 대시보드의 Workers Builds(Git 연결)는 쓰지 않는다. 둘을 함께 켜면 한 번 머지에 두 번 배포된다.
  2. 시크릿의 원본은 GitHub secret이다. 여러 저장소가 쓰는 값은 조직 secret, 한 저장소만 쓰는 값은 저장소 secret에 둔다. 배포 워크플로우가 Worker에 넣는다.
  3. Worker secret을 직접 바꾸지 않는다.
    wrangler secret put
    이나 대시보드로 넣은 값은 같은 이름이면 다음 배포 때 GitHub 값으로 덮이고, 다른 이름이면 GitHub에 기록 없이 Worker에만 남는다.
  4. 공개해도 되는 값은
    wrangler.jsonc
    의
    vars
    에 둔다.
    App ID, Client ID, 공개 URL 같은 값이다. 같은 이름을 vars와 secret에 함께 두지 않는다.
  5. 로컬 개발 값은
    .dev.vars
    에 둔다.
    커밋하지 않는다.
  1. 部署只能通过 GitHub Actions 进行。 使用
    cloudflare/wrangler-action
    进行部署,不使用 Cloudflare 控制台中的 Workers Builds(Git 集成)。如果同时启用两者,一次 merge 就会导致两次部署。
  2. Secret 的唯一来源是 GitHub secret。 多个仓库共用的值存放在组织 secret 中,仅由单个仓库使用的值存放在仓库 secret 中。部署工作流会将它们注入 Worker。
  3. 不要直接修改 Worker secret。 通过
    wrangler secret put
    或控制台设置的值,如果在下次部署时名称相同,就会被 GitHub 中的值覆盖;如果名称不同,则只会保留在 Worker 中,并且不会记录在 GitHub 中。
  4. 可以公开的值放在
    wrangler.jsonc
    的
    vars
    中。
    例如 App ID、Client ID、公开 URL 等值。不要在 vars 和 secret 中使用相同名称。
  5. 本地开发值放在
    .dev.vars
    中。
    不要提交到版本库。

시크릿 추가 절차

添加 Secret 的流程

새 시크릿
FOO_API_KEY
가 필요하면:
  1. 조직에서 이미 쓰는 값인지 먼저 확인한다:
    gh secret list --org DaleStudy
  2. 없으면 운영진에게 GitHub secret 등록을 요청한다. 직접 권한이 있다면
    gh secret set FOO_API_KEY --org DaleStudy --repos <repo>
    또는
    --repo DaleStudy/<repo>
  3. wrangler.jsonc
    의
    secrets.required
    에 이름을 추가한다 (쓰는 저장소만)
  4. deploy.yml
    에서 Worker로 넘기는 목록에 추가한다
需要新 Secret
FOO_API_KEY
时:
  1. 首先确认组织中是否已经使用该值:
    gh secret list --org DaleStudy
  2. 如果尚未使用,请请求维护人员注册 GitHub secret。如果拥有相应权限,可以直接执行
    gh secret set FOO_API_KEY --org DaleStudy --repos <repo>
    或
    --repo DaleStudy/<repo>
  3. 将名称添加到
    wrangler.jsonc
    的
    secrets.required
    中(仅限使用它的仓库)
  4. 将其添加到
    deploy.yml
    中传递给 Worker 的列表

배포 워크플로우

部署工作流

yaml
undefined
yaml
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(
wrangler preview --name pr-<번호>
)로 미리보기를 띄우고 PR에 주소를 댓글로 남기며, PR이 닫히면 지운다.
yaml
undefined
调用组织共享工作流。为每个 PR 使用 Workers Previews(
wrangler preview --name pr-<번호>
)启动预览,并通过评论在 PR 中留下预览地址;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
undefined
bash
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은 슬래시 없는 형태다 (
/about
, 도메인 루트
/
만 예외). API·웹훅·OAuth 콜백 경로가 모두 이 형태로 외부에 등록되어 있고, 앱 프레임워크(TanStack, React Router)도 이 형태로 링크를 만들기 때문이다.
정적 파일로 서빙하는 페이지는 Cloudflare 기본값이
about/index.html
을
/about/
에서 서빙하므로, 설정으로 맞춘다.
구성설정
Workers 정적 에셋 (prerender, SPA, Astro 모두)
wrangler.jsonc
의
assets.html_handling: "drop-trailing-slash"
Astro위 설정과 함께
astro.config.mjs
에
trailingSlash: "never"
,
build: { format: "file" }
TanStack Start·Router, React Router (SSR)기본값 그대로
  • canonical, sitemap, 내부 링크는 모두 슬래시 없는 형태로 쓴다.
  • Workers 정적 에셋의 리다이렉트는 307(임시)이고 바꿀 수 없다. 리다이렉트가 일어날 일 자체를 줄이도록 링크를 정규 형태로 맞춘다.
  • 확인:
    curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n'
    로 주요 페이지를 두 형태로 요청해, 슬래시 없는 쪽만 200이고 슬래시 있는 쪽은 그쪽으로 리다이렉트되는지 본다.
DaleStudy 站点的规范 URL 采用不带 trailing slash 的形式(
/about
,仅域名根路径
/
例外)。API、网页钩子和 OAuth 回调路径都以外部注册为这种形式,应用框架(TanStack、React Router)也会生成这种形式的链接。
对于以静态文件形式提供的页面,Cloudflare 默认会在
/about/
下提供
about/index.html
,因此需要通过配置使其保持一致。
配置设置
Workers 静态资产(prerender、SPA、Astro 均适用)
wrangler.jsonc
中的
assets.html_handling: "drop-trailing-slash"
Astro上述设置,并在
astro.config.mjs
中设置
trailingSlash: "never"
、
build: { format: "file" }
TanStack Start·Router、React Router(SSR)保持默认值
  • canonical、sitemap 和内部链接全部使用不带 trailing slash 的形式。
  • Workers 静态资产的重定向为 307(临时重定向),且无法更改。应将链接调整为规范形式,以尽量避免发生重定向。
  • 检查:使用
    curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n'
    分别以两种形式请求主要页面,确认只有不带 trailing slash 的形式返回 200,而带 trailing slash 的形式会重定向到不带 trailing slash 的版本。