#!/bin/bash # ============================================================================= # usulnet - Quick Install Script # # Usage: # curl -fsSL https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy/install.sh | bash # # Or download and run manually: # chmod +x install.sh && ./install.sh # # ============================================================================= set -euo pipefail INSTALL_DIR="${USULNET_DIR:-/opt/usulnet}" REPO_BASE="https://raw.githubusercontent.com/fr4nsys/usulnet/main/deploy" echo "============================================" echo " usulnet Docker Management Platform" echo " Installation Script" echo "============================================" echo "" # --- Prerequisites --- if ! command -v docker &>/dev/null; then echo "ERROR: Docker is not installed." echo "Install Docker: https://docs.docker.com/engine/install/" exit 1 fi if ! docker compose version &>/dev/null 2>&1; then echo "ERROR: Docker Compose v2 is not available." echo "Install: https://docs.docker.com/compose/install/" exit 1 fi if ! command -v openssl &>/dev/null; then echo "WARNING: openssl not found. Secrets will use /dev/urandom fallback." fi if ! command -v curl &>/dev/null; then echo "ERROR: curl is required." exit 1 fi # --- Create directory --- echo "Install directory: ${INSTALL_DIR}" mkdir -p "${INSTALL_DIR}" cd "${INSTALL_DIR}" # --- Download docker-compose --- echo "Downloading docker-compose.yml..." curl -fsSL "${REPO_BASE}/docker-compose.prod.yml" -o docker-compose.yml curl -fsSL "${REPO_BASE}/.env.example" -o .env # --- Generate secrets --- echo "Generating secure secrets..." generate_hex() { if command -v openssl &>/dev/null; then openssl rand -hex 32 else head -c 32 /dev/urandom | xxd -p -c 64 fi } generate_password() { if command -v openssl &>/dev/null; then openssl rand -base64 24 | tr -dc 'a-zA-Z0-9' | head -c 32 else head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 32 fi } DB_PASSWORD=$(generate_password) JWT_SECRET=$(generate_hex) ENCRYPTION_KEY=$(generate_hex) # Replace DB_PASSWORD placeholder in .env (for PostgreSQL service) sed -i "s|CHANGE_ME_GENERATE_RANDOM_PASSWORD|${DB_PASSWORD}|" .env # --- Generate config.yaml --- echo "Generating config.yaml..." cat > config.yaml </pki) # Database (PostgreSQL) database: url: "postgres://usulnet:${DB_PASSWORD}@postgres:5432/usulnet?sslmode=disable" max_open_conns: 25 max_idle_conns: 10 conn_max_lifetime: "30m" conn_max_idle_time: "5m" # Redis (caching and sessions) redis: url: "redis://redis:6379" password: "" db: 0 # NATS (messaging) nats: url: "nats://nats:4222" name: "usulnet" # token: "" # NATS auth token (if server requires it) # username: "" # NATS username (alternative to token) # password: "" # NATS password jetstream: enabled: true # tls: # TLS encryption for NATS connections # enabled: false # cert_file: "" # Client certificate path (for mutual TLS) # key_file: "" # Client private key path # ca_file: "" # CA certificate path (for server verification) # skip_verify: false # Skip server certificate verification (dev only) # Security (JWT, encryption, passwords) # This is the section the app validates - NOT "auth" security: # Generate with: openssl rand -hex 32 jwt_secret: "${JWT_SECRET}" jwt_expiry: "24h" refresh_expiry: "168h" # Generate with: openssl rand -hex 32 (must be 64 hex chars = 32 bytes) config_encryption_key: "${ENCRYPTION_KEY}" cookie_secure: false cookie_samesite: "lax" password_min_length: 8 # Storage (backups) storage: type: "local" path: "/app/data" backup: compression: "gzip" default_retention_days: 30 # Trivy (security scanning) trivy: enabled: true cache_dir: "/var/lib/usulnet/trivy" timeout: "5m" severity: "CRITICAL,HIGH,MEDIUM" ignore_unfixed: false update_db_on_start: true # Nginx Proxy Manager integration (connect via Settings UI) npm: enabled: false # Caddy reverse proxy integration (connect via Settings UI) caddy: enabled: false # Enable Caddy reverse proxy integration (or env USULNET_CADDY_ENABLED) admin_url: "" # Caddy admin API (or env USULNET_CADDY_ADMIN_URL) acme_email: "" # ACME email for Let's Encrypt (or env USULNET_CADDY_ACME_EMAIL) listen_http: ":80" listen_https: ":443" # MinIO/S3 storage (connect via Settings UI) minio: enabled: false # Docker settings (passed via socket mount, not config) # docker: # socket: "/var/run/docker.sock" # Logging logging: level: "info" format: "json" YAML # --- Start --- echo "" echo "Starting usulnet..." docker compose up -d echo "" echo "============================================" echo " usulnet installed successfully!" echo "============================================" echo "" echo " Access usulnet:" echo " HTTPS: https://$(hostname -I 2>/dev/null | awk '{print $1}' || echo 'localhost'):7443" echo " HTTP: http://$(hostname -I 2>/dev/null | awk '{print $1}' || echo 'localhost'):8080" echo "" echo " Files: ${INSTALL_DIR}/" echo " config.yaml # Application configuration" echo " .env # Docker Compose variables" echo " docker-compose.yml" echo "" echo " Useful commands:" echo " cd ${INSTALL_DIR}" echo " docker compose logs -f # View logs" echo " docker compose restart # Restart" echo " docker compose down # Stop" echo " docker compose pull && docker compose up -d # Update" echo ""