208 lines
5.1 KiB
Markdown
208 lines
5.1 KiB
Markdown
# 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.
|