Add better prod setup
This commit is contained in:
parent
279dc7f2c3
commit
c25cbf5101
2 changed files with 300 additions and 9 deletions
|
|
@ -2,7 +2,35 @@
|
|||
|
||||
This guide provides instructions for deploying Kaboot to a production environment with Caddy reverse proxy and automatic HTTPS.
|
||||
|
||||
## Quick Start (Caddy + Automated Authentik Setup)
|
||||
## Quick Start (Automated Setup)
|
||||
|
||||
The easiest way to deploy Kaboot is using the automated setup script:
|
||||
|
||||
```bash
|
||||
# Run the production setup script with your domains
|
||||
./scripts/setup-prod.sh --domain kaboot.example.com --auth-domain auth.example.com
|
||||
|
||||
# Or run interactively (will prompt for domains)
|
||||
./scripts/setup-prod.sh
|
||||
```
|
||||
|
||||
This script automatically:
|
||||
- Generates all required secrets (database passwords, API tokens, etc.)
|
||||
- Creates the production `.env` file
|
||||
- Creates the `Caddyfile` with your domains
|
||||
- Creates the Authentik production blueprint
|
||||
- Removes the development blueprint
|
||||
- Builds the frontend with production URLs
|
||||
|
||||
After running the script, start the stack:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml -f docker-compose.caddy.yml up -d
|
||||
```
|
||||
|
||||
## Manual Setup
|
||||
|
||||
If you prefer to configure manually, follow these steps:
|
||||
|
||||
```bash
|
||||
# 1. Generate secrets
|
||||
|
|
@ -59,16 +87,22 @@ In production, the stack consists of:
|
|||
|
||||
## Environment Variables
|
||||
|
||||
Create a production `.env` file. Do not commit this file to version control.
|
||||
The `setup-prod.sh` script generates the `.env` file automatically. If you need to create it manually, here's the required configuration:
|
||||
|
||||
### Backend & Authentik Configuration
|
||||
|
||||
```env
|
||||
# Database Passwords (Generated by setup.sh)
|
||||
# Database (generate with: openssl rand -base64 36)
|
||||
PG_PASS=your_strong_postgres_password
|
||||
PG_USER=authentik
|
||||
PG_DB=authentik
|
||||
|
||||
# Authentik Secrets (generate with: openssl rand -base64 60)
|
||||
AUTHENTIK_SECRET_KEY=your_strong_authentik_secret
|
||||
|
||||
# Bootstrap credentials (Generated by setup.sh)
|
||||
# Bootstrap credentials - used for initial Authentik setup
|
||||
# AUTHENTIK_BOOTSTRAP_PASSWORD: Admin password (generate with: openssl rand -base64 24)
|
||||
# AUTHENTIK_BOOTSTRAP_TOKEN: API token (generate with: openssl rand -hex 32)
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD=your_admin_password
|
||||
AUTHENTIK_BOOTSTRAP_TOKEN=your_api_token
|
||||
|
||||
|
|
@ -78,15 +112,18 @@ OIDC_JWKS_URI=https://auth.example.com/application/o/kaboot/jwks/
|
|||
|
||||
# Security
|
||||
CORS_ORIGIN=https://kaboot.example.com
|
||||
NODE_ENV=production
|
||||
LOG_REQUESTS=true
|
||||
```
|
||||
|
||||
### Frontend Configuration
|
||||
|
||||
The frontend requires environment variables at build time:
|
||||
The frontend requires environment variables at **build time** (not runtime):
|
||||
- `VITE_API_URL`: `https://kaboot.example.com/api`
|
||||
- `VITE_OIDC_AUTHORITY`: `https://auth.example.com/application/o/kaboot/`
|
||||
|
||||
The `setup-prod.sh` script sets these automatically when building.
|
||||
|
||||
## Docker Compose Files
|
||||
|
||||
The project includes pre-configured compose files:
|
||||
|
|
@ -236,9 +273,19 @@ server {
|
|||
|
||||
## Authentik Configuration for Production
|
||||
|
||||
### Option A: Automated Setup with Blueprint (Recommended)
|
||||
### Option A: Automated Setup (Recommended)
|
||||
|
||||
Use the production blueprint for automated configuration:
|
||||
The `setup-prod.sh` script handles all Authentik configuration automatically:
|
||||
|
||||
```bash
|
||||
./scripts/setup-prod.sh --domain your-app.com --auth-domain auth.your-app.com
|
||||
```
|
||||
|
||||
This creates the production blueprint with your domains and removes the development blueprint.
|
||||
|
||||
### Option B: Manual Blueprint Setup
|
||||
|
||||
If configuring manually:
|
||||
|
||||
```bash
|
||||
# 1. Copy and configure the production blueprint
|
||||
|
|
@ -257,7 +304,7 @@ rm authentik/blueprints/kaboot-setup.yaml
|
|||
docker compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### Option B: Manual Configuration
|
||||
### Option C: Manual UI Configuration
|
||||
|
||||
1. **Update Redirect URIs**: In the Authentik Admin interface, go to **Applications** > **Providers** > **Kaboot OAuth2**. Update the **Redirect URIs** to use your production domain:
|
||||
- `https://kaboot.example.com/callback`
|
||||
|
|
@ -291,7 +338,7 @@ docker exec kaboot-postgresql pg_dump -U authentik authentik > authentik_backup_
|
|||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] Run `./scripts/setup.sh` to generate strong secrets (don't use defaults).
|
||||
- [ ] Run `./scripts/setup-prod.sh` to generate strong secrets (don't use defaults).
|
||||
- [ ] Ensure `NODE_ENV` is set to `production`.
|
||||
- [ ] Use HTTPS for all connections (Caddy handles this automatically).
|
||||
- [ ] Set `CORS_ORIGIN` to your specific frontend domain (e.g., `https://kaboot.example.com`).
|
||||
|
|
|
|||
244
scripts/setup-prod.sh
Executable file
244
scripts/setup-prod.sh
Executable file
|
|
@ -0,0 +1,244 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
BOLD='\033[1m'
|
||||
NC='\033[0m'
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}${BOLD}════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE}${BOLD} Kaboot Production Setup${NC}"
|
||||
echo -e "${BLUE}${BOLD}════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_step() {
|
||||
echo -e "${GREEN}${BOLD}▶ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✖ $1${NC}"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✔ $1${NC}"
|
||||
}
|
||||
|
||||
print_header
|
||||
|
||||
KABOOT_DOMAIN=""
|
||||
AUTH_DOMAIN=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--domain)
|
||||
KABOOT_DOMAIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--auth-domain)
|
||||
AUTH_DOMAIN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --domain DOMAIN Main application domain (e.g., kaboot.example.com)"
|
||||
echo " --auth-domain DOMAIN Authentication domain (e.g., auth.example.com)"
|
||||
echo " --help, -h Show this help message"
|
||||
echo ""
|
||||
echo "If options are not provided, you will be prompted for them."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -f ".env.example" ]; then
|
||||
print_error "Error: .env.example not found. Run this script from the project root."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f ".env" ]; then
|
||||
print_warning ".env file already exists."
|
||||
read -p "Overwrite existing configuration? (y/N): " -n 1 -r
|
||||
echo ""
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Aborting. Existing configuration preserved."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${BOLD}Domain Configuration${NC}"
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
|
||||
if [ -z "$KABOOT_DOMAIN" ]; then
|
||||
read -p "Enter your main domain (e.g., kaboot.example.com): " KABOOT_DOMAIN
|
||||
fi
|
||||
|
||||
if [ -z "$KABOOT_DOMAIN" ]; then
|
||||
print_error "Domain is required."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$AUTH_DOMAIN" ]; then
|
||||
DEFAULT_AUTH="auth.${KABOOT_DOMAIN}"
|
||||
read -p "Enter your auth domain [$DEFAULT_AUTH]: " AUTH_DOMAIN
|
||||
AUTH_DOMAIN=${AUTH_DOMAIN:-$DEFAULT_AUTH}
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_step "Generating secrets..."
|
||||
|
||||
PG_PASS=$(openssl rand -base64 36 | tr -d '\n' | tr -d '/')
|
||||
AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n' | tr -d '/')
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD=$(openssl rand -base64 24 | tr -d '\n' | tr -d '/')
|
||||
AUTHENTIK_BOOTSTRAP_TOKEN=$(openssl rand -hex 32)
|
||||
|
||||
print_success "Secrets generated"
|
||||
|
||||
print_step "Creating .env file..."
|
||||
|
||||
cat > .env << EOF
|
||||
# Kaboot Production Configuration
|
||||
# Generated by setup-prod.sh on $(date)
|
||||
|
||||
# Database
|
||||
PG_PASS=${PG_PASS}
|
||||
PG_USER=authentik
|
||||
PG_DB=authentik
|
||||
|
||||
# Authentik Secrets
|
||||
AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
|
||||
AUTHENTIK_BOOTSTRAP_PASSWORD=${AUTHENTIK_BOOTSTRAP_PASSWORD}
|
||||
AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}
|
||||
AUTHENTIK_ERROR_REPORTING=false
|
||||
|
||||
# OIDC Configuration (Production)
|
||||
OIDC_ISSUER=https://${AUTH_DOMAIN}/application/o/kaboot/
|
||||
OIDC_JWKS_URI=https://${AUTH_DOMAIN}/application/o/kaboot/jwks/
|
||||
|
||||
# Security
|
||||
CORS_ORIGIN=https://${KABOOT_DOMAIN}
|
||||
NODE_ENV=production
|
||||
LOG_REQUESTS=true
|
||||
EOF
|
||||
|
||||
print_success "Created .env"
|
||||
|
||||
print_step "Creating Caddyfile..."
|
||||
|
||||
cat > Caddyfile << EOF
|
||||
# Kaboot Production Caddyfile
|
||||
# Generated by setup-prod.sh on $(date)
|
||||
|
||||
${KABOOT_DOMAIN} {
|
||||
root * /srv/frontend
|
||||
file_server
|
||||
try_files {path} /index.html
|
||||
|
||||
handle /api/* {
|
||||
reverse_proxy kaboot-backend:3001
|
||||
}
|
||||
|
||||
handle /health {
|
||||
reverse_proxy kaboot-backend:3001
|
||||
}
|
||||
}
|
||||
|
||||
${AUTH_DOMAIN} {
|
||||
reverse_proxy authentik-server:9000 {
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
header_up X-Forwarded-Host {host}
|
||||
transport http {
|
||||
keepalive 30s
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
print_success "Created Caddyfile"
|
||||
|
||||
print_step "Creating production Authentik blueprint..."
|
||||
|
||||
BLUEPRINT_DIR="authentik/blueprints"
|
||||
PROD_BLUEPRINT="${BLUEPRINT_DIR}/kaboot-setup-production.yaml"
|
||||
DEV_BLUEPRINT="${BLUEPRINT_DIR}/kaboot-setup.yaml"
|
||||
|
||||
if [ -f "${BLUEPRINT_DIR}/kaboot-setup-production.yaml.example" ]; then
|
||||
sed "s/kaboot.example.com/${KABOOT_DOMAIN}/g; s/auth.example.com/${AUTH_DOMAIN}/g" \
|
||||
"${BLUEPRINT_DIR}/kaboot-setup-production.yaml.example" > "$PROD_BLUEPRINT"
|
||||
print_success "Created production blueprint"
|
||||
else
|
||||
print_warning "Production blueprint example not found, skipping..."
|
||||
fi
|
||||
|
||||
if [ -f "$DEV_BLUEPRINT" ]; then
|
||||
rm "$DEV_BLUEPRINT"
|
||||
print_success "Removed development blueprint"
|
||||
fi
|
||||
|
||||
print_step "Building frontend with production URLs..."
|
||||
|
||||
VITE_API_URL="https://${KABOOT_DOMAIN}/api" \
|
||||
VITE_OIDC_AUTHORITY="https://${AUTH_DOMAIN}/application/o/kaboot/" \
|
||||
npm run build --silent 2>/dev/null || npm run build
|
||||
|
||||
print_success "Frontend built"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${GREEN}${BOLD} Setup Complete!${NC}"
|
||||
echo -e "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
echo -e "${BOLD}Configuration Summary${NC}"
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo -e " Main Domain: ${BLUE}https://${KABOOT_DOMAIN}${NC}"
|
||||
echo -e " Auth Domain: ${BLUE}https://${AUTH_DOMAIN}${NC}"
|
||||
echo ""
|
||||
echo -e "${BOLD}Authentik Admin Credentials${NC}"
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo -e " Username: ${YELLOW}akadmin${NC}"
|
||||
echo -e " Password: ${YELLOW}${AUTHENTIK_BOOTSTRAP_PASSWORD}${NC}"
|
||||
echo ""
|
||||
echo -e "${RED}${BOLD}⚠ SAVE THESE CREDENTIALS - They won't be shown again!${NC}"
|
||||
echo ""
|
||||
echo -e "${BOLD}Files Created${NC}"
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo " .env - Environment variables"
|
||||
echo " Caddyfile - Reverse proxy config"
|
||||
echo " authentik/blueprints/kaboot-setup-production.yaml"
|
||||
echo " dist/ - Built frontend"
|
||||
echo ""
|
||||
echo -e "${BOLD}Next Steps${NC}"
|
||||
echo "────────────────────────────────────────────────────────────"
|
||||
echo ""
|
||||
echo " 1. Ensure DNS records point to this server:"
|
||||
echo -e " ${KABOOT_DOMAIN} → ${BLUE}<your-server-ip>${NC}"
|
||||
echo -e " ${AUTH_DOMAIN} → ${BLUE}<your-server-ip>${NC}"
|
||||
echo ""
|
||||
echo " 2. Start the production stack:"
|
||||
echo -e " ${YELLOW}docker compose -f docker-compose.prod.yml -f docker-compose.caddy.yml up -d${NC}"
|
||||
echo ""
|
||||
echo " 3. Wait for services to start (~60 seconds for Authentik)"
|
||||
echo ""
|
||||
echo " 4. Verify all services are running:"
|
||||
echo -e " ${YELLOW}docker compose -f docker-compose.prod.yml -f docker-compose.caddy.yml ps${NC}"
|
||||
echo ""
|
||||
echo " 5. Check Authentik blueprint was applied:"
|
||||
echo -e " ${YELLOW}docker compose -f docker-compose.prod.yml logs authentik-server | grep -i blueprint${NC}"
|
||||
echo ""
|
||||
echo " 6. Access your app at:"
|
||||
echo -e " ${BLUE}https://${KABOOT_DOMAIN}${NC}"
|
||||
echo ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue