Files
digiserver-v2/QUICK_DEPLOYMENT.md
T
ske087 052751b599 Rewrite QUICK_DEPLOYMENT.md for Caddy-based architecture
- Replace Nginx references throughout with Caddy
- Update architecture diagram to show Caddy
- Update container details (caddy:2-alpine, ports 8080/8443)
- Update volume paths (caddy-data, caddy-config, caddy-logs)
- Add rebuild guide for code changes (docker build + restart)
- Add quick-test method (docker cp + pkill -HUP)
- Simplify commands section (docker compose not docker-compose)
- Remove Nginx-specific troubleshooting
- Add Caddy validation and reload commands
2026-07-21 10:09:26 +03:00

301 lines
8.5 KiB
Markdown

# DigiServer v2 - Quick Deployment Guide
## 📋 Overview
DigiServer is deployed using Docker Compose with the following architecture:
```
Internet (User) — Port 8080 (HTTP) / 8443 (HTTPS)
Caddy Reverse Proxy (auto HTTPS, gzip, security headers)
Internal Docker Network (digiserver-network)
Flask App (Gunicorn on Port 5000)
SQLite Database
```
Caddy is used instead of Nginx because it:
- **Auto-provisions Let's Encrypt certificates** — no manual certbot
- **Simpler config** — a `Caddyfile` replaces the verbose `nginx.conf`
- **Built-in HTTP/2, gzip, security headers**
- **Admin API** (port 2019) — Flask reloads Caddy config dynamically
---
## 🚀 Quick Start
### **1️⃣ Clone & Setup**
```bash
git clone <repository>
cd digiserver-v2
```
### **2️⃣ Start Containers**
```bash
docker compose up -d
```
This automatically:
1. ✅ Builds the Flask app image from `Dockerfile`
2. ✅ Creates persistent data directories (`data/instance`, `data/uploads`, etc.)
3. ✅ Starts Caddy reverse proxy on ports **8080** (HTTP) and **8443** (HTTPS)
4. ✅ Initializes the database on first run (auto-creates admin user)
5. ✅ Runs all required migrations
**Access the app at:** `http://localhost:8080`
### **3️⃣ First-Time Login**
```
URL: http://localhost:8080
Username: admin
Password: admin123
```
⚠️ **CHANGE PASSWORD IMMEDIATELY IN PRODUCTION!**
---
## 📦 Container Architecture
### **Container 1: digiserver-app (Flask)**
| Property | Value |
|----------|-------|
| **Image** | Built from `Dockerfile` (Python 3.13-slim) |
| **Container name** | `digiserver-v2` |
| **Exposed port** | `5000` (internal — proxied by Caddy) |
| **Mapped port** | `5000:5000` (for direct dev access) |
| **Entrypoint** | `docker-entrypoint.sh` (init DB → gunicorn) |
| **Workers** | 4 gunicorn workers, 120s timeout |
**Volumes (persistent data):**
| Host path | Container path | Purpose |
|-----------|---------------|---------|
| `./data/instance` | `/app/instance` | SQLite database |
| `./data/uploads` | `/app/app/static/uploads` | Media uploads |
> **Code is baked into the Docker image** — see [Rebuild](#-rebuild-after-code-changes) below.
### **Container 2: caddy (Reverse Proxy)**
| Property | Value |
|----------|-------|
| **Image** | `caddy:2-alpine` |
| **Container name** | `digiserver-caddy` |
| **HTTP** | `8080 → 80` (inside container) |
| **HTTPS** | `8443 → 443` (inside container) |
| **Admin API** | `2019` (internal, for dynamic reloads) |
**Volumes:**
| Host path | Container path | Purpose |
|-----------|---------------|---------|
| `./data/Caddyfile` | `/etc/caddy/Caddyfile:rw` | Caddy config (rewritable by Flask) |
| `./data/caddy-data` | `/data` | Let's Encrypt certs & keys |
| `./data/caddy-config` | `/config` | Caddy JSON config |
| `./data/caddy-logs` | `/var/log/caddy` | Access logs |
---
## 🚀 Full Automated Deployment
```bash
./deploy.sh
```
This runs the complete workflow:
1. Creates `data/` directories (`instance`, `uploads`, `caddy-*`)
2. Starts containers (`docker compose up -d`)
3. Initialises database and admin user
4. Runs all database migrations
5. Enables HTTPS via Flask Admin
6. Validates Caddy configuration
7. Prints access URLs and credentials
---
## 🔧 Deployment Steps (Manual)
### **Step 1: Build & Start**
```bash
docker compose up -d
```
- Builds Flask app image (layer cached)
- Creates `digiserver-network` bridge
- Starts `digiserver-app`, then `caddy`
### **Step 2: Database Initialization** (docker-entrypoint.sh)
On container start the entrypoint automatically:
1. Creates required directories
2. Checks for existing `dashboard.db`
3. If absent — creates tables and seeds admin user
4. Starts Gunicorn (4 workers, 120s timeout)
### **Step 3: Run Migrations**
```bash
docker compose exec -T digiserver-app python /app/migrations/<name>.py
```
Key migrations:
- `add_https_config_table.py` — HTTPS settings table
- `add_player_user_table.py` — Player user management
- `add_email_to_https_config.py` — Email field
- `migrate_player_user_global.py` — Global settings
- `add_url_to_content.py` — Web link support
- `add_deployment_fields_to_player.py` — Deployment tracking
### **Step 4: Configure HTTPS**
Via Admin UI (recommended):
1. Go to **Admin → HTTPS Config**
2. Enter hostname, domain, email, IP, port
3. Caddy auto-provisions a Let's Encrypt certificate
Via CLI:
```bash
docker compose exec -T digiserver-app python /app/https_manager.py enable \
<hostname> <domain> <email> <ip_address> <port>
```
### **Step 5: ProxyFix Middleware** (app/app.py)
Flask extracts real client info from Caddy headers:
- `X-Forwarded-For` → Real client IP
- `X-Forwarded-Proto` → Protocol (http/https)
- `X-Forwarded-Host` → Original hostname
- `X-Forwarded-Port` → Original port
---
## 🔄 Rebuild After Code Changes
Because the application code is baked into the Docker image, update it with:
```bash
# 1. Rebuild the image
docker build --no-cache -t digiserver-v2-digiserver-app .
# 2. Replace the running container
docker stop digiserver-v2 && docker rm digiserver-v2
docker compose up -d digiserver-app
```
**Quick test (no rebuild)** — copy files into the running container:
```bash
docker cp <local_file> digiserver-v2:/app/<path>
docker exec digiserver-v2 pkill -HUP -f gunicorn
```
---
## 🌐 Network Migration
When the server moves to a different network / IP:
```bash
./migrate_network.sh 10.55.150.160
# Optional: ./migrate_network.sh 10.55.150.160 digiserver-secured
```
This regenerates SSL certificates, updates the database HTTPS config, and restarts both containers.
---
## 📂 Directory Structure
```
digiserver-v2/
├── app/ (Flask application code)
│ ├── app.py (App factory)
│ ├── blueprints/ (Route definitions)
│ ├── models/ (SQLAlchemy models)
│ ├── templates/ (Jinja2 templates)
│ ├── static/uploads/ (Media files on disk)
│ └── utils/ (Helpers)
├── data/ (PERSISTENT — survives restarts)
│ ├── instance/dashboard.db (SQLite database)
│ ├── uploads/ (Media files)
│ ├── Caddyfile (Caddy config)
│ ├── caddy-data/ (Let's Encrypt certificates)
│ ├── caddy-config/ (Caddy JSON config)
│ └── caddy-logs/ (Access logs)
├── migrations/ (One-shot DB scripts)
├── old_code_documentation/ (Legacy Nginx files, etc.)
├── docker-compose.yml (Service definitions)
├── Dockerfile (Flask image build)
├── deploy.sh (Full automated deploy)
├── migrate_network.sh (Re-config after IP change)
└── docker-entrypoint.sh (Container startup)
```
---
## 🛠️ Common Commands
### **Containers**
```bash
docker compose up -d # Start all services
docker compose down # Stop all services
docker compose restart # Restart all
docker compose restart caddy # Restart only Caddy
```
### **Logs**
```bash
docker compose logs -f # Follow all
docker compose logs -f digiserver-app # Flask only
docker compose logs -f caddy # Caddy only
docker compose logs --tail=50 digiserver-app
```
### **Status**
```bash
docker compose ps
docker ps --format="table {{.Names}}\t{{.Status}}"
```
### **Database**
```bash
docker compose exec digiserver-app sqlite3 /app/instance/dashboard.db
docker compose exec digiserver-app cp /app/instance/dashboard.db \
/app/instance/dashboard.db.backup
```
### **Caddy**
```bash
docker exec digiserver-caddy caddy validate --config /etc/caddy/Caddyfile
docker exec digiserver-caddy caddy reload --config /etc/caddy/Caddyfile
```
---
## 🔒 HTTPS / SSL
Caddy automatically provisions Let's Encrypt certificates when a public domain is configured. For development with self-signed certificates:
```bash
bash generate_nginx_certs.sh 192.168.0.121 365
docker compose restart caddy
```
> **Note:** `generate_nginx_certs.sh` has been moved to `old_code_documentation/` but still works.
---
## 🐛 Troubleshooting
### **Containers not starting?**
```bash
docker compose logs
docker stats
```
### **App not responding?**
```bash
docker compose ps
curl http://localhost:5000/ # Bypass Caddy, hit Flask directly
docker compose logs -f digiserver-app
```
### **Caddy / HTTPS issues?**
```bash
docker exec digiserver-caddy caddy validate --config /etc/caddy/Caddyfile
ls -la ./data/caddy-data/certificates/
docker compose restart caddy
```