Add complete production deployment stack so Timmy can be deployed to any cloud provider (DigitalOcean, AWS, Hetzner, etc.) with a single command. New files: - docker-compose.prod.yml: production stack (Caddy auto-HTTPS, Ollama LLM, Dashboard, Timmy agent, Watchtower auto-updates) - deploy/Caddyfile: reverse proxy with security headers and WebSocket support - deploy/setup.sh: interactive one-click setup script for any Ubuntu/Debian server - deploy/cloud-init.yaml: paste as User Data when creating a cloud VM - deploy/timmy.service: systemd unit for auto-start on boot - deploy/digitalocean/create-droplet.sh: create a DO droplet via doctl CLI Updated: - Dockerfile: non-root user, healthcheck, missing deps (GitPython, moviepy, redis) - Makefile: cloud-deploy, cloud-up/down/logs/status/update/scale targets - .env.example: DOMAIN setting for HTTPS - .dockerignore: exclude deploy configs from image https://claude.ai/code/session_018CduUZoEJzFynBwMsxaP8T
118 lines
4.6 KiB
YAML
118 lines
4.6 KiB
YAML
#cloud-config
|
|
# ── Timmy Time — Cloud-Init Bootstrap ────────────────────────────────────────
|
|
#
|
|
# Paste this as "User Data" when creating a DigitalOcean Droplet, AWS EC2
|
|
# instance, Hetzner server, Vultr instance, or any cloud VM.
|
|
#
|
|
# What it does:
|
|
# 1. Installs Docker + Docker Compose
|
|
# 2. Configures firewall (SSH + HTTP + HTTPS only)
|
|
# 3. Clones the Timmy repo to /opt/timmy
|
|
# 4. Pulls the default LLM model
|
|
# 5. Starts the full production stack
|
|
# 6. Enables auto-start on reboot via systemd
|
|
#
|
|
# After boot (~3-5 min), access: https://<your-ip> or https://<your-domain>
|
|
#
|
|
# Prerequisites:
|
|
# - Point your domain's A record to this server's IP (for auto-HTTPS)
|
|
# - Or access via IP (Caddy will serve HTTP only)
|
|
|
|
package_update: true
|
|
package_upgrade: true
|
|
|
|
packages:
|
|
- curl
|
|
- git
|
|
- ufw
|
|
- fail2ban
|
|
- unattended-upgrades
|
|
|
|
write_files:
|
|
# Timmy environment config — edit after first boot if needed
|
|
- path: /opt/timmy/.env
|
|
permissions: "0600"
|
|
content: |
|
|
# ── Timmy Time — Production Environment ──────────────────────────
|
|
# Edit this file, then: systemctl restart timmy
|
|
|
|
# Your domain (required for auto-HTTPS). Use IP for HTTP-only.
|
|
DOMAIN=localhost
|
|
|
|
# LLM model (pulled automatically on first boot)
|
|
OLLAMA_MODEL=llama3.2
|
|
|
|
# Generate secrets:
|
|
# python3 -c "import secrets; print(secrets.token_hex(32))"
|
|
L402_HMAC_SECRET=
|
|
L402_MACAROON_SECRET=
|
|
|
|
# Telegram bot token (optional)
|
|
TELEGRAM_TOKEN=
|
|
|
|
# Systemd service file
|
|
- path: /etc/systemd/system/timmy.service
|
|
permissions: "0644"
|
|
content: |
|
|
[Unit]
|
|
Description=Timmy Time — Mission Control
|
|
After=docker.service network-online.target
|
|
Requires=docker.service
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
RemainAfterExit=yes
|
|
WorkingDirectory=/opt/timmy
|
|
EnvironmentFile=-/opt/timmy/.env
|
|
ExecStart=/usr/bin/docker compose -f docker-compose.prod.yml up -d
|
|
ExecStop=/usr/bin/docker compose -f docker-compose.prod.yml down
|
|
ExecReload=/usr/bin/docker compose -f docker-compose.prod.yml restart
|
|
Restart=on-failure
|
|
RestartSec=30
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
runcmd:
|
|
# ── Install Docker ─────────────────────────────────────────────────────────
|
|
- curl -fsSL https://get.docker.com | sh
|
|
- systemctl enable docker
|
|
- systemctl start docker
|
|
|
|
# ── Firewall ───────────────────────────────────────────────────────────────
|
|
- ufw default deny incoming
|
|
- ufw default allow outgoing
|
|
- ufw allow 22/tcp # SSH
|
|
- ufw allow 80/tcp # HTTP
|
|
- ufw allow 443/tcp # HTTPS
|
|
- ufw allow 443/udp # HTTP/3
|
|
- ufw --force enable
|
|
|
|
# ── Fail2ban ───────────────────────────────────────────────────────────────
|
|
- systemctl enable fail2ban
|
|
- systemctl start fail2ban
|
|
|
|
# ── Clone and deploy ───────────────────────────────────────────────────────
|
|
- git clone https://github.com/AlexanderWhitestone/Timmy-time-dashboard.git /opt/timmy
|
|
- cd /opt/timmy && mkdir -p data
|
|
|
|
# ── Build and start ────────────────────────────────────────────────────────
|
|
- cd /opt/timmy && docker compose -f docker-compose.prod.yml build
|
|
- cd /opt/timmy && docker compose -f docker-compose.prod.yml up -d
|
|
|
|
# ── Pull default LLM model ────────────────────────────────────────────────
|
|
- |
|
|
echo "Waiting for Ollama to be ready..."
|
|
for i in $(seq 1 30); do
|
|
if curl -sf http://localhost:11434/api/tags > /dev/null 2>&1; then
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
docker exec timmy-ollama ollama pull llama3.2
|
|
|
|
# ── Enable auto-start on boot ──────────────────────────────────────────────
|
|
- systemctl daemon-reload
|
|
- systemctl enable timmy
|