Skip to content

Commit 72bf0a9

Browse files
authored
Merge pull request #18 from YuWei-CH/deployment
Deployment mode
2 parents 75c03f6 + e855572 commit 72bf0a9

35 files changed

+1753
-92
lines changed

.env.example

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,21 @@ OPENROUTER_MODEL="z-ai/glm-4.5-air:free"
3838

3939
# Optional: Database URL (default is an auto-created SQLite DB under backend/)
4040
# DATABASE_URL="sqlite+pysqlite:////absolute/path/to/easyrelocate.db"
41+
42+
# Optional: keep both local + cloud DB URLs, and select via EASYRELOCATE_DB.
43+
# EASYRELOCATE_DB="local" # local|cloud (default: local)
44+
# DATABASE_URL_LOCAL="sqlite+pysqlite:////absolute/path/to/easyrelocate.db"
45+
# DATABASE_URL_CLOUD="postgresql+psycopg://DB_USER:DB_PASSWORD@/DB_NAME?host=/cloudsql/INSTANCE_CONNECTION_NAME"
46+
47+
# Optional: CORS allowlist for browsers (comma-separated).
48+
# In production, set this to your Vercel domain(s).
49+
# CORS_ALLOW_ORIGINS="https://your-vercel-app.vercel.app,https://easyrelocate.yourdomain.com"
50+
51+
# Optional: Allow anonymous users to get a 30-day workspace token from the web UI.
52+
# Production note: enable only if you also add protection (rate limiting / bot protection).
53+
# ENABLE_PUBLIC_WORKSPACE_ISSUE="1"
54+
# PUBLIC_WORKSPACE_TTL_DAYS="30"
55+
56+
# Optional: Postgres (Cloud SQL / Cloud Run examples)
57+
# DATABASE_URL="postgresql+psycopg://DB_USER:DB_PASSWORD@/DB_NAME?host=/cloudsql/INSTANCE_CONNECTION_NAME"
58+
# DATABASE_URL="postgresql+psycopg://DB_USER:DB_PASSWORD@DB_HOST:5432/DB_NAME"

.env.server.example

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# EasyRelocate — server (Option B: self-hosted backend + Postgres + Caddy)
2+
#
3+
# Copy to `.env.server` on your server and fill in values:
4+
# cp .env.server.example .env.server
5+
#
6+
# Then deploy:
7+
# docker compose -f docker-compose.server.yml --env-file .env.server up -d --build
8+
#
9+
# Never commit `.env.server` (it contains secrets).
10+
11+
###############################################################################
12+
# Postgres (Docker)
13+
###############################################################################
14+
POSTGRES_DB="easyrelocate"
15+
POSTGRES_USER="easyrelocate"
16+
POSTGRES_PASSWORD="CHANGE_ME_STRONG_PASSWORD"
17+
18+
# Backend uses this DSN to connect to the Postgres container.
19+
DATABASE_URL="postgresql+psycopg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
20+
21+
###############################################################################
22+
# Backend (FastAPI)
23+
###############################################################################
24+
# CORS allowlist for your Vercel app and/or custom frontend domain.
25+
# Example:
26+
# CORS_ALLOW_ORIGINS="https://easyrelocate.vercel.app,https://easyrelocate.net"
27+
CORS_ALLOW_ORIGINS="https://YOUR_VERCEL_APP_DOMAIN"
28+
29+
# Enable self-serve tokens (onboarding token issuance)
30+
ENABLE_PUBLIC_WORKSPACE_ISSUE="1"
31+
PUBLIC_WORKSPACE_TTL_DAYS="30"
32+
33+
# Optional: Google Maps server-side geocoding
34+
# GOOGLE_MAPS_API_KEY="YOUR_SERVER_KEY"
35+
# GEOCODING_PROVIDER="google"
36+
# ENABLE_GEOCODING="1"
37+
38+
# Optional: OpenRouter LLM extraction for selected posts
39+
# OPENROUTER_API_KEY="YOUR_OPENROUTER_KEY"
40+
# OPENROUTER_MODEL="z-ai/glm-4.5-air:free"
41+

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dist/
2121

2222
# Env files (do not commit secrets)
2323
.env
24+
.env.server
2425
.env.local
2526
.env.*.local
2627
frontend/.env

README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ EasyRelocate is an open-source, non-commercial decision-support tool for housing
77

88
When relocating for an internship, research visit, or new job, housing information is often fragmented across multiple platforms, making comparison slow and error-prone. EasyRelocate helps users organize and compare housing options by focusing on what matters most: where to live, not where to book.
99

10-
Users collect listings while browsing platforms such as Airbnb, Blueground, Facebook Group using a lightweight browser extension (only support Google Chrom now). EasyRelocate then aggregates the minimal, user-authorized information needed to visualize listings on a single map and compare them by price, location, and commute time to a chosen workplace.
10+
Users collect listings while browsing platforms such as Airbnb, Blueground, Facebook Group using a lightweight browser extension (only supports Google Chrome for now). EasyRelocate then aggregates the minimal, user-authorized information needed to visualize listings on a single map and compare them by price, location, and commute time to a chosen workplace.
1111

1212
EasyRelocate does not scrape platforms server-side, host listings, process payments, or replace original marketplaces. It exists solely to help users make better relocation decisions, while respecting platform boundaries and directing all final actions back to the original sources.
1313

1414
## Repo structure
15-
- `backend/`: FastAPI + SQLite API
16-
- `frontend/`: React (Vite) web app (Google Maps JS map + routing, US-only for now)
15+
- `backend/`: FastAPI API (SQLite for local dev; Postgres supported via `DATABASE_URL`)
16+
- `frontend/`: React (Vite) web app (Google Maps JS map + routing)
1717
- `extension/`: Chrome extension (Manifest V3) for user-side extraction
1818

1919
## Configuration (API keys & env vars)
@@ -46,21 +46,45 @@ Backend reads standard env vars (auto-loads repo-root `.env` on startup):
4646
GOOGLE_MAPS_API_KEY="YOUR_SERVER_KEY"
4747
GEOCODING_PROVIDER="google"
4848

49-
# Rrequired for the extension’s “Add selected post” feature
49+
# Required for the extension’s “Add selected post” feature
5050
OPENROUTER_API_KEY="YOUR_OPENROUTER_KEY"
5151
OPENROUTER_MODEL="z-ai/glm-4.5-air:free"
5252

5353
# Optional
5454
ENABLE_GEOCODING="1"
5555
DATABASE_URL="sqlite:///easyrelocate.db"
56+
57+
# Optional (comma-separated)
58+
# CORS_ALLOW_ORIGINS="https://your-vercel-app.vercel.app,https://easyrelocate.yourdomain.com"
59+
```
60+
61+
## Workspaces (tokens, no user accounts)
62+
EasyRelocate uses **admin-created workspace tokens** instead of a user login system. All API calls (except `/api/health`) require:
63+
`Authorization: Bearer <workspace_token>`.
64+
65+
Create a token (local dev / admin):
66+
```bash
67+
cd backend
68+
python scripts/create_workspace.py
5669
```
5770

71+
Optional (self-serve onboarding): enable `ENABLE_PUBLIC_WORKSPACE_ISSUE=1` on the backend, then the web UI can issue a 30-day token automatically via `POST /api/workspaces/issue` (see `docs/DEPLOYMENT.md`).
72+
73+
Then paste `workspace_token` into:
74+
- Web app: Compare page → **Workspace** panel → Save
75+
- Chrome extension: Extension options → **Workspace token** → Save
76+
5877
### Chrome Extension (for developer)
5978
The extension does not read `.env` files. Configure its API base URL in Chrome:
60-
Extension → **Details****Extension options** → “API base URL” (default: `http://127.0.0.1:8000`).
79+
Extension → **Details****Extension options** → “API base URL” + “Workspace token”.
6180

6281
## Local dev
6382

83+
### Quick start (backend + frontend)
84+
```bash
85+
./easyDeploy.sh --db local
86+
```
87+
6488
### 1) Backend API
6589
```bash
6690
cd backend
@@ -84,7 +108,7 @@ Open: `http://127.0.0.1:5173` (landing page)
84108
Compare app: `http://127.0.0.1:5173/#/compare`
85109

86110
Set your workplace target by:
87-
- Typing an address (US) and clicking **Save**, or
111+
- Typing an address and clicking **Save**, or
88112
- Clicking **Pick on map** and then clicking the map, then **Save**
89113

90114
### 3) Browser extension (Chrome)
@@ -113,3 +137,4 @@ See: `docs/GOOGLE_MAPS_APPROX_LOCATION.md`
113137
- Platform organization: `docs/PLATFORM_ORGANIZATION.md`
114138
- Google maps “approx street”: `docs/GOOGLE_MAPS_APPROX_LOCATION.md`
115139
- OpenRouter LLM extraction: `docs/OPENROUTER_LLM_EXTRACTION.md`
140+
- Deployment runbook (GCP managed + self-hosted): `docs/DEPLOYMENT.md`

backend/Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM python:3.11-slim
2+
3+
ENV PYTHONDONTWRITEBYTECODE=1 \
4+
PYTHONUNBUFFERED=1
5+
6+
WORKDIR /app
7+
8+
COPY requirements.txt /app/requirements.txt
9+
RUN pip install --no-cache-dir -r /app/requirements.txt
10+
11+
COPY app /app/app
12+
COPY scripts /app/scripts
13+
14+
EXPOSE 8000
15+
16+
CMD ["python", "-m", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
17+

backend/README.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33
## Prereqs
44
- Python 3.11+
55

6+
## Auth (workspaces, no user accounts)
7+
EasyRelocate uses **admin-created workspace tokens** instead of a user login system.
8+
9+
All API calls (except `GET /api/health`) require:
10+
`Authorization: Bearer <workspace_token>`.
11+
12+
Create a token:
13+
```bash
14+
cd backend
15+
python scripts/create_workspace.py
16+
```
17+
18+
Optional (self-serve onboarding): set `ENABLE_PUBLIC_WORKSPACE_ISSUE=1` and the web UI can call
19+
`POST /api/workspaces/issue` to create a 30-day token (protect this endpoint in production).
20+
621
## Setup
722
```bash
823
python -m venv .venv
@@ -29,7 +44,7 @@ API docs:
2944

3045
## Geocoding (Nominatim / OpenStreetMap)
3146
The backend can:
32-
- Geocode a target address → lat/lng (US-only by default)
47+
- Geocode a target address → lat/lng
3348
- Reverse-geocode lat/lng → a rough location string (city/state)
3449

3550
Endpoints:
@@ -39,13 +54,14 @@ Endpoints:
3954
Env vars:
4055
- `ENABLE_GEOCODING` (default `1`)
4156
- `ENABLE_LISTING_GEOCODE_FALLBACK` (default `0`, if `1` will approximate coords from listing city/region)
42-
- `GEOCODING_COUNTRY_CODES` (default `us`)
57+
- `GEOCODING_COUNTRY_CODES` (optional; defaults are provider-specific)
4358
- `GEOCODING_PROVIDER` (optional: `google` or `nominatim`)
4459
- `GOOGLE_MAPS_API_KEY` (optional; if set, geocoding defaults to Google)
4560
- `GEOCODING_USER_AGENT` (default `EasyRelocate/0.1 (local dev)`)
4661
- `NOMINATIM_BASE_URL` (default `https://nominatim.openstreetmap.org`)
4762
- `GEOCODING_TIMEOUT_S` (default `6`)
48-
- `DATABASE_URL` (optional; defaults to `backend/easyrelocate.db`)
63+
- `DATABASE_URL` (optional; defaults to `backend/easyrelocate.db`)
64+
- `CORS_ALLOW_ORIGINS` (optional; comma-separated allowlist for browsers)
4965

5066
### Google setup requirements
5167
If you use Google geocoding (`GEOCODING_PROVIDER=google` or `GOOGLE_MAPS_API_KEY` is set):
@@ -69,3 +85,7 @@ Env vars:
6985
- `OPENROUTER_TIMEOUT_S` (optional)
7086

7187
Details: `docs/OPENROUTER_LLM_EXTRACTION.md`
88+
89+
## Production database (Cloud SQL Postgres)
90+
Cloud Run instances are ephemeral. For production, set `DATABASE_URL` to Postgres (Cloud SQL).
91+
See: `docs/DEPLOYMENT.md`.

0 commit comments

Comments
 (0)