mirror of
https://github.com/jhd3197/ServerKit.git
synced 2026-11-09 13:35:12 +09:00
The panel is now fully off Docker: the React SPA is served as static files directly by host nginx from frontend/dist, eliminating the serverkit-frontend container and the double nginx hop (host nginx -> container nginx -> dist). Docker is now used ONLY for managed app workloads. - nginx sites (serverkit.conf + serverkit-insecure.conf): `location /` now roots at /opt/serverkit/frontend/dist with a try_files SPA fallback and a long-cache /assets/ block, instead of proxying 127.0.0.1:3847. Root tracks the /opt/serverkit symlink so blue/green updates swap assets atomically. - install.sh: launch_services no longer builds/starts a frontend container; adds apply_frontend_root (rewrites the dist root for a custom SERVERKIT_DIR) and selinux_label_frontend_dist (httpd_sys_- content_t so SELinux hosts can read the bundle from /opt). - update.sh: refresh_config carries the same root rewrite across upgrades; selinux_label_dist relabels the switched-in slot; dropped the `docker compose up -d --force-recreate frontend` from both the forward and rollback paths. - docker-compose.yml: frontend service moved behind a `legacy-frontend` profile (opt-in escape hatch); default `up -d` starts nothing. - docs/DEPLOYMENT.md: documents the off-Docker panel model. Tests: T14 (refresh_config rewrites dist root for custom install dir), T15 (shipped nginx configs serve static, never proxy :3847). 16 passed. Note: live nginx -t / SELinux file-serving not validated on a RHEL box from this dev host; logic is best-effort guarded. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
407 lines
9.4 KiB
Markdown
407 lines
9.4 KiB
Markdown
# ServerKit Deployment Guide
|
|
|
|
Complete guide for deploying ServerKit on Ubuntu servers.
|
|
|
|
## Deployment model (important)
|
|
|
|
ServerKit's backend **manages the host it runs on** — it creates app
|
|
directories under `/var/serverkit/apps`, drives the host Docker daemon (one
|
|
container per managed app), reloads nginx, and runs systemctl/firewall/PHP-FPM.
|
|
A backend running *inside a container* cannot do any of that. So the canonical
|
|
deployment installed by `./serverkit install` (`install.sh`) runs **fully off
|
|
Docker for the panel itself**:
|
|
|
|
- the **backend on the host** via systemd (`serverkit.service`), and
|
|
- the **frontend as static files served directly by host nginx** from
|
|
`frontend/dist` (built by `install.sh`) — no container. Host nginx serves the
|
|
SPA at `location /` and proxies `/api` + `/socket.io` to the host backend on
|
|
`:5000`.
|
|
|
|
Docker is therefore used **only for the workloads you host** (one container per
|
|
managed app). This is deliberate: a ServerKit update never touches those
|
|
containers, and host nginx — which reverse-proxies them — is only ever
|
|
*reloaded*, never stopped, so updating the panel causes **zero downtime for
|
|
hosted apps**.
|
|
|
|
Do **not** add the backend into Docker — a containerized backend fails
|
|
app/WordPress creation with `Permission denied: /var/serverkit/apps/...` and has
|
|
no access to the host Docker daemon. A containerized *frontend* is still
|
|
available as an opt-in escape hatch (`docker compose --profile legacy-frontend
|
|
up -d`, plus repointing nginx `location /` at `127.0.0.1:3847`) but is not used
|
|
by the default install. The single-container image in `./Dockerfile` exists only
|
|
for throwaway demos and, as its header states, cannot manage the host.
|
|
|
|
## Quick Install (Ubuntu)
|
|
|
|
```bash
|
|
# One-line install
|
|
curl -fsSL https://serverkit.ai/install.sh | bash
|
|
|
|
# Or clone and install manually
|
|
git clone https://github.com/jhd3197/serverkit.git
|
|
cd serverkit
|
|
chmod +x serverkit
|
|
./serverkit install
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
- Ubuntu 20.04+ (or Debian 11+)
|
|
- Docker 20.10+ and Docker Compose 2.0+
|
|
- At least 1GB RAM
|
|
- Domain name (for SSL/HTTPS)
|
|
|
|
## CLI Commands
|
|
|
|
ServerKit includes a management CLI for common administrative tasks.
|
|
|
|
### Service Management
|
|
|
|
```bash
|
|
# Start/Stop/Restart
|
|
serverkit start
|
|
serverkit stop
|
|
serverkit restart
|
|
|
|
# View status
|
|
serverkit status
|
|
|
|
# View logs
|
|
serverkit logs # All services
|
|
serverkit logs backend # Backend only
|
|
serverkit logs frontend # Frontend only
|
|
|
|
# Update to latest version
|
|
serverkit update
|
|
|
|
# Uninstall
|
|
serverkit uninstall
|
|
```
|
|
|
|
### User Management
|
|
|
|
```bash
|
|
# Create admin user
|
|
serverkit create-admin
|
|
# Prompts for: email, username, password
|
|
|
|
# Reset a user's password
|
|
serverkit reset-password
|
|
# Prompts for: email, new password
|
|
|
|
# Unlock a locked account (after failed login attempts)
|
|
serverkit unlock-user
|
|
# Prompts for: email
|
|
|
|
# List all users
|
|
serverkit list-users
|
|
|
|
# Promote user to admin
|
|
serverkit make-admin
|
|
# Prompts for: email
|
|
|
|
# Deactivate/Activate user
|
|
serverkit deactivate-user
|
|
serverkit activate-user
|
|
```
|
|
|
|
### Database Management
|
|
|
|
```bash
|
|
# Initialize database
|
|
serverkit init-db
|
|
|
|
# Apply database migrations (after updates)
|
|
serverkit migrate-db
|
|
|
|
# Backup database
|
|
serverkit backup-db
|
|
# Creates: backup/serverkit-YYYYMMDD-HHMMSS.db
|
|
|
|
# Restore from backup
|
|
serverkit restore-db backup/serverkit-20240115-120000.db
|
|
```
|
|
|
|
### App & Cleanup Commands
|
|
|
|
```bash
|
|
# List all installed applications (from database)
|
|
serverkit list-apps
|
|
|
|
# Also show all Docker containers (including infrastructure)
|
|
serverkit list-apps --all
|
|
|
|
# Delete all apps, containers, folders, and orphaned Docker resources
|
|
serverkit cleanup-apps
|
|
|
|
# Also delete Docker volumes
|
|
serverkit cleanup-apps --delete-volumes
|
|
|
|
# Keep database records (only delete containers/folders)
|
|
serverkit cleanup-apps --keep-db
|
|
|
|
# Complete factory reset (delete everything and start fresh)
|
|
# Preserves only serverkit-frontend infrastructure
|
|
serverkit factory-reset
|
|
```
|
|
|
|
**Note:** Cleanup commands will:
|
|
- Stop and remove all app containers
|
|
- Remove orphaned Docker containers (not tracked in database)
|
|
- Prune unused Docker networks
|
|
- Delete all folders in `/var/serverkit/apps/`
|
|
- Never touch ServerKit infrastructure (serverkit-frontend, serverkit-network)
|
|
|
|
### Utility Commands
|
|
|
|
```bash
|
|
# Generate secure keys for .env
|
|
serverkit generate-keys
|
|
|
|
# Edit configuration
|
|
serverkit config
|
|
|
|
# Open shell in backend container
|
|
serverkit shell
|
|
|
|
# Show help
|
|
serverkit help
|
|
```
|
|
|
|
## Manual Installation
|
|
|
|
### 1. Install Docker
|
|
|
|
```bash
|
|
# Install Docker
|
|
curl -fsSL https://get.docker.com | sh
|
|
|
|
# Add user to docker group
|
|
sudo usermod -aG docker $USER
|
|
|
|
# Log out and back in, then verify
|
|
docker --version
|
|
```
|
|
|
|
### 2. Clone Repository
|
|
|
|
```bash
|
|
git clone https://github.com/jhd3197/serverkit.git /opt/serverkit
|
|
cd /opt/serverkit
|
|
```
|
|
|
|
### 3. Configure Environment
|
|
|
|
```bash
|
|
# Generate secure keys
|
|
serverkit generate-keys
|
|
|
|
# Create .env file
|
|
cat > .env << 'EOF'
|
|
SECRET_KEY=<paste-generated-key>
|
|
JWT_SECRET_KEY=<paste-generated-key>
|
|
DATABASE_URL=sqlite:///serverkit.db
|
|
CORS_ORIGINS=https://yourdomain.com
|
|
PORT=80
|
|
SSL_PORT=443
|
|
FLASK_ENV=production
|
|
EOF
|
|
```
|
|
|
|
### 4. SSL Certificate Setup
|
|
|
|
#### Option A: Let's Encrypt (Recommended)
|
|
|
|
```bash
|
|
# Install certbot
|
|
sudo apt install certbot
|
|
|
|
# Get certificate (stop any service on port 80 first)
|
|
sudo certbot certonly --standalone -d yourdomain.com
|
|
|
|
# Copy certificates
|
|
sudo cp /etc/letsencrypt/live/yourdomain.com/fullchain.pem nginx/ssl/
|
|
sudo cp /etc/letsencrypt/live/yourdomain.com/privkey.pem nginx/ssl/
|
|
sudo chown -R $USER:$USER nginx/ssl/
|
|
```
|
|
|
|
#### Option B: Self-Signed (Development Only)
|
|
|
|
```bash
|
|
mkdir -p nginx/ssl
|
|
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
|
|
-keyout nginx/ssl/privkey.pem \
|
|
-out nginx/ssl/fullchain.pem \
|
|
-subj "/CN=localhost"
|
|
```
|
|
|
|
### 5. Build and Start
|
|
|
|
Both panel tiers run on the host: the backend under systemd
|
|
(`serverkit.service`) and the frontend as static files served by host nginx from
|
|
`frontend/dist`. `./serverkit install` builds the bundle and wires nginx for
|
|
you. See the **Deployment model** note above.
|
|
|
|
```bash
|
|
# Build the SPA bundle host nginx serves (install.sh does this automatically)
|
|
cd frontend && npm ci && npm run build && cd ..
|
|
|
|
# Start the host backend + nginx
|
|
sudo systemctl start serverkit
|
|
sudo systemctl reload nginx
|
|
|
|
# Verify
|
|
serverkit status
|
|
```
|
|
|
|
### 6. Create Admin User
|
|
|
|
```bash
|
|
serverkit create-admin
|
|
```
|
|
|
|
## Systemd Service
|
|
|
|
Run ServerKit as a system service:
|
|
|
|
```bash
|
|
# Copy service file
|
|
sudo cp deploy/serverkit.service /etc/systemd/system/
|
|
|
|
# Enable and start
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable serverkit
|
|
sudo systemctl start serverkit
|
|
|
|
# Check status
|
|
sudo systemctl status serverkit
|
|
```
|
|
|
|
## Configuration Reference
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `SECRET_KEY` | Flask secret key | Required |
|
|
| `JWT_SECRET_KEY` | JWT signing key | Required |
|
|
| `DATABASE_URL` | Database connection string | `sqlite:///serverkit.db` |
|
|
| `CORS_ORIGINS` | Allowed CORS origins | `http://localhost` |
|
|
| `PORT` | HTTP port | `80` |
|
|
| `SSL_PORT` | HTTPS port | `443` |
|
|
| `FLASK_ENV` | Environment mode | `production` |
|
|
|
|
### Host data locations
|
|
|
|
The backend runs on the host, so its data lives on the host filesystem (not in
|
|
Docker volumes):
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `/opt/serverkit/backend/instance/serverkit.db` | SQLite database (default) |
|
|
| `/var/serverkit/apps/` | Managed app directories (one per app) |
|
|
| `/etc/serverkit/` | Config (templates, ssl-mode, install state) |
|
|
| `/var/backups/serverkit/` | Backups |
|
|
|
|
## Common Tasks
|
|
|
|
### Auto-renew SSL Certificate
|
|
|
|
```bash
|
|
# Add to crontab
|
|
sudo crontab -e
|
|
|
|
# Add this line (renews at 2:30 AM daily)
|
|
30 2 * * * certbot renew --quiet && cp /etc/letsencrypt/live/yourdomain.com/*.pem /opt/serverkit/nginx/ssl/ && docker compose -f /opt/serverkit/docker-compose.yml restart frontend
|
|
```
|
|
|
|
### Change Domain
|
|
|
|
1. Update `.env` file: `CORS_ORIGINS=https://newdomain.com`
|
|
2. Get new SSL certificate
|
|
3. Restart: `serverkit restart`
|
|
|
|
### Scale for Production
|
|
|
|
For high-traffic deployments, consider:
|
|
|
|
```bash
|
|
# Use PostgreSQL instead of SQLite
|
|
DATABASE_URL=postgresql://user:pass@localhost:5432/serverkit
|
|
|
|
# Add Redis for session storage
|
|
# Edit docker-compose.yml to add redis service
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Container won't start
|
|
|
|
```bash
|
|
# Check logs
|
|
serverkit logs backend
|
|
|
|
# Rebuild
|
|
docker compose build --no-cache
|
|
docker compose up -d
|
|
```
|
|
|
|
### Permission denied errors
|
|
|
|
```bash
|
|
# Fix Docker socket permissions
|
|
sudo chmod 666 /var/run/docker.sock
|
|
|
|
# Or add user to docker group
|
|
sudo usermod -aG docker $USER
|
|
# Then log out and back in
|
|
```
|
|
|
|
### Port already in use
|
|
|
|
```bash
|
|
# Find what's using port 80
|
|
sudo lsof -i :80
|
|
|
|
# Stop the service or change PORT in .env
|
|
```
|
|
|
|
### Reset everything
|
|
|
|
```bash
|
|
# Stop and remove all containers and volumes
|
|
serverkit stop
|
|
docker compose down -v
|
|
|
|
# Rebuild from scratch
|
|
docker compose build --no-cache
|
|
serverkit start
|
|
serverkit init-db
|
|
serverkit create-admin
|
|
```
|
|
|
|
### Locked out / Forgot password
|
|
|
|
```bash
|
|
# Reset password via CLI
|
|
serverkit reset-password
|
|
# Enter email and new password
|
|
|
|
# Or unlock account if locked
|
|
serverkit unlock-user
|
|
```
|
|
|
|
## Security Checklist
|
|
|
|
- [ ] Generated unique SECRET_KEY and JWT_SECRET_KEY
|
|
- [ ] Using HTTPS with valid SSL certificate
|
|
- [ ] Firewall configured (allow only ports 80, 443, 22)
|
|
- [ ] Regular backups configured
|
|
- [ ] Admin password is strong
|
|
- [ ] Updated to latest version
|
|
|
|
## Support
|
|
|
|
- GitHub Issues: https://github.com/jhd3197/serverkit/issues
|
|
- Documentation: https://github.com/jhd3197/serverkit/wiki
|