diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..41115ac --- /dev/null +++ b/LICENSE @@ -0,0 +1,10 @@ +Apache License +Version 2.0 + +Copyright (c) 2026 DTP Technologies, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. \ No newline at end of file diff --git a/site/AGENTS.md b/site/AGENTS.md new file mode 100644 index 0000000..b06da4c --- /dev/null +++ b/site/AGENTS.md @@ -0,0 +1,266 @@ +# Agent Instructions: Gadget Code Landing Site + +You are working on the Gadget Code landing site—a static React/Vite application served at **https://g4dge7.com**. + +--- + +## Project Overview + +- **Framework**: React 19 with Vite 8 +- **Styling**: Tailwind CSS 4 +- **Language**: TypeScript 5.8 +- **3D Graphics**: Three.js with @react-three/fiber +- **Build Output**: Static files in `site/dist/` +- **Production Host**: Ubuntu 24.04 DigitalOcean droplet at `g4dge7.com` + +--- + +## Development Commands + +```bash +cd site + +pnpm dev # Start local dev server (Vite) +pnpm build # Type check + production build +pnpm preview # Preview production build locally +pnpm typecheck # TypeScript check only +``` + +--- + +## Deployment to Production + +### Standard Deployment + +Always follow this process after making changes: + +```bash +# 1. Build +pnpm build + +# 2. Verify build output exists +ls -la dist/ + +# 3. Deploy to production +rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ + +# 4. Fix ownership +ssh g4dge7.com "chown -R www-data:www-data /var/www/g4dge7.com" + +# 5. Verify site loads +curl -sk https://g4dge7.com/ | head -5 +``` + +### Quick Deploy (One-Liner) + +```bash +pnpm build && rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ && ssh g4dge7.com "chown -R www-data:www-data /var/www/g4dge7.com" +``` + +### Post-Deployment Verification + +After deploying, verify: + +1. **Site loads**: Visit https://g4dge7.com in browser +2. **No console errors**: Check browser dev tools Console tab +3. **Assets load**: Check Network tab for 404s +4. **Git server unaffected**: Visit https://git.g4dge7.com (should still show Gitea) + +--- + +## Production Environment Details + +### Server Configuration + +| Component | Value | +|-----------|-------| +| **Domain** | `g4dge7.com` | +| **Git Domain** | `git.g4dge7.com` | +| **Web Server** | Nginx | +| **SSL** | Let's Encrypt (auto-renewing) | +| **Deploy Path** | `/var/www/g4dge7.com` | +| **SSH User** | `root` | +| **SSH Host** | `g4dge7.com` or `157.230.50.250` | + +### Nginx Configuration + +The site is configured with: +- **HTTP → HTTPS redirect** (301) +- **SPA routing**: All routes serve `index.html` (client-side routing) +- **Gzip compression** enabled +- **Static asset caching**: 1 year for `.css`, `.js`, images, fonts +- **Security headers**: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy + +### File Locations + +``` +/var/www/g4dge7.com/ # Production site root +├── index.html # Entry point +├── favicon.png +├── icon.png +├── web-app.png +└── assets/ # Bundled JS/CSS + ├── index-*.css + └── *.js +``` + +--- + +## Important Constraints + +### DO NOT + +- ❌ Do not modify Nginx configuration without explicit instruction +- ❌ Do not change the deploy path (`/var/www/g4dge7.com`) +- ❌ Do not modify SSL certificate configuration +- ❌ Do not deploy without testing the build locally first +- ❌ Do not use `--force` with rsync unless explicitly told to +- ❌ Do not modify the `git.g4dge7.com` Nginx config (that's Gitea) + +### DO + +- ✅ Always run `pnpm build` before deploying +- ✅ Always verify the build succeeds before deploying +- ✅ Always test locally with `pnpm preview` before deploying +- ✅ Always verify the site loads after deployment +- ✅ Check browser console for errors after deployment +- ✅ Use `--delete` flag with rsync to remove stale files + +--- + +## Troubleshooting Guide + +### Build Fails + +```bash +# Check TypeScript errors +pnpm typecheck + +# Check for missing dependencies +pnpm install + +# Clear cache and rebuild +rm -rf dist node_modules/.vite +pnpm build +``` + +### Site Not Loading After Deploy + +```bash +# Check if files were deployed +ssh g4dge7.com "ls -la /var/www/g4dge7.com/" + +# Check Nginx status +ssh g4dge7.com "systemctl status nginx" + +# Check Nginx config +ssh g4dge7.com "nginx -t" + +# Check error logs +ssh g4dge7.com "tail -50 /var/log/nginx/error.log" + +# Check file permissions +ssh g4dge7.com "ls -la /var/www/g4dge7.com/" +``` + +### Assets Returning 404 + +Usually means the build output changed filenames (hash-based) but old files weren't cleaned up: + +```bash +# Re-deploy with --delete to remove stale files +rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ +``` + +### Gitea Becomes Inaccessible + +This means Nginx config was modified incorrectly. Restore from backup: + +```bash +# Check git.g4dge7.com config is intact +ssh g4dge7.com "cat /etc/nginx/sites-available/git.g4dge7.com" + +# Reload Nginx +ssh g4dge7.com "nginx -t && systemctl reload nginx" +``` + +--- + +## Git Workflow + +This site is part of a monorepo. The production branch is `master`. + +```bash +# Work on a feature branch +git checkout -b feature/your-feature + +# Make changes, commit +git add . +git commit -m "feat: your changes" + +# Test locally +pnpm build +pnpm preview + +# Deploy to production (after review/approval) +git checkout master +git merge feature/your-feature +git push dtp master + +# Then deploy the site +cd site +pnpm build +rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ +``` + +--- + +## SSH Access + +### Standard SSH +```bash +ssh root@g4dge7.com +``` + +### Direct IP (if DNS issues) +```bash +ssh root@157.230.50.250 +``` + +### Git SSH (for repo access) +```bash +# Use IP directly (Cloudflare doesn't proxy SSH) +git@157.230.50.250:dtp/gadget.git + +# Or configure SSH config (~/.ssh/config): +# Host g4dge7-git +# HostName 157.230.50.250 +# User git +# IdentityFile ~/.ssh/id_ed25519 +``` + +--- + +## Emergency Rollback + +If a deployment breaks the site: + +```bash +# 1. Revert code changes in monorepo +git revert HEAD + +# 2. Rebuild +pnpm build + +# 3. Re-deploy +rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ + +# 4. Verify +curl -sk https://g4dge7.com/ | head -5 +``` + +--- + +## Contact + +For production access or emergencies, contact the system administrator. diff --git a/site/README.md b/site/README.md new file mode 100644 index 0000000..2954070 --- /dev/null +++ b/site/README.md @@ -0,0 +1,207 @@ +# Gadget Code Landing Site + +Static React/Vite landing page for Gadget Code, served at [https://g4dge7.com](https://g4dge7.com). + +--- + +## Production Environment + +### Host Configuration + +| Setting | Value | +|---------|-------| +| **Provider** | DigitalOcean Droplet | +| **Hostname** | `gadget-site` | +| **Domain** | `g4dge7.com` | +| **Git Subdomain** | `git.g4dge7.com` | +| **OS** | Ubuntu 24.04.3 LTS | +| **Web Server** | Nginx 1.24.0 | +| **SSL** | Let's Encrypt (Certbot) | + +### Service Architecture + +``` +g4dge7.com → Nginx → /var/www/g4dge7.com (static site) +git.g4dge7.com → Nginx → Gitea (port 3000) +``` + +### Directory Structure + +| Path | Purpose | +|------|---------| +| `/var/www/g4dge7.com` | Production static site files | +| `/var/www/certbot` | Let's Encrypt ACME challenge files | +| `/etc/nginx/sites-available/g4dge7.com` | Nginx config for main site | +| `/etc/nginx/sites-available/git.g4dge7.com` | Nginx config for Gitea | +| `/etc/letsencrypt/live/g4dge7.com/` | SSL certificates for main domain | +| `/etc/letsencrypt/live/git.g4dge7.com/` | SSL certificates for git subdomain | + +### Nginx Configuration Summary + +**g4dge7.com** (`/etc/nginx/sites-available/g4dge7.com`): +- Listens on ports 80 and 443 +- HTTP redirects to HTTPS (301) +- Serves static files from `/var/www/g4dge7.com` +- SPA fallback: all routes serve `index.html` +- Gzip compression enabled +- Security headers: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy +- Static assets cached for 1 year + +**git.g4dge7.com** (`/etc/nginx/sites-available/git.g4dge7.com`): +- Listens on ports 80 and 443 +- HTTP redirects to HTTPS (301) +- Proxies to Gitea at `http://127.0.0.1:3000` +- WebSocket support enabled for real-time features + +--- + +## Development + +### Prerequisites + +- Node.js 18+ +- pnpm (recommended) or npm + +### Setup + +```bash +cd site +pnpm install +``` + +### Commands + +```bash +pnpm dev # Start Vite dev server +pnpm build # Type check and build for production +pnpm preview # Preview production build locally +pnpm typecheck # Run TypeScript type checking only +``` + +### Build Output + +Production builds are output to `site/dist/`: +- `index.html` - Entry point +- `assets/` - Bundled JS, CSS, and other assets +- `*.png` - Static images (favicon, icons, etc.) + +--- + +## Deployment to Production + +### Full Deployment Process + +```bash +# 1. Build the site +cd /home/rob/workspaces/core-001/gadget/site +pnpm build + +# 2. Sync to production server +rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ + +# 3. Set correct ownership (if needed) +ssh g4dge7.com "chown -R www-data:www-data /var/www/g4dge7.com" + +# 4. Reload Nginx (usually not needed, but safe to run) +ssh g4dge7.com "nginx -t && systemctl reload nginx" +``` + +### Quick Deploy (One-Liner) + +```bash +pnpm build && rsync -avz --delete dist/ g4dge7.com:/var/www/g4dge7.com/ && ssh g4dge7.com "chown -R www-data:www-data /var/www/g4dge7.com" +``` + +### Deployment Checklist + +- [ ] Build completes without errors +- [ ] rsync completes without errors +- [ ] Site loads at https://g4dge7.com +- [ ] No console errors in browser dev tools +- [ ] Git server still accessible at https://git.g4dge7.com + +--- + +## SSL Certificate Management + +### Renewal + +Certbot is configured for automatic renewal via systemd timer. Manual renewal: + +```bash +ssh g4dge7.com "certbot renew --dry-run" # Test renewal +ssh g4dge7.com "certbot renew" # Actual renewal +``` + +### Certificate Locations + +| Domain | Certificate | Private Key | +|--------|-------------|-------------| +| g4dge7.com | `/etc/letsencrypt/live/g4dge7.com/fullchain.pem` | `/etc/letsencrypt/live/g4dge7.com/privkey.pem` | +| git.g4dge7.com | `/etc/letsencrypt/live/git.g4dge7.com/fullchain.pem` | `/etc/letsencrypt/live/git.g4dge7.com/privkey.pem` | + +--- + +## Troubleshooting + +### Site not loading + +```bash +# Check Nginx status +ssh g4dge7.com "systemctl status nginx" + +# Check Nginx config +ssh g4dge7.com "nginx -t" + +# Check if files exist +ssh g4dge7.com "ls -la /var/www/g4dge7.com/" + +# Check Nginx error logs +ssh g4dge7.com "tail -50 /var/log/nginx/error.log" +``` + +### SSL certificate issues + +```bash +# Check certificate expiry +ssh g4dge7.com "certbot certificates" + +# Force renewal +ssh g4dge7.com "certbot renew --force-renewal" +``` + +### Gitea not accessible + +```bash +# Check Gitea status +ssh g4dge7.com "systemctl status gitea" + +# Check if port 3000 is listening +ssh g4dge7.com "ss -tlnp | grep 3000" + +# Check Gitea logs +ssh g4dge7.com "journalctl -u gitea --no-pager -n 50" +``` + +### SSH access issues + +Use the direct IP for SSH (Cloudflare doesn't proxy SSH): + +```bash +ssh root@157.230.50.250 +``` + +--- + +## Security Notes + +- **IP-only Git access**: Git SSH access requires the droplet IP (`157.230.50.250`), not the domain. This is intentional—Cloudflare doesn't proxy SSH, and this limits access to trusted parties. +- **No shell access for git user**: The `git` system user can only execute Gitea commands via authorized_keys restrictions. +- **Security headers**: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, and Referrer-Policy are all configured. +- **HTTPS only**: Both domains redirect HTTP to HTTPS automatically. + +--- + +## Contact + +For issues or questions about this deployment, contact the system administrator.