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 <noreply@anthropic.com>
This commit is contained in:
156
README.md
156
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://<machine-ip>:3000`
|
||||
- Internet: anyone reaches the app via `https://<subdomain>.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 <office-tunnel-name>
|
||||
# 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: <tunnel-ID>
|
||||
credentials-file: /home/ee/.cloudflared/<tunnel-ID>.json
|
||||
|
||||
ingress:
|
||||
- hostname: <subdomain>.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 <office-tunnel-name> <subdomain>.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://<its-ip>:3000` | `https://summitdentalcare.mydentalofficemanagement.com` | `summit-dental-app` |
|
||||
| Next office | `http://<its-ip>:3000` | `https://<subdomain>.mydentalofficemanagement.com` | `<office>-app` |
|
||||
|
||||
Reference in New Issue
Block a user