diff --git a/README.md b/README.md index b486b09ac..822a367ba 100644 --- a/README.md +++ b/README.md @@ -107,10 +107,16 @@ services: # Security (all optional - runs open by default) # - PULSE_AUTH_USER=admin # Username for web UI login - # - PULSE_AUTH_PASS='$2a$12$...' # Bcrypt hash - MUST be 60 chars in single quotes! + # - PULSE_AUTH_PASS='$$2a$$12$$...' # Bcrypt hash - ESCAPE $ as $$ in docker-compose! # - API_TOKEN= # SHA3-256 hashed API token (64 hex chars) # - ALLOW_UNPROTECTED_EXPORT=false # Allow export without auth (default: false) + # ⚠️ IMPORTANT: Docker Compose requires escaping $ characters! + # In docker-compose.yml, use $$ instead of $: + # WRONG: PULSE_AUTH_PASS='$2a$12$hash...' + # RIGHT: PULSE_AUTH_PASS='$$2a$$12$$hash...' + # Or use a .env file where no escaping is needed + # Polling & timeouts # - POLLING_INTERVAL=3 # Seconds between node checks (default: 3) # - CONNECTION_TIMEOUT=10 # Connection timeout in seconds (default: 10) @@ -255,14 +261,17 @@ See [Reverse Proxy Configuration Guide](docs/REVERSE_PROXY.md) for nginx, Caddy, #### Cannot login after setting up security - **Docker**: Ensure bcrypt hash is exactly 60 characters and wrapped in single quotes -- **Example**: `PULSE_AUTH_PASS='$2a$12$YTZXOCEylj4TaevZ0DCeI.notayQZ..b0OZ97lUZ.Q24fljLiMQHK'` -- If hash is truncated, authentication will fail +- **Docker Compose**: MUST escape $ characters as $$ (e.g., `$$2a$$12$$...`) +- **Example (docker run)**: `PULSE_AUTH_PASS='$2a$12$YTZXOCEylj4TaevZ0DCeI.notayQZ..b0OZ97lUZ.Q24fljLiMQHK'` +- **Example (docker-compose.yml)**: `PULSE_AUTH_PASS='$$2a$$12$$YTZXOCEylj4TaevZ0DCeI.notayQZ..b0OZ97lUZ.Q24fljLiMQHK'` +- If hash is truncated or mangled, authentication will fail - Use Quick Security Setup in the UI to avoid manual configuration errors #### .env file not created (Docker) -- Check container logs: `docker logs ` -- Verify `/data` volume is mounted and writable -- Manually create `/data/.env` with proper format if needed +- **Expected behavior**: When using environment variables, no .env file is created in /data +- The .env file is only created when using Quick Security Setup or password changes +- If you provide credentials via environment variables, they take precedence +- To use Quick Security Setup: Start container WITHOUT auth environment variables ### Connection Issues - Check Proxmox API is accessible (port 8006/8007) @@ -285,7 +294,9 @@ journalctl -u pulse -f ## Documentation +- [Docker Guide](docs/DOCKER.md) - Complete Docker deployment guide - [Configuration Guide](docs/CONFIGURATION.md) - Complete setup and configuration +- [Troubleshooting](docs/TROUBLESHOOTING.md) - Common issues and solutions - [API Reference](docs/API.md) - REST API endpoints and examples - [Webhook Guide](docs/WEBHOOKS.md) - Setting up webhooks and custom payloads - [Reverse Proxy Setup](docs/REVERSE_PROXY.md) - nginx, Caddy, Apache, Traefik configs diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index bf9c0dfd9..3ebb2eb0a 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -29,11 +29,12 @@ docker run -d \ - Settings stored in encrypted JSON files - Environment variables can be set via systemd or .env file - .env file at `/etc/pulse/.env` is auto-loaded if present +- **Service name**: `pulse` (ProxmoxVE) or `pulse-backend` (manual install) **Setting environment variables - Option 1: Systemd override** ```bash -# Edit service -sudo systemctl edit pulse-backend +# Edit service (check which exists: pulse or pulse-backend) +sudo systemctl edit pulse # or pulse-backend # Add overrides: [Service] @@ -51,7 +52,7 @@ FRONTEND_PORT=8080 UPDATE_CHANNEL=rc # Restart service -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` ### Web UI Configuration (Both Deployments) @@ -81,7 +82,11 @@ PULSE_AUTH_PASS='$2a$12$YTZXOCEylj4TaevZ0DCeI.notayQZ..b0OZ97lUZ.Q24fljLiMQHK' API_TOKEN='e6e9fcfb4662d2b485000cc5faf2f7e5d8b75e0492b4877c36dadb085f12e57b' ``` -**CRITICAL**: The bcrypt hash MUST be exactly 60 characters and enclosed in single quotes! +**⚠️ CRITICAL for Docker Compose users:** +- In docker-compose.yml, you MUST escape `$` as `$$` +- Example: `PULSE_AUTH_PASS='$$2a$$12$$YTZXOCEylj4TaevZ0DCeI....'` +- Or use a separate .env file where no escaping is needed +- The bcrypt hash MUST be exactly 60 characters and enclosed in single quotes! ### .enc Files (Sensitive Configuration) - **Purpose**: Store sensitive configuration like Proxmox node credentials @@ -136,7 +141,7 @@ Environment="API_TOKEN=your-secure-token" Environment="ALLOW_UNPROTECTED_EXPORT=true" # Restart service -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` **Docker users:** @@ -198,14 +203,14 @@ docker run -d --name pulse \ **LXC/Systemd:** ```bash echo "FRONTEND_PORT=8080" >> /etc/pulse/.env -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` ### Enable API Authentication ```bash sudo systemctl edit pulse-backend # Add: Environment="API_TOKEN=your-secure-token" -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` ### Configure for Reverse Proxy @@ -222,13 +227,13 @@ docker run -d --name pulse \ **LXC/Systemd:** ```bash echo "ALLOWED_ORIGINS=https://pulse.example.com" >> /etc/pulse/.env -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` ### Enable Debug Logging ```bash echo "LOG_LEVEL=debug" >> /etc/pulse/.env -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend tail -f /etc/pulse/pulse.log ``` @@ -305,5 +310,5 @@ sudo chown -R pulse:pulse /etc/pulse ### Changes Not Taking Effect Always restart after configuration changes: ```bash -sudo systemctl restart pulse-backend +sudo systemctl restart pulse # or pulse-backend ``` \ No newline at end of file diff --git a/docs/DOCKER.md b/docs/DOCKER.md new file mode 100644 index 000000000..a105638fd --- /dev/null +++ b/docs/DOCKER.md @@ -0,0 +1,295 @@ +# Docker Deployment Guide + +## Quick Start + +```bash +docker run -d \ + --name pulse \ + -p 7655:7655 \ + -v pulse_data:/data \ + --restart unless-stopped \ + rcourtman/pulse:latest +``` + +Access at: `http://your-server:7655` + +## Docker Compose + +### Basic Configuration +```yaml +services: + pulse: + image: rcourtman/pulse:latest + container_name: pulse + ports: + - "7655:7655" + volumes: + - pulse_data:/data + restart: unless-stopped + +volumes: + pulse_data: +``` + +### With Authentication + +⚠️ **CRITICAL**: Docker Compose requires escaping `$` characters in bcrypt hashes! + +```yaml +services: + pulse: + image: rcourtman/pulse:latest + container_name: pulse + ports: + - "7655:7655" + volumes: + - pulse_data:/data + environment: + # IMPORTANT: Use $$ instead of $ in docker-compose.yml! + PULSE_AUTH_USER: 'admin' + PULSE_AUTH_PASS: '$$2a$$12$$YourHashHere...' # <-- Note the $$ + API_TOKEN: 'your-sha3-256-token' + restart: unless-stopped + +volumes: + pulse_data: +``` + +### Alternative: Using .env File (Recommended) + +Create `.env` file (no escaping needed): +```env +PULSE_AUTH_USER=admin +PULSE_AUTH_PASS=$2a$12$YourHashHere... +API_TOKEN=your-sha3-256-token +``` + +Docker-compose.yml: +```yaml +services: + pulse: + image: rcourtman/pulse:latest + container_name: pulse + ports: + - "7655:7655" + volumes: + - pulse_data:/data + env_file: .env + restart: unless-stopped + +volumes: + pulse_data: +``` + +## Environment Variables + +### Security Configuration +| Variable | Description | Example | +|----------|-------------|---------| +| `PULSE_AUTH_USER` | Username for web UI | `admin` | +| `PULSE_AUTH_PASS` | Bcrypt password hash (60 chars) | `$2a$12$...` | +| `API_TOKEN` | SHA3-256 hashed API token | 64 hex characters | +| `ALLOW_UNPROTECTED_EXPORT` | Allow export without auth | `false` | + +### Network Configuration +| Variable | Description | Default | +|----------|-------------|---------| +| `PORT` or `FRONTEND_PORT` | Web UI port | `7655` | +| `DISCOVERY_SUBNET` | Auto-discovery subnet | auto-detect | +| `ALLOWED_ORIGINS` | CORS allowed origins | none (same-origin) | + +### System Configuration +| Variable | Description | Default | +|----------|-------------|---------| +| `POLLING_INTERVAL` | Seconds between node checks | `3` | +| `CONNECTION_TIMEOUT` | Connection timeout in seconds | `10` | +| `LOG_LEVEL` | Logging level | `info` | +| `UPDATE_CHANNEL` | Update channel (stable/rc) | `stable` | +| `AUTO_UPDATE_ENABLED` | Enable auto-updates | `false` | + +## Volume Management + +### Data Persistence +All configuration and data is stored in `/data`: +- `.env` - Authentication credentials (if using Quick Setup) +- `*.enc` - Encrypted node credentials +- `*.json` - Configuration files +- `metrics/` - Historical metrics data + +### Backup +```bash +# Backup volume +docker run --rm \ + -v pulse_data:/data \ + -v $(pwd):/backup \ + alpine tar czf /backup/pulse-backup.tar.gz -C /data . + +# Restore volume +docker run --rm \ + -v pulse_data:/data \ + -v $(pwd):/backup \ + alpine tar xzf /backup/pulse-backup.tar.gz -C /data +``` + +## Security Setup + +### Method 1: Quick Security Setup (Recommended) +1. Start container WITHOUT auth environment variables +2. Access http://your-server:7655 +3. Follow the Quick Security Setup wizard +4. Credentials are saved to `/data/.env` +5. Container restart not needed + +### Method 2: Manual Configuration +1. Generate password hash: + ```bash + # Using online bcrypt generator or another tool + # Hash must be exactly 60 characters + ``` + +2. Generate API token: + ```bash + # Generate random token + openssl rand -hex 32 + ``` + +3. Add to docker-compose.yml (remember to escape $ as $$) + +### Method 3: Using Existing .env +If you have a `.env` file from another installation: +```bash +docker cp .env pulse:/data/.env +docker restart pulse +``` + +## Common Issues + +### Cannot Login +1. **Check hash length**: Must be exactly 60 characters +2. **Check escaping**: In docker-compose.yml, use `$$` instead of `$` +3. **Check quotes**: Hash must be in single quotes +4. **Check logs**: `docker logs pulse | grep -i auth` + +### No .env File +**This is normal** when using environment variables. The .env file is only created when: +- Using Quick Security Setup +- Changing password through UI +- Manually creating it + +### Container Won't Start +```bash +# Check logs +docker logs pulse + +# Common issues: +# - Port already in use +# - Volume permission issues +# - Invalid environment variables +``` + +### Password Change Fails +For v4.3.7 and earlier, password changes fail with sudo error. Update to v4.3.8+: +```bash +docker pull rcourtman/pulse:latest +docker stop pulse +docker rm pulse +# Re-run docker run command +``` + +## Networking + +### Using Host Network +For better auto-discovery: +```bash +docker run -d \ + --name pulse \ + --network host \ + -v pulse_data:/data \ + --restart unless-stopped \ + rcourtman/pulse:latest +``` + +### Behind a Reverse Proxy +See [Reverse Proxy Guide](REVERSE_PROXY.md) for nginx, Traefik, Caddy configurations. + +## Updates + +### Manual Update +```bash +# Pull latest image +docker pull rcourtman/pulse:latest + +# Stop and remove old container +docker stop pulse +docker rm pulse + +# Start new container with same settings +docker run -d \ + --name pulse \ + -p 7655:7655 \ + -v pulse_data:/data \ + --restart unless-stopped \ + rcourtman/pulse:latest +``` + +### Docker Compose Update +```bash +docker-compose pull +docker-compose up -d +``` + +### Automatic Updates +Use Watchtower or similar tools: +```bash +docker run -d \ + --name watchtower \ + -v /var/run/docker.sock:/var/run/docker.sock \ + containrrr/watchtower \ + --schedule "0 0 3 * * *" \ + pulse +``` + +## Tips and Best Practices + +1. **Always use named volumes** for data persistence +2. **Escape $ characters** in docker-compose.yml +3. **Use .env files** for cleaner configuration +4. **Set resource limits** for production: + ```yaml + deploy: + resources: + limits: + cpus: '2' + memory: 512M + ``` +5. **Enable auto-restart** with `--restart unless-stopped` +6. **Regular backups** of the data volume +7. **Monitor logs** with `docker logs -f pulse` + +## Debugging + +### Enable Debug Logging +```bash +docker run -d \ + --name pulse \ + -p 7655:7655 \ + -v pulse_data:/data \ + -e LOG_LEVEL=debug \ + --restart unless-stopped \ + rcourtman/pulse:latest +``` + +### Access Container Shell +```bash +docker exec -it pulse sh +``` + +### View Environment +```bash +docker exec pulse env | grep -E "PULSE|API" +``` + +### Check Version +```bash +curl http://localhost:7655/api/version +``` \ No newline at end of file diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 000000000..95301a032 --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,200 @@ +# Pulse Troubleshooting Guide + +## Common Issues and Solutions + +### Authentication Problems + +#### Cannot login after setting up security +**Symptoms**: "Invalid username or password" error despite correct credentials + +**Common causes and solutions:** + +1. **Truncated bcrypt hash** (most common) + - Check hash is exactly 60 characters: `echo -n "$PULSE_AUTH_PASS" | wc -c` + - Look for error in logs: `Bcrypt hash appears truncated!` + - Solution: Use full 60-character hash or Quick Security Setup + +2. **Docker Compose $ character issue** + - Docker Compose interprets `$` as variable expansion + - **Wrong**: `PULSE_AUTH_PASS='$2a$12$hash...'` + - **Right**: `PULSE_AUTH_PASS='$$2a$$12$$hash...'` (escape with $$) + - Alternative: Use a .env file where no escaping is needed + +3. **Environment variable not loaded** + - Check if variable is set: `docker exec pulse env | grep PULSE_AUTH` + - Verify quotes around hash: Must use single quotes + - Restart container after changes + +#### Password change fails +**Error**: `exec: "sudo": executable file not found` + +**Solution**: Update to v4.3.8+ which removes sudo requirement. For older versions: +```bash +# Manually update .env file +docker exec pulse sh -c "echo \"PULSE_AUTH_PASS='new-hash'\" >> /data/.env" +docker restart pulse +``` + +#### Quick Security Setup not accessible +**Symptoms**: Can't access setup wizard, redirected to login + +**Solution**: +- Start container WITHOUT auth environment variables +- Access http://your-ip:7655 to see setup wizard +- Complete setup, then restart container + +### Docker-Specific Issues + +#### No .env file in /data +**This is expected behavior** when using environment variables. The .env file is only created by: +- Quick Security Setup wizard +- Password change through UI +- Manual creation + +If you provide auth via `-e` flags or docker-compose environment section, no .env is created. + +#### Container won't start +Check logs: `docker logs pulse` + +Common issues: +- Port already in use: Change port mapping +- Volume permissions: Ensure volume is writable +- Invalid environment variables: Check syntax + +### Installation Issues + +#### Binary not found (v4.3.7) +**Error**: `/opt/pulse/pulse: No such file or directory` + +**Cause**: v4.3.7 install script bug + +**Solution**: Update to v4.3.8 or manually fix: +```bash +sudo mkdir -p /opt/pulse/bin +sudo mv /opt/pulse/pulse /opt/pulse/bin/pulse +sudo systemctl daemon-reload +sudo systemctl restart pulse +``` + +#### Service name confusion +Pulse uses different service names depending on installation method: +- **ProxmoxVE Script**: `pulse` +- **Manual Install**: `pulse-backend` +- **Docker**: N/A (container name) + +To check which you have: +```bash +systemctl status pulse 2>/dev/null || systemctl status pulse-backend +``` + +### Notification Issues + +#### Emails not sending +1. Check email configuration in Settings → Alerts +2. Verify SMTP settings and credentials +3. Check logs for errors: `docker logs pulse | grep -i email` +4. Test with a simple webhook first + +#### Webhook not working +- Verify URL is accessible from Pulse server +- Check for SSL certificate issues +- Try a test service like webhook.site +- Check logs for response codes + +### Performance Issues + +#### High CPU usage +- Reduce polling interval in Settings → System +- Check number of monitored nodes +- Disable unused features (snapshots, backups monitoring) + +#### High memory usage +- Normal for monitoring many nodes +- Check metrics retention settings +- Restart container to clear any memory leaks + +### Network Issues + +#### Cannot connect to Proxmox nodes +1. Verify Proxmox API is accessible: + ```bash + curl -k https://proxmox-ip:8006 + ``` +2. Check credentials have proper permissions (PVEAuditor minimum) +3. Verify network connectivity between Pulse and Proxmox +4. Check for firewall rules blocking port 8006 + +#### PBS connection issues +- Ensure API token has Datastore.Audit permission +- Check PBS is accessible on port 8007 +- Verify token format: `user@realm!tokenid=secret` + +### Update Issues + +#### Updates not showing +- Check update channel in Settings → System +- Verify internet connectivity +- Check GitHub API rate limits +- Manual update: Pull latest Docker image or run install script + +#### Update fails to apply +**Docker**: Pull new image and recreate container +**Native**: Run install script again or check logs + +### Data Recovery + +#### Lost authentication +If you've lost access and need to reset: + +**Docker**: +```bash +# Remove auth from container +docker exec pulse rm /data/.env +docker restart pulse +# Access UI and use Quick Security Setup +``` + +**Native Install**: +```bash +sudo rm /etc/pulse/.env +sudo systemctl restart pulse # or pulse-backend +# Access UI and use Quick Security Setup +``` + +#### Corrupt configuration +Restore from backup or delete config files to start fresh: +```bash +# Docker +docker exec pulse rm /data/*.json /data/*.enc +docker restart pulse + +# Native +sudo rm /etc/pulse/*.json /etc/pulse/*.enc +sudo systemctl restart pulse +``` + +## Getting Help + +### Collect diagnostic information +```bash +# Version +curl http://localhost:7655/api/version + +# Logs (last 100 lines) +docker logs --tail 100 pulse # Docker +journalctl -u pulse -n 100 # Native + +# Environment +docker exec pulse env | grep -E "PULSE|API" # Docker +systemctl show pulse --property=Environment # Native +``` + +### Report issues +When reporting issues, include: +1. Pulse version +2. Deployment type (Docker/LXC/Manual) +3. Error messages from logs +4. Steps to reproduce +5. Expected vs actual behavior + +Report at: https://github.com/rcourtman/Pulse/issues \ No newline at end of file