Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ EXPO_PUBLIC_SOUNDLOG_API_SOURCE=server EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=/api/so
```

Vercel web 배포는 브라우저 API 호출을 같은 origin에서 처리하도록
`https://soundlog.shop/api/soundlog` rewrite proxy를 사용합니다. 브라우저와 네이티브 앱은 별도 `api` 서브도메인을 쓰지 않습니다. Vercel 내부 rewrite 대상은
`SOUNDLOG_API_ORIGIN` 환경변수로 관리하며, 이 값은 최신 SoundLogServer origin이어야 합니다. `vercel.mjs`의 build command가
`https://soundlog.shop/api/soundlog` rewrite proxy를 사용합니다. Vercel 내부 rewrite 대상은
`SOUNDLOG_API_ORIGIN` 환경변수로 관리하며, 이 값은 최신 SoundLogServer origin(`https://api.soundlog.shop`)이어야 합니다. `vercel.mjs`의 build command가
`EXPO_PUBLIC_SOUNDLOG_API_SOURCE=server`와
`EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=/api/soundlog`를 주입합니다.

네이티브 실배포 빌드는 `https://soundlog.shop/api/soundlog` HTTPS 프록시를 사용합니다. 로그인은 Soundlog 자체 이메일/비밀번호 계정으로 처리합니다.
네이티브 실배포 빌드는 `api.soundlog.shop` 서브도메인을 직접 호출합니다(GCP VM 위 Caddy가 HTTPS를 종료). 로그인은 Soundlog 자체 이메일/비밀번호 계정으로 처리합니다.

## 테스트 설치 빌드

`development`, `preview` EAS profile은 HTTPS Vercel API proxy를 바라보도록 설정되어 있습니다.
`development`, `preview` EAS profile은 `api.soundlog.shop`을 직접 바라보도록 설정되어 있습니다.

- Web: `https://soundlog.shop`
- API: `https://soundlog.shop/api/soundlog`
- API: `https://api.soundlog.shop`
- API source: `server`
- auth: Soundlog 자체 이메일/비밀번호 로그인
- iOS/Android: HTTPS API만 사용
Expand All @@ -67,7 +67,7 @@ Mock API로 되돌리는 런타임 경로는 제거했습니다. 화면 상태
API origin이 최신 서버인지 확인하려면 아래처럼 실행합니다.

```bash
SOUNDLOG_API_ORIGIN=http://<EC2_HOST>:4000 npm run check:api-origin
SOUNDLOG_API_ORIGIN=https://api.soundlog.shop npm run check:api-origin
```

이 검사는 로그인 필수 API도 함께 확인하므로 `SOUNDLOG_CHECK_EMAIL`,
Expand All @@ -80,7 +80,7 @@ Android 지인 테스트용 내부 배포 빌드는 아래 명령으로 생성
npx eas build --profile preview --platform android
```

iOS는 TestFlight 또는 ad hoc 기기 등록이 필요합니다. App Store/TestFlight에 올릴 production profile도 현재는 `https://soundlog.shop/api/soundlog`을 사용합니다.
iOS는 TestFlight 또는 ad hoc 기기 등록이 필요합니다. App Store/TestFlight에 올릴 production profile도 현재는 `https://api.soundlog.shop`을 사용합니다.

## 문서

Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Soundlog 문서는 목적별로 관리합니다. 공모전 기획, RN 프론트

## Deployment

- [soundlog.shop 배포 설정](deployment/SOUNDLOG_SHOP_DOMAIN.md): Gabia DNS, Vercel, EC2 API 도메인, EAS env 설정 기준
- [soundlog.shop 배포 설정](deployment/SOUNDLOG_SHOP_DOMAIN.md): Gabia DNS, Vercel, GCP API 도메인, EAS env 설정 기준

## Legacy Mock API

Expand Down
22 changes: 13 additions & 9 deletions docs/deployment/SOUNDLOG_SHOP_DOMAIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Soundlog 운영/테스트 도메인은 아래 구조로 사용합니다.
| --- | --- | --- |
| `soundlog.shop` | Vercel | Expo web frontend |
| `www.soundlog.shop` | Vercel | Frontend alias |
| `soundlog.shop/api/soundlog` | Vercel rewrite | Express API proxy |
| `api.soundlog.shop` | GCP Compute Engine | Express API (Caddy로 HTTPS 직접 종료) |
| `soundlog.shop/api/soundlog` | Vercel rewrite | 웹 빌드 전용 API 프록시 (브라우저 CORS 회피) |

## Gabia DNS

Expand All @@ -16,8 +17,9 @@ Gabia DNS 관리툴에서 아래 레코드를 설정합니다.
| --- | --- | --- |
| `A` | `@` | `76.76.21.21` |
| `CNAME` | `www` | `cname.vercel-dns.com.` |
| `A` | `api` | `34.64.116.40` |

별도 `api` 서브도메인은 사용하지 않습니다. API 컨테이너는 EC2 `4000` 포트에서 동작하고, Vercel이 `https://soundlog.shop/api/soundlog/:path*` 요청을 EC2 API로 rewrite합니다.
API 컨테이너는 GCP VM(`soundlog-api`, `asia-northeast3-a`)의 Docker Compose 스택에서 동작하고, VM 위의 Caddy가 `api.soundlog.shop`에 대한 Let's Encrypt 인증서를 자동으로 발급해 HTTPS를 직접 종료합니다. `api` A 레코드가 GCP 정적 IP를 가리키기 전까지는 인증서 발급이 되지 않으므로 `https://api.soundlog.shop`은 동작하지 않습니다.

## Vercel

Expand All @@ -26,23 +28,23 @@ Vercel project domain에 아래 도메인을 추가합니다.
- `soundlog.shop`
- `www.soundlog.shop`

Web build는 `vercel.mjs`에서 `EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=/api/soundlog`를 주입합니다. `/api/soundlog/:path*` 요청은 Vercel이 서버 사이드에서 `SOUNDLOG_API_ORIGIN`으로 rewrite합니다.
Web build는 `vercel.mjs`에서 `EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=/api/soundlog`를 주입합니다. `/api/soundlog/:path*` 요청은 Vercel이 서버 사이드에서 `SOUNDLOG_API_ORIGIN`으로 rewrite합니다. 이 프록시는 브라우저 fetch가 same-origin이 되도록 웹 빌드에서만 사용하며, 모바일 앱은 `api.soundlog.shop`을 직접 호출합니다.

Vercel 환경변수에 아래 값을 설정합니다.

```dotenv
SOUNDLOG_API_ORIGIN=http://<EC2_HOST>:4000
SOUNDLOG_API_ORIGIN=https://api.soundlog.shop
```

브라우저와 앱이 호출하는 공개 API URL은 계속 `https://soundlog.shop/api/soundlog`입니다. `SOUNDLOG_API_ORIGIN`은 Vercel 서버 사이드 rewrite에서만 쓰이는 내부 origin입니다.
브라우저가 호출하는 공개 API URL은 계속 `https://soundlog.shop/api/soundlog`입니다. `SOUNDLOG_API_ORIGIN`은 Vercel 서버 사이드 rewrite에서만 쓰이는 내부 origin입니다.

## EAS app env

`development`, `preview`, `production` profile은 `soundlog.shop` HTTPS Vercel proxy를 사용합니다.
`development`, `preview`, `production` profile은 `api.soundlog.shop`을 직접 호출합니다.

```dotenv
EXPO_PUBLIC_SOUNDLOG_API_SOURCE=server
EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=https://soundlog.shop/api/soundlog
EXPO_PUBLIC_SOUNDLOG_API_BASE_URL=https://api.soundlog.shop
```

Production profile은 추가로 약관/개인정보 URL과 지원 메일을 설정합니다.
Expand All @@ -60,7 +62,9 @@ DNS와 HTTPS 설정이 끝나면 아래 명령으로 확인합니다.
```bash
dig +short soundlog.shop A
dig +short www.soundlog.shop CNAME
dig +short api.soundlog.shop A
curl -I https://soundlog.shop
curl https://api.soundlog.shop/v1/health
curl https://soundlog.shop/api/soundlog/v1/health
npm run check:deployed-web -- https://soundlog.shop
```
Expand All @@ -70,8 +74,8 @@ npm run check:deployed-web -- https://soundlog.shop
`SOUNDLOG_CHECK_PASSWORD`를 지정해 고정 검증 계정으로 실행합니다. 값을 지정하지
않으면 스크립트가 `@soundlog.test` 임시 계정을 생성합니다.

EC2 origin을 직접 검증하려면 아래 명령을 실행합니다. 이 검사는 `/openapi.yaml`, fallback 장소 source, Spotify 메타데이터 제거 여부까지 확인하므로 예전 백엔드로 잘못 붙은 경우 실패합니다.
GCP origin을 직접 검증하려면 아래 명령을 실행합니다. 이 검사는 `/openapi.yaml`, fallback 장소 source, Spotify 메타데이터 제거 여부까지 확인하므로 예전 백엔드로 잘못 붙은 경우 실패합니다.

```bash
SOUNDLOG_API_ORIGIN=http://<EC2_HOST>:4000 npm run check:api-origin
SOUNDLOG_API_ORIGIN=https://api.soundlog.shop npm run check:api-origin
```
6 changes: 3 additions & 3 deletions eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@
"developmentClient": true,
"distribution": "internal",
"env": {
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://soundlog.shop/api/soundlog",
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://api.soundlog.shop",
"EXPO_PUBLIC_SOUNDLOG_API_SOURCE": "server"
}
},
"preview": {
"distribution": "internal",
"env": {
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://soundlog.shop/api/soundlog",
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://api.soundlog.shop",
"EXPO_PUBLIC_SOUNDLOG_API_SOURCE": "server"
}
},
"production": {
"autoIncrement": true,
"env": {
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://soundlog.shop/api/soundlog",
"EXPO_PUBLIC_SOUNDLOG_API_BASE_URL": "https://api.soundlog.shop",
"EXPO_PUBLIC_SOUNDLOG_API_SOURCE": "server",
"EXPO_PUBLIC_SOUNDLOG_PRIVACY_URL": "https://soundlog.shop/legal/privacy",
"EXPO_PUBLIC_SOUNDLOG_SUPPORT_EMAIL": "support@soundlog.shop",
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-api-origin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const apiOrigin = (process.argv[2] || process.env.SOUNDLOG_API_ORIGIN || '').rep
let authHeaderPromise;

if (!apiOrigin) {
console.error('Usage: npm run check:api-origin -- http://<EC2_HOST>:4000');
console.error('Usage: npm run check:api-origin -- https://api.soundlog.shop');
process.exit(1);
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/check-server-web-export.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function verifyBundle(bundleText) {
assertExcludes(
bundleText,
/http:\/\/\d+\.\d+\.\d+\.\d+:4000/,
'Server web export must not inline a direct EC2 HTTP API URL.',
'Server web export must not inline a direct raw-IP HTTP API URL.',
);
[
['authMockHandlers', 'Server web export must not include auth mock handlers.'],
Expand Down
3 changes: 1 addition & 2 deletions scripts/require-vercel-api-origin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
const apiOrigin = process.env.SOUNDLOG_API_ORIGIN?.replace(/\/+$/, '');
const staleOrigins = new Set([
'http://52.79.185.121:4000',
'https://api.soundlog.shop',
]);

if (!apiOrigin) {
console.error(
'SOUNDLOG_API_ORIGIN is required for Vercel builds. Set it to the current SoundLogServer origin, for example http://<EC2_HOST>:4000.',
'SOUNDLOG_API_ORIGIN is required for Vercel builds. Set it to the current SoundLogServer origin, for example https://api.soundlog.shop.',
);
process.exit(1);
}
Expand Down
Loading