개발일기

2026. 5. 10. 21:39공부

728x90
반응형
# Cloudflare Pages 테스트 배포

현재 목표는 1단계 수동 배포입니다. Firebase 로그인, 광고, 결제는 빼고 기본 게임과 닉네임 기반 랭킹만 확인합니다.

랭킹은 Cloudflare Pages Function의 `/api/scores`가 받고, Cloudflare KV의 `RANKINGS` namespace에 저장합니다.

## 1단계: 수동 배포

### 1. Godot에서 Web export 만들기

Godot Editor를 열고 Web export preset을 만듭니다.

- Export path: `export/web/index.html`
- Thread Support: 끄기
- Extension Support: 끄기
- Head Include: 비우기

처음 테스트는 Thread Support와 Extension Support를 끄는 것이 좋습니다. 나중에 켜면 `web/cloudflare/_headers` 파일을 `export/web/_headers`로 복사해야 합니다.

### 2. Wrangler 설치 및 로그인

PowerShell을 열고 repo root에서 실행합니다.

```powershell
cd D:\game\minigames
npm install -D wrangler
npx wrangler login
```

브라우저가 열리면 Cloudflare 계정으로 로그인하고 권한을 승인합니다.

### 3. 랭킹 저장용 KV 만들기

```powershell
npx wrangler kv namespace create RANKINGS
```
명령 결과에 namespace ID가 나옵니다. 일단 복사해 두세요. 대시보드에서도 다시 확인할 수 있습니다.

### 4. Cloudflare Pages 프로젝트 만들기

```powershell
npx wrangler pages project create minigames
```

production branch를 물어보면 `main`을 선택합니다.

이미 `minigames` 프로젝트가 있다고 나오면 이 단계는 건너뛰어도 됩니다.

### 5. Pages 프로젝트에 KV 연결하기

Cloudflare 대시보드에서 설정합니다.

1. Workers & Pages로 이동
2. `minigames` 프로젝트 선택
3. Settings 선택
4. Bindings 선택
5. Add binding 선택
6. Type은 KV namespace 선택
7. Variable name은 반드시 `RANKINGS`
8. KV namespace는 3번에서 만든 namespace 선택

바인딩 이름이 `RANKINGS`와 정확히 같아야 `functions/api/scores.js`가 랭킹 저장소를 찾을 수 있습니다.




### 6. 배포하기

반드시 repo root인 `D:\game\minigames`에서 실행합니다. 그래야 `functions/` 폴더가 같이 올라갑니다.

Cloudflare Pages는 단일 파일이 25MiB를 넘으면 배포가 실패합니다. Godot의 `index.wasm`이 25MiB보다 크면 먼저 아래 명령으로 wasm을 Brotli 압축합니다.

```powershell
node scripts/prepare-cloudflare-pages.mjs
```

압축 후 `export/web/_headers` 파일이 자동 생성됩니다. 이 파일이 있어야 브라우저가 압축된 `index.wasm`을 정상적으로 읽습니다.

```powershell
cd D:\game\minigames
node scripts\prepare-cloudflare-pages.mjs
npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true
```
주의: Godot에서 다시 export하면 압축된 index.wasm이 원래 큰 파일로 덮어써집니다. 그래서 배포 전에는 항상 node scripts\prepare-cloudflare-pages.mjs를 먼저 실행해야 합니다.


성공하면 `https://...pages.dev` 형태의 URL이 출력됩니다.

### 7. 테스트하기

1. 출력된 Pages URL 열기
2. 로비 진입 확인
3. 게임 하나 플레이
4. 게임 오버 후 닉네임 입력
5. 랭킹 화면에서 닉네임과 점수 표시 확인

랭킹이 비어 있으면 Cloudflare Pages 프로젝트의 KV binding 이름이 정확히 `RANKINGS`인지 확인하고 다시 배포합니다.

## 2단계: GitHub push 자동 배포

1단계가 잘 되면 다음 단계로 GitHub Actions를 추가합니다.

목표 흐름은 다음과 같습니다.

1. `main` 브랜치에 push
2. GitHub Actions가 Godot headless를 설치
3. Web export를 `export/web`에 생성
4. Wrangler로 Cloudflare Pages에 배포

Cloudflare Pages의 GitHub 연동만으로도 자동 배포는 가능하지만, Godot Web export를 만들어야 하므로 GitHub Actions에서 export까지 직접 처리하는 방식이 더 안정적입니다.

2단계에서 준비할 값:

- Cloudflare Account ID
- Cloudflare API Token
- Pages project name: `minigames`
- Godot version

이 값들은 GitHub repository secrets에 넣고, workflow 파일에서 사용합니다.



 


막힌 이유는 이것입니다.

index.wasm 34.1 MiB인데, Cloudflare Pages는 파일 하나가 25 MiB를 넘으면 업로드를 거부합니다.

지금 먼저 해야 할 순서는 이겁니다.

1. Godot에서 다시 Export
Godot export 화면으로 돌아가서 Web preset을 확인하세요.

반드시 이렇게 맞춥니다.

  • 확장 기능 지원: 끄기
  • 스레드 지원: 끄기
  • Head 포함: 비우기
  • 프로그레시브 웹 앱 > 활성화: 끄기
  • 실행 가능: 켜짐 OK
  • 내보낼 경로: D:\game\minigames\export\web\index.html

그리고 프로젝트 내보내기...를 누를 때, 혹시 디버그 포함 / Export With Debug 체크가 보이면 끄고 내보내세요.

2. export 후 크기 확인
PowerShell에서:

 
cd D:\game\minigames Get-ChildItem export\web\index.wasm | Select-Object Name,Length

Length가 26214400보다 작아야 합니다. 즉 25MiB 미만이어야 합니다.

더 보기 좋게 확인하려면:

 
"{0:N2} MiB" -f ((Get-Item export\web\index.wasm).Length / 1MB)

3. 다시 배포
25MiB 아래로 내려갔으면:

 
npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true

--commit-dirty=true는 지금 README 수정 등 커밋 안 된 변경이 있어서 Wrangler가 경고를 띄우는 걸 무시하는 옵션입니다.

중요
제가 확인한 현재 export/web/index.html에는 스레드 관련 설정이 들어가 있습니다.

 
godotPoolSize: 4 emscriptenPoolSize: 8 ensureCrossOriginIsolationHeaders: true

그래서 Godot 화면에서 스레드 지원을 껐다고 생각했더라도, 실제 export 결과는 스레드 빌드로 나간 상태입니다. 다시 내보낸 뒤 index.html에서 저 값들이 사라지거나 0이 되어야 합니다.

다시 export했는데도 index.wasm이 25MiB를 넘으면 다음 대안은 두 가지입니다.

  1. index.wasm을 Brotli로 미리 압축해서 Cloudflare에 올리는 방식
  2. Cloudflare Pages 대신 큰 wasm 파일 제한이 덜 빡센 호스팅을 임시로 쓰는 방식

일단은 스레드 끄기 + 디버그 없이 release export가 먼저입니다. 이걸 하면 대개 파일 크기가 많이 줄어듭니다.

 

 

문제 원인은 index.wasm이 Cloudflare Pages 단일 파일 제한인 25MiB를 넘은 것이었습니다. 그래서 scripts/prepare-cloudflare-pages.mjs (line 1)를 추가해서 index.wasm을 Brotli 압축했고, 크기가 이렇게 줄었습니다.

text
 
35.95 MiB -> 6.30 MiB

그 다음 이 명령으로 배포 성공했습니다.

powershell
 
npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true

앞으로 Godot에서 Web export를 다시 할 때마다 순서는 이렇게 하세요.

powershell
 
cd D:\game\minigames node scripts\prepare-cloudflare-pages.mjs npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true

주의: Godot에서 다시 export하면 압축된 index.wasm이 원래 큰 파일로 덮어써집니다. 그래서 배포 전에는 항상 node scripts\prepare-cloudflare-pages.mjs를 먼저 실행해야 합니다.

추가한 스크립트와 README 수정은 아직 GitHub에 push되지 않은 로컬 변경입니다. 다음에 자동 배포 단계로 넘어가기 전에 커밋/푸시하면 됩니다.

 


 

원인은 두 가지였습니다.

  1. 한글 깨짐
    Godot Web 기본 폰트가 한글 글리프를 못 그려서 입력창에서 깨져 보였습니다.
    resources/fonts/malgun.ttf를 추가하고 FontManager.gd (line 1) autoload로 모든 UI Control에 기본 폰트로 적용했습니다.
  2. 랭킹 안 나옴
    Cloudflare KV/API는 정상입니다. 제가 직접 API를 확인했을 때 점수가 이미 저장되어 있었습니다.
    문제는 Godot HTTPRequest 결과 배열을 잘못 읽고 있던 겁니다. 실제 HTTP status는 result[1], body는 result[3]인데 기존 코드는 result[0], result[2]를 보고 있어서 항상 빈 랭킹으로 처리됐습니다. RankingManager.gd (line 34)에서 고쳤습니다.

추가로 저장 직후 바로 랭킹 화면으로 넘어가면서 조회가 먼저 실행될 수 있어서, 점수 저장 요청이 끝난 뒤 랭킹 화면으로 이동하도록 바꿨습니다.

이제 다시 배포하려면 아래 순서로 하세요.

  1. Godot에서 다시 Web export
    D:\game\minigames\export\web\index.html
  2. PowerShell에서:
powershell
 
cd D:\game\minigames node scripts\prepare-cloudflare-pages.mjs npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true
 

중요: 이번 수정은 Godot 코드와 폰트 리소스가 바뀐 거라, 반드시 Godot에서 Web export를 다시 해야 브라우저에 반영됩니다.

 

 

Web Export

 

Godot 화면 기준으로 Web export는 이렇게 하면 됩니다.

**1. Export 창 열기**
Godot 상단 메뉴에서:

`프로젝트 > 내보내기...`

또는 영어 UI면:

`Project > Export...`

**2. Web 프리셋 선택**
왼쪽에서 `Web (실행 가능)` 프리셋을 선택하세요.

없으면:
- `추가...`
- `Web`
- 선택

**3. 내보낼 경로 설정**
오른쪽 위 `내보낼 경로` 옆 폴더 버튼을 누르고 아래 경로로 저장합니다.

```text
D:\game\minigames\export\web\index.html
```

파일 이름은 반드시 `index.html`로 하세요.

**4. 옵션 설정**
현재 테스트용 설정은 이렇게 맞추세요.

- `확장 기능 지원`: 끄기
- `스레드 지원`: 끄기
- `Head 포함`: 비우기
- `프로그레시브 웹 앱 > 활성화`: 끄기
- `Canvas 크기 조절 방식`: Adaptive
- `시작할 때 Canvas에 포커스`: 켜기
- `실험적 가상 키보드`: 켜도 되고 꺼도 되지만, 한글 입력 테스트 중이면 켜서 한번 확인해보는 것도 좋습니다.

**5. 내보내기 실행**
아래 버튼 중:

`프로젝트 내보내기...`

를 누르세요.

주의:
- `PCK/ZIP 내보내기...`가 아닙니다.
- `프로젝트 내보내기...`를 눌러야 `.html`, `.js`, `.wasm`, `.pck`가 같이 나옵니다.

저장 창이 뜨면 다시:

```text
D:\game\minigames\export\web\index.html
```

로 저장합니다.

혹시 `디버그 포함` 같은 체크박스가 보이면 꺼주세요.

**6. 결과 확인**
PowerShell에서:

```powershell
cd D:\game\minigames
Get-ChildItem export\web
```

아래 파일들이 있으면 정상입니다.

```text
index.html
index.js
index.wasm
index.pck
```

**7. Cloudflare용 압축 후 배포**
Godot export가 끝나면 반드시 이 순서로 실행하세요.

```powershell
cd D:\game\minigames
node scripts\prepare-cloudflare-pages.mjs
npx wrangler pages deploy export/web --project-name minigames --commit-dirty=true
```

`node scripts\prepare-cloudflare-pages.mjs`는 `index.wasm`을 Cloudflare Pages 제한에 맞게 압축하는 단계입니다. Godot에서 export를 다시 할 때마다 이 명령도 다시 실행해야 합니다.

728x90
반응형

'공부' 카테고리의 다른 글

개발 일기  (0) 2026.05.15
long video 개발 일기 (kimi)  (0) 2026.05.02
게임 개발 일기  (0) 2026.04.27
오늘의 영문장 9/16  (1) 2025.09.16
오늘의 영문장  (7) 2025.08.30