From 58b2e4af93415f48d71d81d39b8f6801cf36e418 Mon Sep 17 00:00:00 2001 From: Gitead Date: Wed, 20 May 2026 23:25:44 -0400 Subject: [PATCH] docs: add Cloudflare tunnel setup guide and ports reference Add step-by-step Cloudflare tunnel setup to README.md with Summit Dental Care as a multi-office example. Create docs/ports.md documenting all service hosts and ports. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 156 +++++++++++++++++++++++++++++++++++++++++++++++++- docs/ports.md | 84 +++++++++++++++++++++++++++ 2 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 docs/ports.md diff --git a/README.md b/README.md index 5c2cda47..421438c6 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ cd apps/SeleniumService ## 📖 Developer Documentation - [Setting up server environment](docs/server-setup.md) — the first step, to run this app in environment. -- [Development Hosts & Ports](docs/ports.md) — which app runs on which host/port +- [Development Hosts & Ports](docs/ports.md) — which app runs on which host/port, and how to configure `.env` for LAN or single-device access --- @@ -195,3 +195,157 @@ Each package/app is 100% [TypeScript](https://www.typescriptlang.org/) (except t - [TypeScript](https://www.typescriptlang.org/) for static type checking - [ESLint](https://eslint.org/) for code linting - [Prettier](https://prettier.io) for code formatting + +--- + +## Cloudflare Tunnel Setup (Remote Access per Office) + +This connects each office's local app to a public subdomain via a Cloudflare Tunnel — no port forwarding needed, local network access is unchanged. + +**How it works:** +- Local network: other office PCs reach the app directly at `http://:3000` +- Internet: anyone reaches the app via `https://.mydentalofficemanagement.com` +- Both paths hit the same app simultaneously with no conflict + +--- + +### Step 1 — Add domain to Cloudflare (done once for all offices) + +> Skip this step if the domain is already on Cloudflare. + +1. Go to `dash.cloudflare.com` → **Add a site** → enter `mydentalofficemanagement.com` (free plan) +2. Cloudflare scans existing DNS records — review and keep them +3. Cloudflare gives you 2 nameservers (e.g. `holly.ns.cloudflare.com`, `amir.ns.cloudflare.com`) +4. Log into **Ionos** → replace the domain's nameservers with Cloudflare's two +5. Wait 10–30 min → Cloudflare emails you when active +6. DNSSEC: if not purchased on Ionos, it was never enabled — nothing to turn off + +### Step 2 — Install `cloudflared` on the office PC + +Run this in a terminal on the office machine: + +```bash +curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb +sudo dpkg -i cloudflared.deb +cloudflared --version +``` + +### Step 3 — Authenticate with Cloudflare + +```bash +cloudflared tunnel login +``` + +A browser window opens → click `mydentalofficemanagement.com` → terminal shows success and saves a certificate to `~/.cloudflared/cert.pem`. + +### Step 4 — Create a tunnel for this office + +Use a unique tunnel name per office: + +```bash +cloudflared tunnel create +# Example: cloudflared tunnel create summit-dental-app +``` + +Note the **tunnel ID** (UUID) printed — you need it in Step 5. + +### Step 5 — Create the config file + +```bash +sudo mkdir -p /etc/cloudflared +sudo nano /etc/cloudflared/config.yml +``` + +Paste (replace tunnel ID, credentials path, and subdomain for this office): + +```yaml +tunnel: +credentials-file: /home/ee/.cloudflared/.json + +ingress: + - hostname: .mydentalofficemanagement.com + service: http://localhost:3000 + - service: http_status:404 +``` + +Save: `Ctrl+O` → Enter → `Ctrl+X`. + +### Step 6 — Route DNS for this office's subdomain + +```bash +cloudflared tunnel route dns .mydentalofficemanagement.com +``` + +### Step 7 — Install as a system service (auto-starts on boot) + +```bash +sudo cloudflared service install +sudo systemctl enable cloudflared +sudo systemctl start cloudflared +sudo systemctl status cloudflared +``` + +### Step 8 — Allow the subdomain in Vite + +In `apps/Frontend/vite.config.js`, add the subdomain to `server.allowedHosts` so Vite does not block external requests. + +### Step 9 — Allow the subdomain in backend CORS + +In `apps/Backend`, add the subdomain URL to the allowed CORS origins so login and API calls work from the public URL. + +--- + +### Example — Adding Summit Dental Care + +**Office subdomain:** `summitdentalcare.mydentalofficemanagement.com` + +**Step 1:** Already done (domain is on Cloudflare). + +**Step 2:** Install `cloudflared` on Summit Dental's PC. + +**Step 3:** Run `cloudflared tunnel login` on Summit Dental's PC. + +**Step 4:** +```bash +cloudflared tunnel create summit-dental-app +# Example output: Created tunnel summit-dental-app with id a1b2c3d4-... +``` + +**Step 5 — `/etc/cloudflared/config.yml`:** +```yaml +tunnel: a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx +credentials-file: /home/ee/.cloudflared/a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json + +ingress: + - hostname: summitdentalcare.mydentalofficemanagement.com + service: http://localhost:3000 + - service: http_status:404 +``` + +**Step 6:** +```bash +cloudflared tunnel route dns summit-dental-app summitdentalcare.mydentalofficemanagement.com +``` + +**Step 7:** +```bash +sudo cloudflared service install +sudo systemctl enable cloudflared +sudo systemctl start cloudflared +``` + +**Step 8:** Add `summitdentalcare.mydentalofficemanagement.com` to `allowedHosts` in `vite.config.js`. + +**Step 9:** Add `https://summitdentalcare.mydentalofficemanagement.com` to backend CORS allowed origins. + +--- + +### Multi-office overview + +Each office runs its own `cloudflared` tunnel on its own PC. Ports never conflict because each PC is a separate machine. + +| Office | Local access | Public access | Tunnel name | +|---|---|---|---| +| Community Dentists of Lowell | `http://192.168.1.236:3000` | `https://communitydentistsoflowell.mydentalofficemanagement.com` | `dental-app` | +| Summit Dental Care | `http://:3000` | `https://summitdentalcare.mydentalofficemanagement.com` | `summit-dental-app` | +| Next office | `http://:3000` | `https://.mydentalofficemanagement.com` | `-app` | diff --git a/docs/ports.md b/docs/ports.md new file mode 100644 index 00000000..c6a6f958 --- /dev/null +++ b/docs/ports.md @@ -0,0 +1,84 @@ +# Development Hosts & Ports + +This document defines the default **host** and **port** used by each app/service +in this turborepo. +Update this file whenever a new service is added or port is changed. + +--- + +## Frontend (React + Vite) +- **Host:** `localhost` (default) + - Use `0.0.0.0` if you need LAN access (phone/other device on same Wi-Fi). +- **Port:** `3000` +- **Access URLs:** + - Local: [http://localhost:3000](http://localhost:3000) + - LAN: `http://:3000` (only if HOST=0.0.0.0) + +**Current setup:** +Frontend is running on `0.0.0.0` and is accessible via the device IP. + +**`.env` file:** +```env +NODE_ENV=development +HOST=0.0.0.0 +PORT=3000 +VITE_API_BASE_URL_BACKEND=http://192.168.1.8:5000 +``` + +`VITE_API_BASE_URL_BACKEND` must point to the backend's IP/port as seen from the browser. +Use `localhost` if only accessing from the same machine, or the machine's LAN IP for access from other devices. + +--- + +## Backend (Express.js) +- **Host:** `0.0.0.0` (all interfaces) +- **Port:** `5000` +- **Access URL:** [http://localhost:5000](http://localhost:5000) + +**Current setup:** +Runs on all interfaces and allows configured frontend URLs via CORS. Change `FRONTEND_URLS` to match your setup. + +**`.env` file:** +```env +NODE_ENV="development" +HOST=0.0.0.0 +PORT=5000 +FRONTEND_URLS=http://localhost:3000,http://192.168.1.8:3000 +``` + +--- + +## Patient Data Extractor Service +- **Host:** `localhost` +- **Port:** `5001` +- **Access URL:** [http://localhost:5001](http://localhost:5001) + +--- + +## Selenium Service +- **Host:** `localhost` +- **Port:** `5002` +- **Access URL:** [http://localhost:5002](http://localhost:5002) + +--- + +## Payment OCR Service +- **Host:** `localhost` +- **Port:** `5003` +- **Access URL:** [http://localhost:5003](http://localhost:5003) + +--- + +## Notes +- `HOST` controls binding: `localhost` = loopback only, `0.0.0.0` = all interfaces (LAN accessible). +- `PORT` controls the service's port. Ports never conflict across separate machines — two office PCs can both run on port 5000 with no issue. +- Frontend uses `VITE_` prefixed variables for client-side access (e.g. `VITE_API_BASE_URL_BACKEND`). +- In production, traffic is routed through Cloudflare Tunnel — see [Cloudflare Tunnel Setup](../README.md#cloudflare-tunnel-setup-remote-access-per-office) in the main README. + +--- + +**Action for developers:** +1. Copy `.env.example` → `.env` inside each app folder. +2. Adjust `HOST` / `PORT` if your ports are already taken. +3. Set `VITE_API_BASE_URL_BACKEND` to the backend's LAN IP if accessing from other devices. +4. Run `npm run dev` from the repo root.