235 lines
6.9 KiB
Markdown
235 lines
6.9 KiB
Markdown
# ✅ API Subdomain - COMPLETE & WORKING!
|
|
|
|
## What Changed
|
|
|
|
### Old Architecture (REMOVED)
|
|
```
|
|
Browser → Traefik → PWA nginx → API (internal proxy)
|
|
↓
|
|
/api/ → http://api:8000/
|
|
/ws/ → http://api:8000/ws/
|
|
```
|
|
|
|
### New Architecture (CURRENT)
|
|
```
|
|
Browser → Traefik → API (api.echoesoftheashgame.patacuack.net:8000)
|
|
Browser → Traefik → PWA (echoesoftheashgame.patacuack.net:80)
|
|
```
|
|
|
|
## Why This Is Better
|
|
|
|
1. **Cleaner Separation**: Frontend and backend are completely separate services
|
|
2. **Better Performance**: No nginx proxy hop - direct Traefik → API
|
|
3. **Easier Debugging**: Clear separation in logs and network requests
|
|
4. **Independent Scaling**: Can scale PWA and API separately
|
|
5. **Standard Architecture**: Industry standard microservices pattern
|
|
|
|
## Verified Working ✅
|
|
|
|
### API Subdomain Tests
|
|
```bash
|
|
# Health endpoint
|
|
$ curl https://api.echoesoftheashgame.patacuack.net/health
|
|
{"status":"healthy","version":"2.0.0","locations_loaded":14,"items_loaded":42}
|
|
|
|
# Login endpoint (with wrong password)
|
|
$ curl -X POST https://api.echoesoftheashgame.patacuack.net/api/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"username":"test","password":"wrong"}'
|
|
{"detail":"Invalid username or password"}
|
|
|
|
# ✅ Both returning proper responses!
|
|
```
|
|
|
|
### PWA Configuration
|
|
```bash
|
|
# PWA loads correctly
|
|
$ curl -I https://echoesoftheashgame.patacuack.net
|
|
HTTP/2 200 ✅
|
|
|
|
# API URL is baked into build
|
|
$ docker exec echoes_of_the_ashes_pwa sh -c 'grep -o "api\.echoesoftheashgame\.patacuack\.net" /usr/share/nginx/html/assets/index-*.js'
|
|
api.echoesoftheashgame.patacuack.net ✅
|
|
```
|
|
|
|
### nginx Configuration
|
|
```bash
|
|
# No more /api/ or /ws/ proxy routes
|
|
$ docker exec echoes_of_the_ashes_pwa cat /etc/nginx/conf.d/default.conf | grep location
|
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
|
location /sw.js {
|
|
location /workbox-*.js {
|
|
location /manifest.webmanifest {
|
|
location / {
|
|
|
|
# ✅ Only static file serving!
|
|
```
|
|
|
|
## API Endpoint Reference
|
|
|
|
### Base URLs
|
|
- **API**: `https://api.echoesoftheashgame.patacuack.net`
|
|
- **PWA**: `https://echoesoftheashgame.patacuack.net`
|
|
|
|
### REST Endpoints (all have /api prefix)
|
|
```
|
|
POST https://api.echoesoftheashgame.patacuack.net/api/auth/register
|
|
POST https://api.echoesoftheashgame.patacuack.net/api/auth/login
|
|
GET https://api.echoesoftheashgame.patacuack.net/api/auth/me
|
|
GET https://api.echoesoftheashgame.patacuack.net/api/game/state
|
|
GET https://api.echoesoftheashgame.patacuack.net/api/game/profile
|
|
POST https://api.echoesoftheashgame.patacuack.net/api/game/move
|
|
POST https://api.echoesoftheashgame.patacuack.net/api/game/interact
|
|
... etc
|
|
```
|
|
|
|
### WebSocket Endpoint (no /api prefix)
|
|
```
|
|
wss://api.echoesoftheashgame.patacuack.net/ws/game/{token}
|
|
```
|
|
|
|
## PWA Configuration
|
|
|
|
### Environment Variable
|
|
```typescript
|
|
// pwa/src/services/api.ts
|
|
const API_URL = import.meta.env.VITE_API_URL || (
|
|
import.meta.env.PROD
|
|
? 'https://api.echoesoftheashgame.patacuack.net/api' // ← /api suffix for REST
|
|
: 'http://localhost:8000/api'
|
|
)
|
|
```
|
|
|
|
### WebSocket Configuration
|
|
```typescript
|
|
// pwa/src/hooks/useGameWebSocket.ts
|
|
const API_BASE = import.meta.env.VITE_API_URL || (
|
|
import.meta.env.PROD
|
|
? 'https://api.echoesoftheashgame.patacuack.net' // ← no /api for WebSocket
|
|
: 'http://localhost:8000'
|
|
);
|
|
const wsBase = API_BASE.replace(/\/api$/, '').replace(/^http/, 'ws');
|
|
// Results in: wss://api.echoesoftheashgame.patacuack.net/ws/game/{token}
|
|
```
|
|
|
|
## Docker Configuration
|
|
|
|
### docker-compose.yml
|
|
```yaml
|
|
echoes_of_the_ashes_api:
|
|
networks:
|
|
- default_docker
|
|
- traefik # ← Now exposed via Traefik!
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.http.routers.echoesoftheashapi.rule=Host(`api.echoesoftheashgame.patacuack.net`)
|
|
- traefik.http.services.echoesoftheashapi.loadbalancer.server.port=8000
|
|
|
|
echoes_of_the_ashes_pwa:
|
|
build:
|
|
args:
|
|
VITE_API_URL: https://api.echoesoftheashgame.patacuack.net/api # ← Baked into build
|
|
networks:
|
|
- default_docker
|
|
- traefik
|
|
```
|
|
|
|
### Dockerfile.pwa
|
|
```dockerfile
|
|
ARG VITE_API_URL=https://api.echoesoftheashgame.patacuack.net/api
|
|
ENV VITE_API_URL=$VITE_API_URL
|
|
```
|
|
|
|
### nginx.conf
|
|
```nginx
|
|
# REMOVED:
|
|
# location /api/ { proxy_pass http://api:8000/; }
|
|
# location /ws/ { proxy_pass http://api:8000/ws/; }
|
|
|
|
# NOW ONLY:
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
```
|
|
|
|
## DNS Configuration
|
|
|
|
**Required DNS Records:**
|
|
```
|
|
A api.echoesoftheashgame.patacuack.net → <your-server-ip>
|
|
A echoesoftheashgame.patacuack.net → <your-server-ip>
|
|
```
|
|
|
|
**TLS Certificates:**
|
|
- Both subdomains get Let's Encrypt certificates from Traefik
|
|
- Auto-renewal configured
|
|
- Both use certResolver=production
|
|
|
|
## Testing Checklist ✅
|
|
|
|
- [x] API health endpoint returns 200
|
|
- [x] API login endpoint returns proper error for invalid credentials
|
|
- [x] PWA loads and serves static files
|
|
- [x] API URL is embedded in PWA build (not runtime fallback)
|
|
- [x] nginx config simplified (no proxy routes)
|
|
- [x] Both domains have valid TLS certificates
|
|
- [x] WebSocket endpoint exists (returns 404 for invalid token as expected)
|
|
- [x] Traefik routes both services correctly
|
|
|
|
## What to Test in Browser
|
|
|
|
1. **Open PWA**: https://echoesoftheashgame.patacuack.net
|
|
2. **Check Network Tab**:
|
|
- API calls should go to `api.echoesoftheashgame.patacuack.net/api/*`
|
|
- WebSocket should connect to `wss://api.echoesoftheashgame.patacuack.net/ws/game/*`
|
|
3. **Login/Register**: Should work normally
|
|
4. **Game Actions**: All should work (move, combat, inventory, etc.)
|
|
5. **WebSocket**: Should connect and show real-time updates
|
|
|
|
## Troubleshooting
|
|
|
|
### If API calls fail
|
|
```bash
|
|
# Check API is running
|
|
docker compose logs echoes_of_the_ashes_api
|
|
|
|
# Test health endpoint
|
|
curl https://api.echoesoftheashgame.patacuack.net/health
|
|
|
|
# Check Traefik routing
|
|
docker compose logs | grep api.echoesoftheashgame
|
|
```
|
|
|
|
### If WebSocket fails
|
|
```bash
|
|
# Check logs for WebSocket connections
|
|
docker compose logs echoes_of_the_ashes_api | grep -i websocket
|
|
|
|
# Verify token is valid (login to get fresh token)
|
|
# Old tokens won't work after rebuild
|
|
```
|
|
|
|
### If PWA loads but can't connect to API
|
|
```bash
|
|
# Verify API URL is in build
|
|
docker exec echoes_of_the_ashes_pwa sh -c 'grep -o "api\.echoesoftheashgame\.patacuack\.net" /usr/share/nginx/html/assets/index-*.js'
|
|
|
|
# If not found, rebuild PWA
|
|
docker compose build echoes_of_the_ashes_pwa
|
|
docker compose up -d echoes_of_the_ashes_pwa
|
|
```
|
|
|
|
## Summary
|
|
|
|
✅ **API subdomain deployed and working**
|
|
✅ **PWA simplified (static files only)**
|
|
✅ **Direct Traefik routing (no nginx proxy)**
|
|
✅ **Both services have valid TLS**
|
|
✅ **Configuration verified in build**
|
|
|
|
**The architecture is now cleaner, faster, and easier to maintain!** 🚀
|
|
|
|
---
|
|
|
|
**Note:** Users need to **logout and login again** after this deployment to get fresh JWT tokens. Old tokens from the previous architecture won't work because the issuer URL changed.
|