Documentation structure: - docs/README.md - Documentation index - docs/getting-started.md - Installation and first run - docs/usage.md - Dashboard features and usage - docs/configuration.md - Full configuration reference - docs/multi-device.md - Agent setup and PKI management - docs/security.md - Authentication, RBAC, mTLS - docs/api.md - Complete REST API reference - docs/deployment.md - Production deployment guide - docs/troubleshooting.md - Common issues and solutions - docs/development.md - Contributing and building Total: ~80KB of documentation covering all features 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
484 lines
9.0 KiB
Markdown
484 lines
9.0 KiB
Markdown
# Deployment Guide
|
|
|
|
This guide covers production deployment options for Tyto.
|
|
|
|
## Deployment Options
|
|
|
|
| Method | Best For |
|
|
|--------|----------|
|
|
| Docker Compose | Quick setup, small deployments |
|
|
| Native Binary | Performance, minimal dependencies |
|
|
| Kubernetes | Large scale, cloud native |
|
|
|
|
## Docker Compose Deployment
|
|
|
|
### Basic Setup
|
|
|
|
```bash
|
|
git clone https://somegit.dev/vikingowl/tyto.git
|
|
cd tyto
|
|
docker compose up -d
|
|
```
|
|
|
|
### Production Configuration
|
|
|
|
Use the production overlay:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
|
```
|
|
|
|
The production overlay adds:
|
|
- Resource limits (CPU, memory)
|
|
- Log rotation
|
|
- Restart policies
|
|
- Health checks
|
|
|
|
### Custom docker-compose.override.yml
|
|
|
|
Create `docker-compose.override.yml` for local customizations:
|
|
|
|
```yaml
|
|
services:
|
|
backend:
|
|
environment:
|
|
- TYTO_MODE=server
|
|
- TYTO_DB_TYPE=postgres
|
|
- TYTO_DB_URL=postgres://tyto:${DB_PASSWORD}@db:5432/tyto
|
|
volumes:
|
|
- ./config.yaml:/etc/tyto/config.yaml:ro
|
|
- ./certs:/etc/tyto/certs:ro
|
|
|
|
db:
|
|
image: postgres:16-alpine
|
|
environment:
|
|
- POSTGRES_USER=tyto
|
|
- POSTGRES_PASSWORD=${DB_PASSWORD}
|
|
- POSTGRES_DB=tyto
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
|
|
volumes:
|
|
postgres-data:
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Create `.env` file:
|
|
|
|
```bash
|
|
DB_PASSWORD=secure-password
|
|
LDAP_BIND_PASSWORD=ldap-password
|
|
```
|
|
|
|
## Native Installation
|
|
|
|
### One-Line Install
|
|
|
|
```bash
|
|
curl -fsSL https://somegit.dev/vikingowl/tyto/raw/branch/main/scripts/install.sh | sudo bash
|
|
```
|
|
|
|
### Manual Installation
|
|
|
|
```bash
|
|
# Download binary
|
|
curl -LO https://somegit.dev/vikingowl/tyto/releases/latest/download/tyto-linux-amd64.tar.gz
|
|
tar -xzf tyto-linux-amd64.tar.gz
|
|
|
|
# Install binary
|
|
sudo mv tyto /usr/local/bin/
|
|
sudo chmod +x /usr/local/bin/tyto
|
|
|
|
# Create user and directories
|
|
sudo useradd --system --no-create-home tyto
|
|
sudo mkdir -p /etc/tyto /var/lib/tyto /var/log/tyto
|
|
sudo chown tyto:tyto /var/lib/tyto /var/log/tyto
|
|
|
|
# Create config
|
|
sudo cat > /etc/tyto/config.yaml << EOF
|
|
mode: standalone
|
|
http:
|
|
port: 8080
|
|
refresh_rate: 5
|
|
EOF
|
|
|
|
# Create systemd service
|
|
sudo cat > /etc/systemd/system/tyto.service << EOF
|
|
[Unit]
|
|
Description=Tyto System Monitor
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=tyto
|
|
ExecStart=/usr/local/bin/tyto --config /etc/tyto/config.yaml
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# Start service
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable tyto
|
|
sudo systemctl start tyto
|
|
```
|
|
|
|
## Reverse Proxy
|
|
|
|
### Nginx
|
|
|
|
```nginx
|
|
upstream tyto_frontend {
|
|
server 127.0.0.1:3000;
|
|
}
|
|
|
|
upstream tyto_backend {
|
|
server 127.0.0.1:8080;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2;
|
|
server_name tyto.example.com;
|
|
|
|
ssl_certificate /etc/nginx/ssl/tyto.crt;
|
|
ssl_certificate_key /etc/nginx/ssl/tyto.key;
|
|
|
|
# Frontend
|
|
location / {
|
|
proxy_pass http://tyto_frontend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
}
|
|
|
|
# API and SSE
|
|
location /api/ {
|
|
proxy_pass http://tyto_backend;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# SSE support
|
|
proxy_set_header Connection '';
|
|
proxy_buffering off;
|
|
proxy_cache off;
|
|
proxy_read_timeout 86400s;
|
|
}
|
|
|
|
# Health check
|
|
location /health {
|
|
proxy_pass http://tyto_backend;
|
|
}
|
|
}
|
|
|
|
# Redirect HTTP to HTTPS
|
|
server {
|
|
listen 80;
|
|
server_name tyto.example.com;
|
|
return 301 https://$server_name$request_uri;
|
|
}
|
|
```
|
|
|
|
### Caddy
|
|
|
|
```caddyfile
|
|
tyto.example.com {
|
|
# Frontend
|
|
reverse_proxy /api/* localhost:8080
|
|
reverse_proxy /* localhost:3000
|
|
}
|
|
```
|
|
|
|
### Traefik (Docker)
|
|
|
|
```yaml
|
|
services:
|
|
traefik:
|
|
image: traefik:v2.10
|
|
command:
|
|
- --providers.docker
|
|
- --entrypoints.web.address=:80
|
|
- --entrypoints.websecure.address=:443
|
|
- --certificatesresolvers.letsencrypt.acme.email=admin@example.com
|
|
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
|
|
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
- letsencrypt:/letsencrypt
|
|
|
|
frontend:
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.http.routers.tyto.rule=Host(`tyto.example.com`)
|
|
- traefik.http.routers.tyto.tls.certresolver=letsencrypt
|
|
|
|
backend:
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.http.routers.tyto-api.rule=Host(`tyto.example.com`) && PathPrefix(`/api`)
|
|
- traefik.http.routers.tyto-api.tls.certresolver=letsencrypt
|
|
```
|
|
|
|
## Database Setup
|
|
|
|
### PostgreSQL
|
|
|
|
```bash
|
|
# Install PostgreSQL
|
|
sudo apt install postgresql postgresql-contrib
|
|
|
|
# Create database and user
|
|
sudo -u postgres psql << EOF
|
|
CREATE DATABASE tyto;
|
|
CREATE USER tyto WITH ENCRYPTED PASSWORD 'secure-password';
|
|
GRANT ALL PRIVILEGES ON DATABASE tyto TO tyto;
|
|
\c tyto
|
|
GRANT ALL ON SCHEMA public TO tyto;
|
|
EOF
|
|
```
|
|
|
|
Configure Tyto:
|
|
|
|
```yaml
|
|
database:
|
|
type: postgres
|
|
url: postgres://tyto:secure-password@localhost:5432/tyto?sslmode=require
|
|
```
|
|
|
|
### PostgreSQL with Docker
|
|
|
|
```yaml
|
|
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
environment:
|
|
POSTGRES_USER: tyto
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
POSTGRES_DB: tyto
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U tyto"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
|
|
backend:
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
environment:
|
|
TYTO_DB_TYPE: postgres
|
|
TYTO_DB_URL: postgres://tyto:${DB_PASSWORD}@db:5432/tyto
|
|
```
|
|
|
|
## SSL/TLS Certificates
|
|
|
|
### Let's Encrypt with Certbot
|
|
|
|
```bash
|
|
# Install certbot
|
|
sudo apt install certbot python3-certbot-nginx
|
|
|
|
# Obtain certificate
|
|
sudo certbot --nginx -d tyto.example.com
|
|
|
|
# Auto-renewal is configured automatically
|
|
```
|
|
|
|
### Self-Signed Certificates
|
|
|
|
```bash
|
|
# Generate self-signed certificate
|
|
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
|
-keyout /etc/tyto/ssl/server.key \
|
|
-out /etc/tyto/ssl/server.crt \
|
|
-subj "/CN=tyto.example.com"
|
|
```
|
|
|
|
## Monitoring Tyto
|
|
|
|
### Prometheus Metrics
|
|
|
|
Tyto exposes Prometheus metrics at `/metrics`:
|
|
|
|
```yaml
|
|
# prometheus.yml
|
|
scrape_configs:
|
|
- job_name: 'tyto'
|
|
static_configs:
|
|
- targets: ['tyto.example.com:8080']
|
|
```
|
|
|
|
### Health Checks
|
|
|
|
```bash
|
|
# Basic health check
|
|
curl -f http://localhost:8080/health
|
|
|
|
# Docker health check
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
```
|
|
|
|
## Backup and Restore
|
|
|
|
### SQLite Backup
|
|
|
|
```bash
|
|
# Stop service (for consistency)
|
|
sudo systemctl stop tyto
|
|
|
|
# Backup
|
|
cp /var/lib/tyto/tyto.db /backup/tyto-$(date +%Y%m%d).db
|
|
|
|
# Restart
|
|
sudo systemctl start tyto
|
|
```
|
|
|
|
### PostgreSQL Backup
|
|
|
|
```bash
|
|
# Backup
|
|
pg_dump -U tyto tyto > /backup/tyto-$(date +%Y%m%d).sql
|
|
|
|
# Restore
|
|
psql -U tyto tyto < /backup/tyto-20240115.sql
|
|
```
|
|
|
|
### Automated Backups
|
|
|
|
```bash
|
|
# /etc/cron.daily/tyto-backup
|
|
#!/bin/bash
|
|
pg_dump -U tyto tyto | gzip > /backup/tyto-$(date +%Y%m%d).sql.gz
|
|
find /backup -name "tyto-*.sql.gz" -mtime +30 -delete
|
|
```
|
|
|
|
## Resource Requirements
|
|
|
|
### Minimum (Standalone)
|
|
|
|
| Resource | Value |
|
|
|----------|-------|
|
|
| CPU | 1 core |
|
|
| RAM | 256 MB |
|
|
| Disk | 1 GB |
|
|
|
|
### Recommended (Server Mode)
|
|
|
|
| Resource | Value |
|
|
|----------|-------|
|
|
| CPU | 2 cores |
|
|
| RAM | 1 GB |
|
|
| Disk | 10 GB |
|
|
|
|
### Agent
|
|
|
|
| Resource | Value |
|
|
|----------|-------|
|
|
| CPU | 0.1 core |
|
|
| RAM | 64 MB |
|
|
| Disk | 50 MB |
|
|
|
|
## Scaling
|
|
|
|
### Horizontal Scaling
|
|
|
|
For high availability, run multiple server instances:
|
|
|
|
```yaml
|
|
services:
|
|
backend-1:
|
|
image: tyto:latest
|
|
environment:
|
|
- TYTO_MODE=server
|
|
- TYTO_DB_URL=postgres://tyto:pass@db:5432/tyto
|
|
|
|
backend-2:
|
|
image: tyto:latest
|
|
environment:
|
|
- TYTO_MODE=server
|
|
- TYTO_DB_URL=postgres://tyto:pass@db:5432/tyto
|
|
|
|
nginx:
|
|
image: nginx
|
|
volumes:
|
|
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
|
ports:
|
|
- "8080:80"
|
|
```
|
|
|
|
### Load Balancer Configuration
|
|
|
|
```nginx
|
|
upstream tyto_backends {
|
|
least_conn;
|
|
server backend-1:8080;
|
|
server backend-2:8080;
|
|
}
|
|
```
|
|
|
|
## Troubleshooting Deployment
|
|
|
|
### Service Won't Start
|
|
|
|
```bash
|
|
# Check logs
|
|
journalctl -u tyto -f
|
|
|
|
# Check configuration
|
|
tyto validate-config --config /etc/tyto/config.yaml
|
|
|
|
# Check permissions
|
|
ls -la /var/lib/tyto
|
|
```
|
|
|
|
### Database Connection Failed
|
|
|
|
```bash
|
|
# Test PostgreSQL connection
|
|
psql -h localhost -U tyto -d tyto -c "SELECT 1"
|
|
|
|
# Check connection string
|
|
echo $TYTO_DB_URL
|
|
```
|
|
|
|
### Port Already in Use
|
|
|
|
```bash
|
|
# Find process using port
|
|
lsof -i :8080
|
|
netstat -tlnp | grep 8080
|
|
|
|
# Use different port
|
|
TYTO_HTTP_PORT=8081 tyto
|
|
```
|
|
|
|
### Container Not Starting
|
|
|
|
```bash
|
|
# Check container logs
|
|
docker compose logs backend
|
|
|
|
# Check container status
|
|
docker compose ps
|
|
|
|
# Rebuild containers
|
|
docker compose build --no-cache
|
|
docker compose up -d
|
|
```
|