Add comprehensive documentation: README, DEPLOYMENT, CHANGELOG, .env.example
This commit is contained in:
+311
@@ -0,0 +1,311 @@
|
||||
# Deployment Guide
|
||||
|
||||
Complete setup for deploying the portfolio site with Docker, Caddy, and Oracle Cloud VPS.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Cloudflare │────▶│ Oracle VPS │────▶│ Vite Dev │
|
||||
│ (DNS + Proxy) │ │ (Caddy) │ │ Server │
|
||||
│ │ │ Port 80/443 │────▶│ Port 5173 │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Docker │
|
||||
│ (Caddy) │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Oracle Cloud VPS (or similar)
|
||||
- Domain name (Cloudflare recommended)
|
||||
- Docker + Docker Compose installed
|
||||
- Git access to repository
|
||||
|
||||
## Server Setup
|
||||
|
||||
### 1. Provision VPS
|
||||
|
||||
**Oracle Cloud Free Tier:**
|
||||
1. Create instance (Ubuntu 22.04/24.04 ARM or AMD)
|
||||
2. Add ingress rules for ports 22, 80, 443
|
||||
3. Note the public IP
|
||||
|
||||
**Open Ports in Oracle Console:**
|
||||
1. Networking → Virtual Cloud Networks
|
||||
2. Click your VCN → Subnets
|
||||
3. Security Lists → Default Security List
|
||||
4. Add Ingress Rules:
|
||||
- TCP 80 from 0.0.0.0/0
|
||||
- TCP 443 from 0.0.0.0/0
|
||||
- TCP 22 from your IP (SSH)
|
||||
|
||||
### 2. Install Dependencies
|
||||
|
||||
```bash
|
||||
# Update system
|
||||
sudo apt update && sudo apt upgrade -y
|
||||
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
|
||||
# Install Node.js 22
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
|
||||
# Verify
|
||||
node -v # Should be 20.19+ or 22.12+
|
||||
npm -v
|
||||
docker --version
|
||||
```
|
||||
|
||||
### 3. Clone Repository
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /opt/peters-portfolio-site
|
||||
sudo chown $USER:$USER /opt/peters-portfolio-site
|
||||
cd /opt/peters-portfolio-site
|
||||
git clone https://git.dustin.coffee/hobokenchicken/peters-portfolio-site.git .
|
||||
```
|
||||
|
||||
### 4. Configure Caddy
|
||||
|
||||
Create directory structure:
|
||||
```bash
|
||||
mkdir -p docker_configs/caddy/conf
|
||||
mkdir -p docker_configs/caddy/site
|
||||
mkdir -p docker_configs/caddy/caddy_data
|
||||
mkdir -p docker_configs/caddy/caddy_config
|
||||
mkdir -p docker_configs/caddy/logs
|
||||
```
|
||||
|
||||
Create `docker_configs/caddy/conf/Caddyfile`:
|
||||
|
||||
```caddy
|
||||
pwlmyers.org {
|
||||
reverse_proxy 172.20.1.232:5173
|
||||
|
||||
log {
|
||||
output file /var/log/caddy/access.log
|
||||
format json
|
||||
}
|
||||
|
||||
# Optional: Add headers
|
||||
header {
|
||||
X-Content-Type-Options nosniff
|
||||
X-Frame-Options DENY
|
||||
X-XSS-Protection "1; mode=block"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** Adjust `172.20.1.232` to match your Vite server's IP (check with `ip addr show`)
|
||||
|
||||
### 5. Docker Compose for Caddy
|
||||
|
||||
Create `compose.caddy.yaml`:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./docker_configs/caddy/conf:/etc/caddy
|
||||
- ./docker_configs/caddy/site:/srv
|
||||
- ./docker_configs/caddy/caddy_data:/data
|
||||
- ./docker_configs/caddy/caddy_config:/config
|
||||
- ./docker_configs/caddy/logs:/var/log/caddy
|
||||
networks:
|
||||
- caddy_network
|
||||
|
||||
networks:
|
||||
caddy_network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
### 6. DNS Configuration (Cloudflare)
|
||||
|
||||
1. Log into Cloudflare dashboard
|
||||
2. Select your domain
|
||||
3. **DNS** tab → Add records:
|
||||
- Type: `A`
|
||||
- Name: `@` (root) or `www`
|
||||
- Content: `150.136.209.11` (your VPS IP)
|
||||
- Proxy status: 🟠 Orange cloud (proxied) or ⚪ Gray cloud (DNS only)
|
||||
- TTL: Auto
|
||||
|
||||
4. **SSL/TLS** tab:
|
||||
- Mode: **Full (strict)** or **Full**
|
||||
- Always Use HTTPS: On
|
||||
|
||||
### 7. Deploy Application
|
||||
|
||||
```bash
|
||||
cd /opt/peters-portfolio-site
|
||||
|
||||
# Copy docs to public
|
||||
cp -r docs/* public/docs/
|
||||
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start Vite dev server (background)
|
||||
nohup npm run dev > vite.log 2>&1 &
|
||||
|
||||
# Start Caddy
|
||||
docker compose -f compose.caddy.yaml up -d
|
||||
```
|
||||
|
||||
### 8. Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check Caddy is running
|
||||
docker ps | grep caddy
|
||||
|
||||
# Check Vite is running
|
||||
ps aux | grep vite
|
||||
curl http://172.20.1.232:5173/
|
||||
|
||||
# Test from VPS
|
||||
curl -H "Host: pwlmyers.org" http://localhost/
|
||||
|
||||
# Test HTTPS (after DNS propagates)
|
||||
curl -v https://pwlmyers.org/
|
||||
```
|
||||
|
||||
## Updates
|
||||
|
||||
### Pull and Update
|
||||
|
||||
```bash
|
||||
cd /opt/peters-portfolio-site
|
||||
|
||||
# Pull latest changes
|
||||
git pull
|
||||
|
||||
# Reinstall if package.json changed
|
||||
npm install
|
||||
|
||||
# Copy any new docs
|
||||
cp -r docs/* public/docs/
|
||||
|
||||
# Restart Vite
|
||||
pkill -f vite || true
|
||||
nohup npm run dev > vite.log 2>&1 &
|
||||
|
||||
# Restart Caddy if config changed
|
||||
docker compose -f compose.caddy.yaml restart
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Vite logs
|
||||
tail -f vite.log
|
||||
|
||||
# Caddy logs
|
||||
docker logs -f ubuntu-caddy-1
|
||||
tail -f docker_configs/caddy/logs/access.log
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### SSL Certificate Issues
|
||||
|
||||
If Caddy fails to get Let's Encrypt certificate:
|
||||
|
||||
```bash
|
||||
# Check Cloudflare proxy status
|
||||
dig pwlmyers.org +short
|
||||
# Should return your VPS IP, not Cloudflare IPs
|
||||
|
||||
# If using Cloudflare proxy (orange cloud):
|
||||
# - Use Cloudflare Origin Certificate
|
||||
# - Or switch to DNS only (gray cloud) for Let's Encrypt
|
||||
```
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
```bash
|
||||
# Find what's using port 80/443
|
||||
sudo netstat -tlnp | grep -E ':(80|443)'
|
||||
|
||||
# Stop conflicting service
|
||||
sudo systemctl stop nginx apache2
|
||||
```
|
||||
|
||||
### Vite Not Accessible
|
||||
|
||||
```bash
|
||||
# Check Vite is listening on all interfaces
|
||||
netstat -tlnp | grep 5173
|
||||
|
||||
# Should show 0.0.0.0:5173, not 127.0.0.1:5173
|
||||
|
||||
# Check allowedHosts in vite.config.ts
|
||||
cat vite.config.ts
|
||||
```
|
||||
|
||||
### Docker Network Issues
|
||||
|
||||
```bash
|
||||
# Check Caddy can reach Vite
|
||||
docker exec ubuntu-caddy-1 wget -qO- http://172.20.1.232:5173/
|
||||
|
||||
# If using Docker network instead of host IP:
|
||||
docker network ls
|
||||
docker network inspect caddy_caddy_network
|
||||
```
|
||||
|
||||
## Alternative: Systemd Service
|
||||
|
||||
Instead of `nohup`, create a systemd service for Vite:
|
||||
|
||||
```bash
|
||||
sudo tee /etc/systemd/system/peters-portfolio.service > /dev/null <<'EOF'
|
||||
[Unit]
|
||||
Description=Peter's Portfolio Vite Dev Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=ubuntu
|
||||
WorkingDirectory=/opt/peters-portfolio-site
|
||||
ExecStart=/usr/bin/npm run dev
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
Environment=NODE_ENV=development
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable peters-portfolio
|
||||
sudo systemctl start peters-portfolio
|
||||
sudo systemctl status peters-portfolio
|
||||
```
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Keep `node_modules` updated: `npm audit fix`
|
||||
- Use Cloudflare proxy for DDoS protection
|
||||
- Consider fail2ban for SSH brute force protection
|
||||
- Regular backups of `docs/` directory
|
||||
|
||||
## Support
|
||||
|
||||
For issues with:
|
||||
- **Application code:** Check README.md troubleshooting section
|
||||
- **Server/Docker:** Check logs with commands above
|
||||
- **DNS/SSL:** Verify Cloudflare settings and Oracle firewall rules
|
||||
Reference in New Issue
Block a user