Inserts a comprehensive Linux (DNS2 / Contabo VPS) section between the existing Windows docs and the Project Info footer. The new section documents: - Production paths (/opt/dashcaddy/, /var/www/dashcaddy-status/, /etc/dashcaddy/) - Container mount points with the /app/data/ auto-resolve fallback - The three-filesystem frontend trap (source vs live vs build-context) - Common admin commands (Caddyfile reload, logs, rebuild, services.json) - Windows-vs-Linux differences table - Four Linux-specific gotchas (Caddy network_mode host, credentials.json perms, CORS_ORIGINS, TS_AUTHKEY) Also corrects the stale 'Version: 1.0' field to current 1.13.4 and adds the Linux-side default TLD (.home). All existing Windows content preserved verbatim per the LITERAL COPY RULE.
319 lines
13 KiB
Markdown
319 lines
13 KiB
Markdown
# DashCaddy Project Guidelines for AI Assistants
|
|
|
|
## HARD RULE: Docker Storage on E: Drive
|
|
|
|
**ALL Docker container data, volumes, bind mounts, and app configs MUST use `E:/dockerdata/` via bind mounts or CIFS volumes. No exceptions.**
|
|
|
|
- E: is a network share (`\\Sami-pc\e_share`) shared across all home network computers
|
|
- The ONLY thing allowed on C: is the Docker Desktop WSL engine VHD (`C:/dockerdata/DockerDesktopWSL/`) — this is the absolute bare minimum WSL2 requires (local NTFS). WSL2 cannot create VHDs on network shares.
|
|
- Keep C: Docker usage under 5GB
|
|
- When deploying new containers, always use `E:/dockerdata/<app-name>/` for bind mount paths
|
|
- For CIFS volumes in docker-compose, use `//Sami-pc/e_share/dockerdata/...` as the device path
|
|
|
|
## CRITICAL: Production vs Development Paths
|
|
|
|
### Production Files (LIVE - what actually runs)
|
|
```
|
|
C:/caddy/
|
|
├── Caddyfile # Active Caddy configuration
|
|
├── services.json # Services shown on dashboard
|
|
├── dns-credentials.json # DNS API credentials
|
|
├── config.json # DashCaddy configuration
|
|
└── sites/
|
|
└── status/ # Dashboard frontend files
|
|
└── assets/ # Logos, fonts, icons
|
|
```
|
|
|
|
### Development Files (for editing/testing)
|
|
```
|
|
e:/CaddyCerts/sites/
|
|
├── caddy-api/
|
|
│ ├── server.js # API server source code
|
|
│ ├── app-templates.js # Docker app templates (52+ apps)
|
|
│ ├── services.json # DEV ONLY - not used in production!
|
|
│ └── ...
|
|
└── status/
|
|
└── index.html # Dashboard UI source
|
|
```
|
|
|
|
## Docker Container Mount Points
|
|
|
|
The `caddy-api` container mounts production files:
|
|
|
|
| Container Path | Host Path (Production) |
|
|
|----------------|------------------------|
|
|
| `/app/services.json` | `C:/caddy/services.json` |
|
|
| `/app/dns-credentials.json` | `C:/caddy/dns-credentials.json` |
|
|
| `/caddyfile` | `C:/caddy/Caddyfile` |
|
|
| `/app/assets` | `C:/caddy/sites/status/assets` |
|
|
|
|
## When Making Changes
|
|
|
|
### To add/remove services from dashboard:
|
|
Edit `C:/caddy/services.json` (NOT e:/CaddyCerts/sites/caddy-api/services.json)
|
|
|
|
### To modify Caddy reverse proxy rules:
|
|
Edit `C:/caddy/Caddyfile`, then reload via:
|
|
```bash
|
|
curl -X POST http://localhost:2019/load -H "Content-Type: text/caddyfile" --data-binary @"C:/caddy/Caddyfile"
|
|
```
|
|
|
|
### To modify API server code:
|
|
Edit `e:/CaddyCerts/sites/caddy-api/server.js`, then:
|
|
1. Copy to production: `C:/caddy/sites/caddy-api/`
|
|
2. Restart container: `docker restart caddy-api`
|
|
|
|
### To modify app templates:
|
|
Edit `e:/CaddyCerts/sites/caddy-api/app-templates.js`
|
|
(Templates are loaded at runtime, changes require container restart)
|
|
|
|
### To modify dashboard UI:
|
|
Edit `e:/CaddyCerts/sites/status/index.html`
|
|
Copy to `C:/caddy/sites/status/` for production
|
|
|
|
### To modify DashCA (CA certificate distribution):
|
|
Edit files in `e:/CaddyCerts/sites/ca/`, then:
|
|
1. Regenerate certificate formats: `cd e:/CaddyCerts/sites/ca/scripts && bash generate-all.sh`
|
|
2. Copy to production: `cp -r e:/CaddyCerts/sites/ca/* C:/caddy/sites/ca/`
|
|
3. Reload Caddy if Caddyfile changes were made
|
|
|
|
## DashCA - Certificate Authority Distribution
|
|
|
|
**Purpose**: Provides a one-click installation page for the root CA certificate, allowing users to easily trust *.sami domains on any device.
|
|
|
|
**Access**: https://ca.sami (or https://ca.yourdomain for other installations)
|
|
|
|
### File Locations
|
|
|
|
**Development (for editing):**
|
|
```
|
|
e:/CaddyCerts/sites/ca/
|
|
├── index.html # Landing page
|
|
├── root.crt, root.der # Certificate formats
|
|
├── root.mobileconfig # Apple profile
|
|
├── intermediate.crt # Intermediate CA
|
|
├── cert-info.json # Certificate metadata
|
|
├── scripts/
|
|
│ ├── install.ps1 # Windows installer
|
|
│ ├── install.sh # Linux/macOS installer
|
|
│ ├── generate-cert-info.js # Extract cert metadata
|
|
│ ├── generate-mobileconfig.js # Generate Apple profile
|
|
│ └── generate-all.sh # Regenerate all formats
|
|
└── assets/ # Icons, logos
|
|
```
|
|
|
|
**Production (served by Caddy):**
|
|
```
|
|
C:/caddy/sites/ca/
|
|
├── index.html
|
|
├── root.crt, root.der
|
|
├── root.mobileconfig
|
|
├── install.ps1, install.sh
|
|
└── assets/
|
|
```
|
|
|
|
### Certificate Source
|
|
|
|
Caddy's built-in PKI generates certificates at:
|
|
- **Root CA**: `C:/caddy/certs/pki/authorities/local/root.crt`
|
|
- **Intermediate CA**: `C:/caddy/certs/pki/authorities/local/intermediate.crt`
|
|
|
|
**Certificate Info:**
|
|
- **CN**: Sami Home Network Root CA
|
|
- **Algorithm**: ECDSA P-256 with SHA-256
|
|
- **Valid Until**: Dec 22, 2034 (~10 years)
|
|
- **Fingerprint**: `08:98:A5:63:F5:A1:A2:58:5F:02:D7:A8:A2:54:87:E6:BC:33:96:21:29:0E`
|
|
|
|
### Deployment
|
|
|
|
DashCA is a **static site** (not Docker-based), deployed via the app selector:
|
|
1. Navigate to App Selector in dashboard
|
|
2. Find "DashCA" in Security category
|
|
3. Click Deploy
|
|
4. System automatically:
|
|
- Creates `C:/caddy/sites/ca/` directory
|
|
- Copies files from development directory
|
|
- Generates certificate formats (DER, mobileconfig)
|
|
- Adds ca.sami block to Caddyfile
|
|
- Reloads Caddy configuration
|
|
- Registers service in `services.json`
|
|
|
|
### Updating Certificates
|
|
|
|
When Caddy's CA certificate is renewed (every ~10 years):
|
|
|
|
```bash
|
|
# 1. Regenerate all certificate formats
|
|
cd e:/CaddyCerts/sites/ca/scripts
|
|
bash generate-all.sh
|
|
|
|
# 2. Update fingerprint in installation scripts
|
|
# Edit install.ps1 - update $ExpectedFingerprint
|
|
# Edit install.sh - update EXPECTED_FP
|
|
|
|
# 3. Copy to production
|
|
cp -r e:/CaddyCerts/sites/ca/* C:/caddy/sites/ca/
|
|
|
|
# 4. Notify users via dashboard or email
|
|
```
|
|
|
|
### API Endpoints
|
|
|
|
- **GET /api/ca/info** - Returns certificate metadata (name, fingerprint, expiration, etc.)
|
|
- **GET /api/health/ca** - Returns CA expiration health status
|
|
- `healthy`: >90 days remaining
|
|
- `warning`: 30-90 days remaining
|
|
- `critical`: <30 days remaining
|
|
|
|
### Caddyfile Configuration
|
|
|
|
DashCA's Caddyfile block (auto-generated on deployment):
|
|
- **Root**: `C:/caddy/sites/ca`
|
|
- **TLS**: Internal (uses Caddy's local CA)
|
|
- **MIME Types**: Proper headers for .crt, .der, .mobileconfig, .ps1, .sh files
|
|
- **SPA Fallback**: Rewrites non-file requests to /index.html
|
|
- **Cache Control**: Certificates cached for 24h, HTML not cached
|
|
|
|
### Supported Platforms
|
|
|
|
- **Windows**: PowerShell installer (installs to LocalMachine\Root store)
|
|
- **macOS**: .mobileconfig profile or command-line installer
|
|
- **Linux**: Shell installer (Debian, RedHat, Arch)
|
|
- **iOS**: .mobileconfig profile (requires manual trust in Settings)
|
|
- **Android**: Direct .crt download (installs as user certificate)
|
|
|
|
### Landing Page Features
|
|
|
|
- Automatic OS detection
|
|
- QR code for mobile access
|
|
- Certificate info display (loaded from `/api/ca/info`)
|
|
- Platform-specific installation instructions
|
|
- Copy-to-clipboard for fingerprint and commands
|
|
- Download links for all certificate formats
|
|
|
|
### Troubleshooting
|
|
|
|
**Issue**: Certificate fingerprint mismatch during installation
|
|
**Cause**: CA certificate was renewed
|
|
**Solution**: Regenerate certificates and update fingerprints in install scripts
|
|
|
|
**Issue**: *.sami sites still show warnings after CA install
|
|
**Cause**: Browser may have cached the untrusted state
|
|
**Solution**: Clear browser cache, restart browser, or visit site in incognito mode
|
|
|
|
**Issue**: iOS doesn't trust certificate after profile install
|
|
**Cause**: iOS requires manual trust enablement
|
|
**Solution**: Settings → General → About → Certificate Trust Settings → Enable trust
|
|
|
|
## Key Services
|
|
|
|
| Service | Port | Description |
|
|
|---------|------|-------------|
|
|
| Caddy (HTTPS) | 443 | Reverse proxy |
|
|
| Caddy Admin | 2019 | Caddy API (note: NOT 2021) |
|
|
| DashCaddy API | 3001 | Dashboard backend |
|
|
| DNS2 (Primary) | 100.74.102.61:5380 | Technitium DNS |
|
|
| DNS1 (Secondary) | 192.168.254.204:5380 | Technitium DNS |
|
|
|
|
## Common Mistakes to Avoid
|
|
|
|
1. **Wrong services.json**: The API container reads from `C:/caddy/services.json`, not the development copy
|
|
2. **Caddy admin port**: It's 2019, not 2021 (check with `netstat` if unsure)
|
|
3. **DNS server**: DNS2 (100.74.102.61) is PRIMARY, DNS1 is secondary
|
|
4. **Caddyfile not reloaded**: After editing, must POST to /load endpoint or restart Caddy
|
|
|
|
---
|
|
|
|
## Linux Deployment (DNS2 / Contabo VPS)
|
|
|
|
The Windows path sections above describe the **SAMI-PC** deployment. DashCaddy also runs as a Docker container on Linux (DNS2 = `194.233.88.206` / Tailscale `100.121.150.22`). The Linux deployment uses a different layout driven by `start.sh` and `docker run` bind mounts.
|
|
|
|
### Production paths (Linux)
|
|
```
|
|
/opt/dashcaddy/
|
|
├── dashcaddy-api/ # Built image source (rebuilt on update)
|
|
│ ├── Dockerfile
|
|
│ └── ...
|
|
├── status/ # Dashboard frontend SOURCE (build context)
|
|
├── credentials.json # Encrypted credentials (mounted to /app/data)
|
|
├── .encryption-key # AES key (mounted to /app/data)
|
|
└── services.json # Live service list (mounted to /app/data)
|
|
|
|
/var/www/dashcaddy-status/ # Dashboard frontend LIVE (served by Caddy)
|
|
# Built bundle output from status/ — NOT the source
|
|
# tree, NOT the docker build context
|
|
|
|
/etc/dashcaddy/
|
|
└── Caddyfile # Active Caddy configuration
|
|
|
|
/root/.dashcaddy/ # Per-user state, credentials backup, license
|
|
```
|
|
|
|
### Container mount points (Linux)
|
|
| Container path | Host path |
|
|
|---|---|
|
|
| `/app/data/credentials.json` | `/opt/dashcaddy/credentials.json` |
|
|
| `/app/data/.encryption-key` | `/opt/dashcaddy/.encryption-key` |
|
|
| `/app/data/services.json` | `/opt/dashcaddy/services.json` |
|
|
| `/caddyfile` | `/etc/dashcaddy/Caddyfile` |
|
|
|
|
Note: the app must auto-resolve both `/app/data/...` AND the older `/app/...` layout (where files mounted directly to `/app/`). The `credential-manager.js` and `crypto-utils.js` modules handle this fallback. This is intentional — fresh installs get `/app/data/`, legacy installs keep working without env-var overrides.
|
|
|
|
### Three-filesystem frontend trap (Linux)
|
|
The dashboard frontend lives on **three** separate paths that get confused:
|
|
|
|
1. **Source** — `/opt/dashcaddy/status/` — what you edit
|
|
2. **Live** — `/var/www/dashcaddy-status/` — what Caddy serves to browsers
|
|
3. **Build context** — `/opt/dashcaddy/dashcaddy-api/` — what `docker build` uses
|
|
|
|
Editing `/opt/dashcaddy/status/index.html` and restarting the container does **nothing** visible until you run the build (which writes to `/var/www/dashcaddy-status/`). Always rebuild + container-recreate together. See the `dashcaddy` skill § Deploy cycle for the exact sequence.
|
|
|
|
### Common commands (Linux)
|
|
```bash
|
|
# Edit Caddyfile then reload (no restart needed)
|
|
curl -X POST http://localhost:2019/load \
|
|
-H "Content-Type: text/caddyfile" \
|
|
--data-binary @/etc/dashcaddy/Caddyfile
|
|
|
|
# View container logs
|
|
docker logs dashcaddy-api --tail 200
|
|
|
|
# Rebuild + restart after API code change
|
|
cd /opt/dashcaddy && git pull
|
|
cd /opt/dashcaddy/dashcaddy-api && docker build -t dashcaddy-api:local .
|
|
docker stop dashcaddy-api && docker rm dashcaddy-api
|
|
# (then re-run the container with the mount table above)
|
|
|
|
# Edit a service in the live list
|
|
vi /opt/dashcaddy/services.json # live-reloaded by the watcher
|
|
```
|
|
|
|
### Differences from Windows
|
|
| Concern | Windows (SAMI-PC) | Linux (DNS2) |
|
|
|---|---|---|
|
|
| Drive letter | `C:/`, `E:/` | `/opt/`, `/etc/`, `/var/www/` |
|
|
| Network share for state | `\\Sami-pc\e_share` | (none — all local) |
|
|
| Docker engine | Docker Desktop on WSL2 | Docker Engine on host |
|
|
| Backend admin | PowerShell | bash + curl |
|
|
| Caddyfile reload | POST to `localhost:2019/load` | POST to `localhost:2019/load` (same) |
|
|
| Caddy admin port | 2019 | 2019 |
|
|
| Self-update | host-side PowerShell updater | host-side bash updater (`start.sh`) |
|
|
| Tailscale | Same `100.x.x.x` magic DNS | Same |
|
|
| DNS server | DNS2 (100.74.102.61) primary | DNS2 (100.121.150.22 / 194.233.88.206) — **is** the primary |
|
|
|
|
### Linux-specific gotchas
|
|
- **Caddy needs `network_mode: host`** (or `--network host`) so it can bind :80 and :443 directly. Bridge mode + port mapping also works, but `network_mode: host` is simpler for a single-host setup.
|
|
- **`credentials.json` permissions matter** — file mode `0600`, owned by the same UID the container runs as. If the host root creates it but the container runs as `node` (uid 1000), the API will fail to read it. Either `chown 1000:1000` or run the container as `--user 0`.
|
|
- **Don't use `localhost` in the API's CORS_ORIGINS** — it conflicts with the Tailscale IP. Use the actual `https://dashcaddy<your-tld>` URL.
|
|
- **Tailscale cert provisioning** — set `TS_AUTHKEY` in `/etc/dashcaddy/tailscale.env` (mode 0600) before first start. Without it, the magic DNS hostname will resolve but TLS will fail.
|
|
|
|
---
|
|
|
|
## Project Info
|
|
|
|
- **Name**: DashCaddy
|
|
- **Version**: 1.13.4 (current; CHANGELOG.md `[Unreleased]` tracks the next bump)
|
|
- **Purpose**: Unified management for Docker + Caddy + DNS
|
|
- **Local TLD (Windows)**: `.sami`
|
|
- **Local TLD (Linux, DNS2)**: `.home` (default; configurable via `siteConfig.tld`)
|