docs: Organize documentation into structured folders
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
Organized documentation into cleaner structure: Root directory (user-facing): - README.md - Main documentation - CLAUDE.md - AI context (referenced by system) - QUICKSTART.md - Quick start guide docs/ (technical documentation): - CASL_AUTHORIZATION.md - Authorization guide - ERROR_HANDLING.md - Error handling patterns - REQUIREMENTS.md - Project requirements docs/deployment/ (production deployment): - HTTPS_SETUP.md - SSL/TLS setup - PRODUCTION_ENVIRONMENT_TEMPLATE.md - Env vars template - PRODUCTION_VERIFICATION_CHECKLIST.md - Deployment checklist Removed: - DOCKER_TROUBLESHOOTING.md - Outdated (referenced Google OAuth, old domain) Updated references: - Fixed links to moved files in CASL_AUTHORIZATION.md - Fixed links to moved files in ERROR_HANDLING.md - Removed reference to deleted BUILD_STATUS.md in QUICKSTART.md Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
100
docs/deployment/HTTPS_SETUP.md
Normal file
100
docs/deployment/HTTPS_SETUP.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Enabling HTTPS with Certbot and Nginx
|
||||
|
||||
The production Docker stack ships with an Nginx front-end (the `frontend` service). Follow these steps to terminate HTTPS traffic with Let's Encrypt certificates.
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
- DNS `A` records for your domain (e.g. `vip.example.com`) pointing to `162.243.171.221`.
|
||||
- Ports **80** and **443** open in the DigitalOcean firewall.
|
||||
- Docker Compose production stack deployed.
|
||||
- Certbot installed on the droplet (`apt-get install -y certbot` already run).
|
||||
|
||||
## 2. Obtain certificates
|
||||
|
||||
Run Certbot in standalone mode (temporarily stop the `frontend` container during issuance if it is already binding to port 80):
|
||||
|
||||
```bash
|
||||
# Stop the frontend container temporarily
|
||||
docker compose -f docker-compose.prod.yml stop frontend
|
||||
|
||||
# Request the certificate (replace the domain names)
|
||||
sudo certbot certonly --standalone \
|
||||
-d vip.example.com \
|
||||
-d www.vip.example.com
|
||||
|
||||
# Restart the frontend container
|
||||
docker compose -f docker-compose.prod.yml start frontend
|
||||
```
|
||||
|
||||
Certificates will be stored under `/etc/letsencrypt/live/vip.example.com/`.
|
||||
|
||||
## 3. Mount certificates into the frontend container
|
||||
|
||||
Copy the key pair into the repository (or mount the original directory as a read-only volume). For example:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/vip-coordinator/certs
|
||||
sudo cp /etc/letsencrypt/live/vip.example.com/fullchain.pem /opt/vip-coordinator/certs/
|
||||
sudo cp /etc/letsencrypt/live/vip.example.com/privkey.pem /opt/vip-coordinator/certs/
|
||||
sudo chown root:root /opt/vip-coordinator/certs/*.pem
|
||||
sudo chmod 600 /opt/vip-coordinator/certs/privkey.pem
|
||||
```
|
||||
|
||||
Update `docker-compose.prod.yml` to mount the certificate directory (uncomment the example below):
|
||||
|
||||
```yaml
|
||||
frontend:
|
||||
volumes:
|
||||
- /opt/vip-coordinator/certs:/etc/nginx/certs:ro
|
||||
```
|
||||
|
||||
## 4. Enable the TLS server block
|
||||
|
||||
Edit `frontend/nginx.conf`:
|
||||
|
||||
1. Uncomment the TLS server block and point to `/etc/nginx/certs/fullchain.pem` and `privkey.pem`.
|
||||
2. Change the port 80 server block to redirect to HTTPS (e.g. `return 301 https://$host$request_uri;`).
|
||||
|
||||
Example TLS block:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name vip.example.com www.vip.example.com;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||
|
||||
include /etc/nginx/snippets/ssl-params.conf; # optional hardening
|
||||
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Rebuild and redeploy the frontend container:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml build frontend
|
||||
docker compose -f docker-compose.prod.yml up -d frontend
|
||||
```
|
||||
|
||||
## 5. Automate renewals
|
||||
|
||||
Certbot installs a systemd timer that runs `certbot renew` twice a day. After renewal, copy the updated certificates into `/opt/vip-coordinator/certs/` and reload the frontend container:
|
||||
|
||||
```bash
|
||||
sudo certbot renew --dry-run
|
||||
sudo cp /etc/letsencrypt/live/vip.example.com/{fullchain.pem,privkey.pem} /opt/vip-coordinator/certs/
|
||||
docker compose -f docker-compose.prod.yml exec frontend nginx -s reload
|
||||
```
|
||||
|
||||
Consider scripting the copy + reload to run after each renewal (e.g. with a cron job).
|
||||
|
||||
## 6. Hardening checklist
|
||||
|
||||
- Add `ssl_ciphers`, `ssl_prefer_server_ciphers`, and HSTS headers to Nginx.
|
||||
- Restrict `ADMIN_PASSWORD` to a strong value and rotate `JWT_SECRET`.
|
||||
- Enable a firewall (DigitalOcean VPC or `ufw`) allowing only SSH, HTTP, HTTPS.
|
||||
- Configure automatic backups for PostgreSQL (snapshot or `pg_dump`).
|
||||
|
||||
24
docs/deployment/PRODUCTION_ENVIRONMENT_TEMPLATE.md
Normal file
24
docs/deployment/PRODUCTION_ENVIRONMENT_TEMPLATE.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Production Environment Variables
|
||||
|
||||
Copy this template to your deployment secrets manager or `.env` file before bringing up the production stack.
|
||||
|
||||
```bash
|
||||
# PostgreSQL
|
||||
DB_PASSWORD=change-me
|
||||
|
||||
# Backend application
|
||||
FRONTEND_URL=https://your-domain.com
|
||||
|
||||
# Auth0 configuration
|
||||
AUTH0_DOMAIN=your-tenant.region.auth0.com
|
||||
AUTH0_CLIENT_ID=your-auth0-client-id
|
||||
AUTH0_CLIENT_SECRET=your-auth0-client-secret
|
||||
AUTH0_AUDIENCE=https://your-api-identifier (create an API in Auth0 and use its identifier)
|
||||
INITIAL_ADMIN_EMAILS=primary.admin@example.com,another.admin@example.com
|
||||
|
||||
# Optional third-party integrations
|
||||
AVIATIONSTACK_API_KEY=
|
||||
```
|
||||
|
||||
> ⚠️ Never commit real secrets to version control. Use this file as a reference only.
|
||||
|
||||
29
docs/deployment/PRODUCTION_VERIFICATION_CHECKLIST.md
Normal file
29
docs/deployment/PRODUCTION_VERIFICATION_CHECKLIST.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Production Verification Checklist
|
||||
|
||||
Use this run-book after deploying the production stack.
|
||||
|
||||
## 1. Application health
|
||||
- [ ] `curl http://<server-ip>:3000/api/health` returns `OK`.
|
||||
- [ ] `docker compose -f docker-compose.prod.yml ps` shows `backend`, `frontend`, `db`, `redis` as healthy.
|
||||
- [ ] PostgreSQL contains expected tables (`vips`, `drivers`, `schedule_events`, `flights`, `users`).
|
||||
|
||||
## 2. HTTPS validation
|
||||
- [ ] DNS resolves the public domain to the Droplet (`dig vip.example.com +short`).
|
||||
- [ ] `certbot certificates` shows the Let's Encrypt certificate with a valid expiry date.
|
||||
- [ ] `curl -I https://vip.example.com` returns `200 OK`.
|
||||
- [ ] Qualys SSL Labs scan reaches at least grade **A**.
|
||||
|
||||
## 3. Front-end smoke tests
|
||||
- [ ] Load `/` in a private browser window and confirm the login screen renders.
|
||||
- [ ] Use dev login or OAuth (depending on environment) to access the dashboard.
|
||||
- [ ] Verify VIP and driver lists render without JavaScript console errors.
|
||||
|
||||
## 4. Hardening review
|
||||
- [ ] UFW/DigitalOcean firewall allows only SSH (22), HTTP (80), HTTPS (443).
|
||||
- [ ] `ADMIN_PASSWORD` and `JWT_SECRET` rotated to secure values.
|
||||
- [ ] Scheduled backups for PostgreSQL configured (e.g., `pg_dump` cron or DO backups).
|
||||
- [ ] Droplet rebooted after kernel updates (`needrestart` output clean).
|
||||
- [ ] `docker compose logs` reviewed for warnings or stack traces.
|
||||
|
||||
Document any deviations above and create follow-up tasks.
|
||||
|
||||
Reference in New Issue
Block a user