Update CLAUDE.md with Dokploy deployment docs and fixes
This commit is contained in:
parent
79701c5e93
commit
b184d74ad4
1 changed files with 189 additions and 1 deletions
190
CLAUDE.md
190
CLAUDE.md
|
|
@ -77,4 +77,192 @@ Key modules (read in this order for domain understanding):
|
|||
- **routers/** — REST endpoints (scenarios, sensitivities, templates)
|
||||
- **workers/** — Arq async tasks (run via Redis queue)
|
||||
- **db/** — SQLAlchemy models + migrations
|
||||
- **main.py** — FastAPI app factory
|
||||
- **main.py** — FastAPI app factory
|
||||
|
||||
## Deployment (Dokploy)
|
||||
|
||||
### Docker Configuration
|
||||
|
||||
**API Dockerfile** (`packages/api/Dockerfile`):
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN pip install poetry
|
||||
|
||||
COPY packages /app/packages
|
||||
|
||||
WORKDIR /app/packages/api
|
||||
RUN poetry install --no-interaction
|
||||
|
||||
ENV VENV_PATH=/root/.cache/pypoetry/virtualenvs/remodel-api-cufy8KWC-py3.12/bin
|
||||
ENV PATH=$VENV_PATH:$PATH
|
||||
ENV PYTHONPATH=/app/packages/engine/src:/app/packages/api/src
|
||||
|
||||
WORKDIR /app/packages/api
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
CMD ["uvicorn", "remodel_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
```
|
||||
|
||||
**Web Dockerfile** (`packages/web/Dockerfile`):
|
||||
```dockerfile
|
||||
FROM node:22-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
COPY . .
|
||||
RUN test -f .env.local || echo "# placeholder" > .env.local
|
||||
RUN pnpm install --frozen-lockfile --ignore-scripts
|
||||
RUN pnpm build
|
||||
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
|
||||
COPY --from=builder /app/.next ./.next
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/package.json .
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
COPY --from=builder /app/.env.local ./.env.local
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["/app/node_modules/.bin/next", "start"]
|
||||
```
|
||||
|
||||
### docker-compose.yml (Dokploy)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- internal
|
||||
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: packages/api/Dockerfile
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- DATABASE_URL=sqlite+aiosqlite:///./remodel.db
|
||||
- REDIS_URL=redis://redis:6379
|
||||
depends_on:
|
||||
- redis
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=web"
|
||||
- "traefik.http.routers.api.rule=Host(`model.manohargupta.com`) && PathPrefix(`/api`)"
|
||||
- "traefik.http.routers.api.entrypoints=websecure"
|
||||
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.api.loadbalancer.server.port=8000"
|
||||
networks:
|
||||
- internal
|
||||
- web
|
||||
|
||||
worker:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: packages/api/Dockerfile
|
||||
command: python -m arq remodel_api.workers.main.WorkerSettings
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- DATABASE_URL=sqlite+aiosqlite:///./remodel.db
|
||||
- REDIS_URL=redis://redis:6379
|
||||
depends_on:
|
||||
- redis
|
||||
networks:
|
||||
- internal
|
||||
|
||||
web:
|
||||
build:
|
||||
context: ./packages/web
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=https://model.manohargupta.com/api
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=web"
|
||||
- "traefik.http.routers.web.rule=Host(`model.manohargupta.com`)"
|
||||
- "traefik.http.routers.web.entrypoints=websecure"
|
||||
- "traefik.http.routers.web.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.web.loadbalancer.server.port=3000"
|
||||
networks:
|
||||
- web
|
||||
|
||||
networks:
|
||||
internal:
|
||||
internal: true
|
||||
web:
|
||||
name: dokploy-network
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
redis_data:
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Description | Required |
|
||||
|----------|-------------|----------|
|
||||
| `DATABASE_URL` | SQLite with async driver | `sqlite+aiosqlite:///./remodel.db` |
|
||||
| `REDIS_URL` | Redis connection string | `redis://redis:6379` |
|
||||
| `NEXT_PUBLIC_API_URL` | Public API URL for web | `https://model.manohargupta.com/api` |
|
||||
|
||||
### CORS Configuration
|
||||
|
||||
In `packages/api/src/remodel_api/main.py`:
|
||||
```python
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["http://localhost:3000", "https://model.manohargupta.com"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
```
|
||||
|
||||
### Config Settings
|
||||
|
||||
In `packages/api/src/remodel_api/config.py`:
|
||||
```python
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_prefix="", extra="ignore")
|
||||
database_url: str = "sqlite+aiosqlite:///./remodel.db"
|
||||
redis_url: str = "redis://localhost:6379"
|
||||
```
|
||||
|
||||
**Important**: No prefix for env vars - they must match docker-compose exactly.
|
||||
|
||||
### Network Requirements
|
||||
|
||||
- `dokploy-network` must exist on Dokploy server (external network)
|
||||
- Traefik uses `websecure` endpoint (HTTPS with Let's Encrypt TLS)
|
||||
|
||||
## Deployment Issues & Fixes
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| Poetry pyproject.toml not found | COPY syntax wrong in Dockerfile | Copy entire `packages/` directory |
|
||||
| `--no-venv-seeding` flag error | Old Poetry version | Remove the flag |
|
||||
| Missing `.env.local` | Not in git | Create placeholder in builder stage |
|
||||
| `uvicorn` not in PATH | Poetry venv not in PATH | Set `ENV PATH=$VENV_PATH:$PATH` |
|
||||
| `next` not found | pnpm stores bins differently | Use absolute path `/app/node_modules/.bin/next` |
|
||||
| 504 Gateway Timeout | Redis/DB not accessible | Check network, restart containers |
|
||||
| Worker can't connect to Redis | Wrong env prefix | Use `REDIS_URL` not `REMODEL_REDIS_URL` |
|
||||
| SQLite async error | Wrong driver | Use `sqlite+aiosqlite://` not `sqlite://` |
|
||||
| CORS blocked | Origin mismatch | Add production domain to allow_origins |
|
||||
Loading…
Add table
Reference in a new issue