# 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.