Skip to main content
Run tinykit on any Linux VPS—DigitalOcean, Linode, Hetzner, AWS, or your own hardware.

Requirements

  • OS: Ubuntu 22.04+ / Debian 12+ (or any Linux with Node.js support)
  • RAM: 1GB minimum, 2GB recommended
  • Disk: 5GB minimum
  • Node.js: 20.x or later
  • Ports: 80, 443 (with reverse proxy) or custom port

Quick Setup

1

Install Node.js

# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verify
node --version  # Should be v20.x.x
npm --version
2

Clone and Install

# Clone repository
git clone https://github.com/tinykit-studio/tinykit.git
cd tinykit

# Install dependencies
npm install

# Build for production
npm run build
3

Configure Environment

# Copy example config
cp .env.example .env

# Edit with your settings
nano .env
Set these variables:
LLM_PROVIDER=anthropic
LLM_API_KEY=sk-ant-...
LLM_MODEL=claude-sonnet-4-20250514
PORT=3000
HOST=0.0.0.0
4

Download Pocketbase

npm run pocketbase:download
5

Start the Server

# Make start script executable
chmod +x deploy/railway/start.sh

# Start (for testing)
./deploy/railway/start.sh

Production Setup with PM2

Use PM2 to keep tinykit running and restart on crashes:
# Install PM2 globally
npm install -g pm2

# Create PM2 ecosystem file
cat > ecosystem.config.js << 'EOF'
module.exports = {
  apps: [{
    name: 'tinykit',
    script: './deploy/railway/start.sh',
    cwd: '/path/to/tinykit',
    env: {
      NODE_ENV: 'production',
      PORT: 3000,
      HOST: '0.0.0.0'
    },
    // Restart on failure
    restart_delay: 5000,
    max_restarts: 10,
    // Logging
    error_file: './logs/error.log',
    out_file: './logs/out.log',
    merge_logs: true,
    time: true
  }]
}
EOF

# Start with PM2
pm2 start ecosystem.config.js

# Save PM2 config (survives reboot)
pm2 save

# Enable PM2 startup on boot
pm2 startup

PM2 Commands

pm2 status           # View status
pm2 logs tinykit     # View logs
pm2 restart tinykit  # Restart
pm2 stop tinykit     # Stop
pm2 delete tinykit   # Remove from PM2

Reverse Proxy Setup

Caddy automatically handles SSL certificates:
# Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Create Caddyfile:
sudo nano /etc/caddy/Caddyfile
app.yourdomain.com {
    reverse_proxy localhost:3000
}

# Multiple domains for different apps
recipes.yourdomain.com {
    reverse_proxy localhost:3000
}

blog.yourdomain.com {
    reverse_proxy localhost:3000
}
# Reload Caddy
sudo systemctl reload caddy

nginx

# Install nginx
sudo apt install nginx

# Create config
sudo nano /etc/nginx/sites-available/tinykit
server {
    listen 80;
    server_name app.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }
}
# Enable site
sudo ln -s /etc/nginx/sites-available/tinykit /etc/nginx/sites-enabled/

# Test config
sudo nginx -t

# Reload nginx
sudo systemctl reload nginx

# Add SSL with Certbot
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app.yourdomain.com

Systemd Service (Alternative to PM2)

Create a systemd service for automatic startup:
sudo nano /etc/systemd/system/tinykit.service
[Unit]
Description=tinykit
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/tinykit
ExecStart=/path/to/tinykit/deploy/railway/start.sh
Restart=on-failure
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=tinykit
Environment=NODE_ENV=production
Environment=PORT=3000
Environment=HOST=0.0.0.0
Environment=LLM_PROVIDER=anthropic
Environment=LLM_API_KEY=sk-ant-...

[Install]
WantedBy=multi-user.target
# Reload systemd
sudo systemctl daemon-reload

# Enable on boot
sudo systemctl enable tinykit

# Start
sudo systemctl start tinykit

# Check status
sudo systemctl status tinykit

# View logs
sudo journalctl -u tinykit -f

Firewall Setup

# Allow HTTP/HTTPS
sudo ufw allow 80
sudo ufw allow 443

# Or allow custom port
sudo ufw allow 3000

# Enable firewall
sudo ufw enable

Updating

cd /path/to/tinykit

# Pull latest
git pull

# Install new dependencies
npm install

# Rebuild
npm run build

# Restart
pm2 restart tinykit
# or
sudo systemctl restart tinykit

Backup

Database Backup

# Stop the app (optional, for consistent backup)
pm2 stop tinykit

# Copy database
cp -r pocketbase/pb_data /backup/tinykit-$(date +%Y%m%d)

# Restart
pm2 start tinykit

Automated Backups

# Add to crontab
crontab -e
# Daily backup at 2 AM
0 2 * * * cp -r /path/to/tinykit/pocketbase/pb_data /backup/tinykit-$(date +\%Y\%m\%d)

# Keep only last 7 days
0 3 * * * find /backup -name "tinykit-*" -mtime +7 -delete

Troubleshooting

Check permissions:
chmod +x pocketbase/pocketbase
ls -la pocketbase/
Ensure the binary matches your architecture (amd64 vs arm64).
Ensure the user running tinykit owns the directory:
sudo chown -R $USER:$USER /path/to/tinykit
Check what’s using the port:
sudo lsof -i :3000
Kill the process or change the PORT in your config.
With Caddy, certificates are automatic. With nginx + Certbot:
sudo certbot renew --dry-run
Check memory usage:
free -h
htop
Consider adding swap or upgrading your VPS.

Security Checklist

  • Keep the system updated: sudo apt update && sudo apt upgrade
  • Use strong passwords for Pocketbase admin
  • Enable firewall (ufw)
  • Use HTTPS (Caddy or Certbot)
  • Don’t expose port 3000 directly—use a reverse proxy
  • Regular backups
  • Consider fail2ban for brute-force protection