docs: record production deployment and maintenance
This commit is contained in:
@@ -2,6 +2,27 @@
|
||||
|
||||
本文件是当前项目给协作代理、自动化助手与派生工作流的硬约束补充。它不替代 `SKILL.md`,而是把最容易被偷懒、省略、或在多窗口工作时遗失的高严谨规则单独钉死。
|
||||
|
||||
## 0. Production Maintenance Truth
|
||||
|
||||
任何部署、线上故障、域名、登录或环境变量任务,先读取 `deploy/README.md`,不要重新猜测架构。
|
||||
|
||||
- Production domain: `https://jyotisha.chat`
|
||||
- Source: `https://github.com/jesse-ux/Jyotisha.git`
|
||||
- Server: Hong Kong Ubuntu 22.04 VPS, `103.117.123.53`, SSH port `22000`
|
||||
- Runtime: `/opt/jyotisha-app`, Docker Compose file `deploy/docker-compose.server.yml`
|
||||
- Secrets: `/opt/jyotisha-app/.env.production`; never print, copy into chat, or commit
|
||||
- Public edge: Caddy only; Next.js `3000` and Python API `5200` stay Docker-private
|
||||
- Managed services: Spaceship DNS, Supabase project `vtvnfqmonbfuxmqkqdlc`, external model API
|
||||
- Capacity boundary: 1 vCPU / 2 GB RAM / 40 GB disk / 5 Mbps; demo and low concurrency only
|
||||
|
||||
Deployment safety rules:
|
||||
|
||||
1. Run `git status --short --branch` before packaging; do not overwrite unrelated dirty files.
|
||||
2. Verify `dig +short @launch1.spaceship.net A jyotisha.chat` returns `103.117.123.53` before troubleshooting Caddy certificate issuance.
|
||||
3. Keep Supabase Auth Site URL and redirect URLs aligned with `https://jyotisha.chat`.
|
||||
4. After deployment, verify `/login`, logged-out `/api/account` = `401`, internal `/api/health` = `200`, and `swisseph_available = true`.
|
||||
5. Never expose port `5200`, `SUPABASE_SERVICE_ROLE_KEY`, model keys, user JWTs, passwords, or SSH private keys.
|
||||
|
||||
## 1. High-Rigor Override
|
||||
|
||||
当用户明确要求以下任一项时,必须进入高严谨模式:
|
||||
|
||||
@@ -11,23 +11,32 @@
|
||||
|
||||
---
|
||||
|
||||
## Product service layout
|
||||
## Production service layout
|
||||
|
||||
```text
|
||||
frontend/ Next.js + Mastra chat product
|
||||
scripts/jyotish_api_server.py Python API entrypoint
|
||||
jyotish_vedic/ Python calculation package
|
||||
skills/ + references/ + assets/ Agent skill and calculation evidence
|
||||
supabase/ Auth, profile, session, credits migrations
|
||||
deploy/ Railway web/api Dockerfiles
|
||||
jyotisha.chat
|
||||
-> Spaceship DNS
|
||||
-> Caddy on Hong Kong VPS (80/443)
|
||||
-> Next.js + Mastra web container (3000, private)
|
||||
-> Python Jyotish API container (5200, private)
|
||||
-> Swiss Ephemeris / local calculation engine
|
||||
-> VedAstro gateway with local fallback
|
||||
-> Supabase Cloud (Auth, Postgres, profiles, sessions, credits)
|
||||
-> external OpenAI-compatible model API
|
||||
```
|
||||
|
||||
Railway runs two services from the same repository:
|
||||
Current production infrastructure:
|
||||
|
||||
- `web`: `deploy/railway-web.Dockerfile`
|
||||
- `api`: `deploy/railway-api.Dockerfile`
|
||||
- Domain: `https://jyotisha.chat`
|
||||
- Server: Hong Kong, Ubuntu 22.04, `103.117.123.53`, SSH port `22000`
|
||||
- Capacity: 1 vCPU, 2 GB RAM, 40 GB disk, 5 Mbps; intended for demos and low concurrency
|
||||
- Runtime directory: `/opt/jyotisha-app`
|
||||
- Compose file: `deploy/docker-compose.server.yml`
|
||||
- Production environment: `/opt/jyotisha-app/.env.production` (`0600`, never commit)
|
||||
- Supabase project: `vtvnfqmonbfuxmqkqdlc`
|
||||
- Source repository: `https://github.com/jesse-ux/Jyotisha.git`
|
||||
|
||||
Deployment variables and private-network wiring are documented in `deploy/README.md`.
|
||||
Deployment, recovery, DNS, HTTPS, update and verification commands are documented in [`deploy/README.md`](deploy/README.md). Railway/Vercel remain optional alternatives, not the current production topology.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
|
||||
+130
-36
@@ -1,62 +1,156 @@
|
||||
# Railway deployment
|
||||
# Production deployment and maintenance
|
||||
|
||||
Create services named `web` and `api` from this repository. Leave both **Root Directory** and **Start Command** empty; the Dockerfiles bind `0.0.0.0` and read `$PORT`.
|
||||
This file is the operational source of truth for the current Jyotisha demo deployment.
|
||||
|
||||
| Service | Required variable | Healthcheck Path |
|
||||
| --- | --- | --- |
|
||||
| `web` | `RAILWAY_DOCKERFILE_PATH=/deploy/railway-web.Dockerfile` | `/login` |
|
||||
| `api` | `RAILWAY_DOCKERFILE_PATH=/deploy/railway-api.Dockerfile` | `/api/health` |
|
||||
## Current production
|
||||
|
||||
## `api` variables
|
||||
| Item | Value |
|
||||
| --- | --- |
|
||||
| Public domain | `https://jyotisha.chat` |
|
||||
| DNS | Spaceship nameservers (`launch1.spaceship.net`, `launch2.spaceship.net`) |
|
||||
| Server | Hong Kong VPS, Ubuntu 22.04 x86_64 |
|
||||
| Public host | `103.117.123.53` |
|
||||
| SSH | port `22000`, public-key authentication only |
|
||||
| Capacity | 1 vCPU / 2 GB RAM / 40 GB disk / 5 Mbps |
|
||||
| App directory | `/opt/jyotisha-app` |
|
||||
| Environment file | `/opt/jyotisha-app/.env.production` (`0600`) |
|
||||
| Source repository | `https://github.com/jesse-ux/Jyotisha.git` |
|
||||
| Supabase project | `vtvnfqmonbfuxmqkqdlc` |
|
||||
|
||||
```dotenv
|
||||
PORT=5200
|
||||
This machine is suitable for a client demo and low concurrency. Supabase and the model provider stay managed externally; do not self-host them on this VPS.
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
Spaceship DNS
|
||||
-> Caddy :80/:443
|
||||
-> web:3000 (Next.js + Mastra, Docker-private)
|
||||
-> api:5200 (Python Jyotish API, Docker-private)
|
||||
-> Swiss Ephemeris / local engine
|
||||
-> VedAstro gateway with local fallback
|
||||
-> Supabase Cloud
|
||||
-> external OpenAI-compatible model API
|
||||
```
|
||||
|
||||
`PORT` is set explicitly so the web service can reference the private API port. Railway healthchecks and the container command use the same value. No public API domain or legacy `jyotish-app/` service is needed.
|
||||
Only Caddy publishes host ports. Ports `3000` and `5200` must remain private.
|
||||
|
||||
## `web` variables
|
||||
## DNS and Supabase Auth
|
||||
|
||||
Required:
|
||||
Spaceship resource records:
|
||||
|
||||
```text
|
||||
A @ 103.117.123.53
|
||||
CNAME www jyotisha.chat
|
||||
```
|
||||
|
||||
Supabase Authentication URL Configuration:
|
||||
|
||||
```text
|
||||
Site URL: https://jyotisha.chat
|
||||
Redirect URLs: https://jyotisha.chat/**
|
||||
https://www.jyotisha.chat/**
|
||||
```
|
||||
|
||||
Before changing Caddy to the domain, verify the authoritative DNS result:
|
||||
|
||||
```bash
|
||||
dig +short @launch1.spaceship.net A jyotisha.chat
|
||||
```
|
||||
|
||||
It must return `103.117.123.53`. Caddy provisions and renews HTTPS automatically after DNS resolves.
|
||||
|
||||
## Production environment
|
||||
|
||||
`.env.production` combines the backend and frontend server variables. Required groups:
|
||||
|
||||
```dotenv
|
||||
JYOTISH_API_BASE=http://${{api.RAILWAY_PRIVATE_DOMAIN}}:${{api.PORT}}
|
||||
SITE_ADDRESS=https://jyotisha.chat
|
||||
JYOTISH_API_BASE=http://api:5200
|
||||
|
||||
NEXT_PUBLIC_SUPABASE_URL=...
|
||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=...
|
||||
SUPABASE_SERVICE_ROLE_KEY=...
|
||||
```
|
||||
ADMIN_EMAILS=...
|
||||
|
||||
For AI responses, configure either:
|
||||
|
||||
```dotenv
|
||||
# Either OpenAI:
|
||||
OPENAI_API_KEY=...
|
||||
MASTRA_MODEL=openai/gpt-5-mini
|
||||
```
|
||||
MASTRA_MODEL=...
|
||||
|
||||
or an OpenAI-compatible provider:
|
||||
|
||||
```dotenv
|
||||
# Or an OpenAI-compatible provider:
|
||||
LLM_BASE_URL=...
|
||||
LLM_API_KEY=...
|
||||
LLM_MODEL=...
|
||||
# LLM_PROVIDER_ID=third-party
|
||||
|
||||
# Optional VedAstro official upstream; local fallback remains available:
|
||||
VEDASTRO_API_ENDPOINT=...
|
||||
VEDASTRO_API_KEY=...
|
||||
```
|
||||
|
||||
`ADMIN_EMAILS=admin@example.com,ops@example.com` is required to use `/admin/codes`. Generate a public domain only for `web`.
|
||||
Never commit `.env.production`, `SUPABASE_SERVICE_ROLE_KEY`, model keys, user JWTs, SSH private keys or passwords. `NEXT_PUBLIC_SUPABASE_ANON_KEY` is intentionally public; authorization is enforced by Supabase RLS and server-side checks.
|
||||
|
||||
|
||||
## After the first deploy
|
||||
|
||||
1. Add the generated `web` domain to Supabase Auth **Site URL** and **Redirect URLs**.
|
||||
2. Open `/login`, sign in with an address listed in `ADMIN_EMAILS`, then verify `/admin/codes`.
|
||||
3. Keep `api` private; verify its `/api/health` from Railway logs or the `web` service.
|
||||
|
||||
## Small VPS deployment
|
||||
|
||||
For a single low-traffic server, keep Supabase managed and run only the Web and API services:
|
||||
## Connect and inspect
|
||||
|
||||
```bash
|
||||
docker compose --env-file .env.production -f deploy/docker-compose.server.yml up -d --build
|
||||
ssh -p 22000 root@103.117.123.53
|
||||
cd /opt/jyotisha-app
|
||||
COMPOSE='docker compose --env-file .env.production -f deploy/docker-compose.server.yml'
|
||||
$COMPOSE ps
|
||||
$COMPOSE logs --tail=100 api web caddy
|
||||
free -h
|
||||
docker stats --no-stream
|
||||
```
|
||||
|
||||
Set `SITE_ADDRESS=http://SERVER_IP` for initial HTTP testing. Replace it with the production domain after DNS resolves; Caddy will then provision HTTPS automatically.
|
||||
The server has a persistent 2 GB `/swapfile`. UFW permits only SSH `22000/tcp`, HTTP `80/tcp`, HTTPS `443/tcp`, and the pre-existing WireGuard `51820/udp` rule.
|
||||
|
||||
## Deploy an update from the maintainer Mac
|
||||
|
||||
The GitHub repository is private and the VPS does not currently have a GitHub deploy key. Deploy the tracked tree without copying local secrets:
|
||||
|
||||
```bash
|
||||
cd /Users/jesse/Downloads/Copse/astrology/yinduzhanxing
|
||||
git status --short --branch
|
||||
git archive --format=tar.gz --output=/tmp/jyotisha.tar.gz HEAD
|
||||
scp -P 22000 /tmp/jyotisha.tar.gz root@103.117.123.53:/tmp/jyotisha.tar.gz
|
||||
ssh -p 22000 root@103.117.123.53 \
|
||||
'cd /opt/jyotisha-app && tar -xzf /tmp/jyotisha.tar.gz && rm -f /tmp/jyotisha.tar.gz && docker compose --env-file .env.production -f deploy/docker-compose.server.yml up -d --build'
|
||||
```
|
||||
|
||||
`git archive` does not include ignored `.env` files. Extraction preserves `/opt/jyotisha-app/.env.production`.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
curl -fsS https://jyotisha.chat/login >/dev/null
|
||||
curl -fsS -o /dev/null -w '%{http_code}\n' https://jyotisha.chat/api/account
|
||||
```
|
||||
|
||||
The second command should return `401` while logged out. Verify the private Python API from inside the web container:
|
||||
|
||||
```bash
|
||||
ssh -p 22000 root@103.117.123.53 \
|
||||
'cd /opt/jyotisha-app && docker compose --env-file .env.production -f deploy/docker-compose.server.yml exec -T web node -e "fetch(\"http://api:5200/api/health\").then(async r=>{console.log(r.status); console.log(await r.text())})"'
|
||||
```
|
||||
|
||||
Expected: HTTP `200`, `"status": "ok"`, and `"swisseph_available": true`. Public access to `103.117.123.53:5200` must fail.
|
||||
|
||||
Then manually verify: OTP login, onboarding/profile persistence, chat-session persistence, code redemption, admin code generation, streaming response, one-credit charge, and refund on failure before the first output chunk.
|
||||
|
||||
## Common operations
|
||||
|
||||
```bash
|
||||
# Restart without rebuilding
|
||||
docker compose --env-file .env.production -f deploy/docker-compose.server.yml up -d
|
||||
|
||||
# Rebuild only the web container
|
||||
docker compose --env-file .env.production -f deploy/docker-compose.server.yml up -d --build web caddy
|
||||
|
||||
# Rebuild only the Python API
|
||||
docker compose --env-file .env.production -f deploy/docker-compose.server.yml up -d --build api
|
||||
|
||||
# Follow logs
|
||||
docker compose --env-file .env.production -f deploy/docker-compose.server.yml logs -f --tail=100 api web caddy
|
||||
```
|
||||
|
||||
## Optional Railway deployment
|
||||
|
||||
Railway is not the current production target. If needed, create `web` and `api` services from the same repository using `deploy/railway-web.Dockerfile` and `deploy/railway-api.Dockerfile`; keep `api` private and set the web service's `JYOTISH_API_BASE` to Railway's private API hostname.
|
||||
|
||||
+7
-1
@@ -216,7 +216,13 @@ supabase/migrations/20260715040000_agent_onboarding_cache.sql
|
||||
|
||||
相同兑换码只能兑换一次;首次兑换后会永久记录兑换账户、邮箱和时间。新注册用户默认 0 点,因此即使 demo URL 被转发,也不能在没有兑换码的情况下调用 Agent。
|
||||
|
||||
## Vercel + Supabase Demo 部署
|
||||
## 当前线上部署
|
||||
|
||||
当前生产 Demo 使用 `https://jyotisha.chat`,Next.js、Mastra 和 Python API 通过 Docker Compose 部署在香港 VPS,Supabase 与模型 API 继续使用云服务。服务器、DNS、环境变量、更新和验收命令统一以 [`../deploy/README.md`](../deploy/README.md) 为准。
|
||||
|
||||
## Vercel + Supabase 备选部署
|
||||
|
||||
以下方案只作为无服务器备选,不是当前线上拓扑。
|
||||
|
||||
### Web 部署到 Vercel
|
||||
|
||||
|
||||
Reference in New Issue
Block a user