| .. | ||
| public | ||
| src | ||
| .gitignore | ||
| AGENTS.md | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| README.md | ||
| tailwind.config.js | ||
| tsconfig.json | ||
| vite.config.ts | ||
Gadget Code Landing Site
Static React/Vite landing page for Gadget Code, served at 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
cd site
pnpm install
Commands
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 pointassets/- Bundled JS, CSS, and other assets*.png- Static images (favicon, icons, etc.)
Deployment to Production
Full Deployment Process
# 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)
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:
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
# 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
# Check certificate expiry
ssh g4dge7.com "certbot certificates"
# Force renewal
ssh g4dge7.com "certbot renew --force-renewal"
Gitea not accessible
# 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):
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
gitsystem 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.