rvs-prxy/Design_Doc/Tech_Desc.md

10 KiB

Technical Architecture and Implementation Details

Script Architecture

The deploy-rvs-prxy.sh script is an automated deployment tool supporting both FRP and Traefik modes.

Key Architecture: The script runs directly on the same server where the application is hosted (local deployment), eliminating the need for SSH-based remote operations in Traefik mode.

Deployment Modes:

  1. Setup Reverse Proxy: Deploys new Traefik or FRP Tunnel with Traefik
  2. Setup New Domain: Adds new domain configuration to existing reverse proxy

Configuration File Structure:

  • .env.rvs-prxy - Reverse proxy instance configuration (FRP mode, Traefik version, etc.)
  • .env-<domain> - Domain-specific configuration (DOMAIN_NAME, LOCAL_SERVICE_NAME, LOCAL_SERVICE_PORT)
    • Domain format: Any domain format supported (.com, .net, .org, .org.hk, .com.hk, subdomains, etc.)
    • Filename pattern: Dots replaced with dashes (e.g., app.example.com → .env-app-example-com)
  • .env-port-<port> - Port-based routing configuration (HOST_PORT, CONTAINER_NAME, CONTAINER_PORT)
  • Multiple domain and port files can coexist for multiple domains and ports

Automatic Mode Detection:

  • No config files → Interactive wizard for proxy setup
  • .env.rvs-prxy exists, proxy not running → Setup Reverse Proxy
  • .env.rvs-prxy exists, proxy running, no domain/port file → Interactive wizard for domain/port setup
  • .env.rvs-prxy + .env-<domain> exists → Setup New Domain
  • .env.rvs-prxy + .env-port-<port> exists → Setup Port Exposure

Validation:

  • Proxy Setup Mode: Validates proxy-specific settings (TRAEFIK_VER, LETSENCRYPT_EMAIL for Traefik; FRP_SERVER_ADDR for FRP)
  • Domain Setup Mode: Validates domain-specific settings (DOMAIN_NAME, LOCAL_SERVICE_NAME, LOCAL_SERVICE_PORT)

Workflow:

First Run (No .env.rvs-prxy):

  1. Interactive wizard asks for proxy instance settings
  2. Creates .env.rvs-prxy with Traefik/FRP settings
  3. Validation checks proxy settings (TRAEFIK_VER, LETSENCRYPT_EMAIL)
  4. Deploys reverse proxy
  5. Shows message: "Next: Run the script again to setup your first domain or port"

Second Run (.env.rvs-prxy exists, proxy running):

  1. Detects running proxy
  2. Interactive wizard asks for domain or port settings
  3. Creates .env- or .env-port- with settings
  4. Validation checks domain/port settings
  5. Checks if application service/container is running
  6. Configures domain/port in existing reverse proxy
  7. Shows: "Service will be accessible at: https://domain.name or http://host-ip:port"

Three Deployment Modes:

  1. Setup Reverse Proxy - Deploys Traefik or FRP Tunnel
  2. Setup New Domain - Adds domain-based routing
  3. Setup Port Exposure - Adds port-based routing

Core Components

1. Environment Loading (load_env)

  • Loads configuration from .env.rvs-prxy.development, .env.rvs-prxy.production, or .env.rvs-prxy
  • Supports files in current directory or script directory
  • Interactive Setup Wizard: If no .env.rvs-prxy file is found, automatically launches a guided setup wizard
  • Normalizes boolean values (FRP variable)
  • Validates required parameters for each mode
  • Supports three modes: proxy setup, domain setup, and port exposure

Interactive Setup Wizard Features:

  • Step-by-step guided configuration
  • Mode selection (Traefik or FRP) for proxy setup
  • Choice between domain setup or port exposure when proxy exists
  • Mode-specific configuration prompts
  • Sensible defaults for all settings
  • Automatic saving to .env.rvs-prxy, .env-<domain>, or .env-port-<port> files

2. Instance Management (prompt_instance_name)

  • Auto-detects existing instances from Docker volumes (FRP mode)
  • Supports instance name override via INSTANCE_NAME environment variable
  • Generates timestamped default names
  • Saves selections to .env for future runs

3. Docker Network Selection (select_docker_network)

  • Lists available Docker networks
  • Supports custom network names
  • Remembers previous selections via .para file in volume (FRP mode)

4. Configuration Generation

  • FRP Mode: Generates frpc.toml with dynamic proxy configurations
  • Traefik Mode: Generates YAML configuration files for routing rules (local deployment)

5. Container Management

  • Creates and manages Docker containers with persistent volumes
  • Supports container restart and lifecycle operations
  • Displays operation commands for user reference

Traefik Mode Implementation (Local Deployment)

Setup Flow (setup_traefik_only)

  1. Pre-request Checks

    • Verify Docker command permissions
  2. Application Service Verification (check_app_service_local)

    • Confirms target service is running locally
    • Verifies connection to traefik-public network
  3. Traefik Container Creation (create_traefik_container_local)

    • Creates traefik_data volume for persistence
    • Generates dynamic configuration with:
      • Dashboard routing
      • HTTP to HTTPS redirect
      • Security headers
    • Creates traefik-public Docker network
    • Uses Docker Compose for container orchestration
    • Detects Docker version for command compatibility (docker compose vs docker-compose)
  4. Service Configuration (configure_traefik_local)

    • Generates service-specific routing rules
    • Supports sub-path routing (e.g., example.com/api)
    • Creates unique configuration filenames to avoid conflicts
    • Supports dynamic configuration loading (no restart required by default)

Local Docker Operations

  • local_docker_exec(): Executes Docker commands directly on the local server
  • local_volume_copy(): Copies files to Docker volumes using temporary containers

Configuration File Structure

Traefik Main Config (traefik.yml):

http:
  routers:
    api:
      rule: "PathPrefix(`/api`)"
      service: api@internal
    dashboard:
      rule: "PathPrefix(`/dashboard`)"
      service: api@internal
    http-catchall:
      rule: "PathRegexp(`{any:.*}`)"
      entryPoints:
        - "web"
      service: "noop@internal"
      middlewares:
        - "redirect-to-https"
  middlewares:
    api-headers:
      headers:
        customFrameOptionsValue: SAMEORIGIN
        contentTypeNosniff: true
        browserXssFilter: true
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 15552000
    redirect-to-https:
      redirectScheme:
        scheme: "https"
        permanent: true

Service Config (dynamic, per-service):

http:
  routers:
    <service-name>-https:
      rule: 'Host(`<domain>`)'
      service: <service-name>-service
      tls:
        certResolver: letsencrypt
      entryPoints:
        - websecure
    <service-name>-http:
      rule: 'Host(`<domain>`)'
      service: <service-name>-service
      entryPoints:
        - web
      middlewares:
        - redirect-to-https
  services:
    <service-name>-service:
      loadBalancer:
        servers:
          - url: 'http://<service-name>:<port>'
        passHostHeader: true

Entrypoints Configuration: Default entrypoints (web on :80, websecure on :443) are defined in the docker-compose.yml command args. Additional entrypoints can be configured via the EXTRA_ENTRYPOINTS environment variable in .env.rvs-prxy:

  • Format: name=:port/protocol,name2=:port (comma-separated)
  • Example: quic=:443/udp enables HTTP/3 QUIC on UDP port 443
  • These are injected into both the docker-compose.yml command: section and the docker run command
  • Port mappings (TCP/UDP) are automatically added to the ports: section
  • The parse_extra_entrypoints() function parses the variable and builds:
    • EXTRA_ENTRYPOINT_ARGS: array of --entrypoints.<name>.address=<address> args
    • EXTRA_PORT_MAPPINGS: array of port mappings in host:container/protocol format
    • EXTRA_COMPOSE_ENTRYPOINTS: YAML lines for docker-compose.yml command section
    • EXTRA_COMPOSE_PORTS: YAML lines for docker-compose.yml ports section

FRP Mode Implementation

Setup Flow

  1. Instance Setup: Prompt for instance name
  2. Port Configuration: Prompt for internal service port
  3. FRP Config Generation (generate_frpc_config)
    • Extracts existing configuration from volume
    • Supports dynamic proxy configurations via PROXY_*_PORT variables
    • Generates frpc.toml with TCP proxy rules
  4. Container Start (start_docker_container)
    • Creates volume if not exists
    • Starts frpc container with configuration mounted
  5. Proxy Server Update (update_proxy_server_config)
    • Uploads dynamic configuration script to proxy server
    • Updates docker-compose.app.yml with port mappings and labels
    • Supports domain-based routing configuration

Dynamic Proxy Configuration

The script supports dynamic proxy configurations through environment variables:

  • PROXY_<NAME>_PORT: Defines remote port for proxy
  • PROXY_<NAME>_LOCAL_PORT: Defines local port (defaults to INTERNAL_SERVICE_PORT)

Example:

PROXY_WEB_PORT=12077
PROXY_WEB_LOCAL_PORT=3000
PROXY_SSH_PORT=2222
PROXY_SSH_LOCAL_PORT=22

Proxy Server Configuration Update

The script generates and executes a remote script on the proxy server that:

  • Checks existing configuration status (not_found, up_to_date, outdated)
  • Updates port mappings section in docker-compose.app.yml
  • Updates labels section for Traefik routing
  • Optionally restarts Docker Compose service

File Deployment (Traefik Mode)

The deploy command syncs files from local folder to target server:

  • Source: LOCAL_FOLDER (default: ../out/)
  • Destination: DEST_PATH on target server
  • Uses rsync for efficient synchronization with --delete option

Logging and Debugging

Logging Functions:

  • log_info(): Green [INFO] messages
  • log_error(): Red [ERROR] messages
  • log_warn(): Yellow [WARN] messages
  • log_debug(): Blue [DEBUG] messages (only when DEBUG=true)

Status Commands:

  • check_status_on_target(): Shows Traefik and Application service status
  • view_traefik_logs(): Displays last 50 lines of Traefik logs

Error Handling

  • Uses set -e for immediate exit on errors
  • Validates required parameters before execution
  • Provides detailed error messages with suggested fixes
  • Graceful handling of missing configurations

Version Compatibility

Docker Version Detection:

  • Detects Docker version to determine command syntax
  • Uses docker compose for Docker 20.10.0+
  • Falls back to docker-compose for older versions
  • Handles Compose file version field (deprecated in v2.0+)

Traefik Version:

  • Default: v3.6.9
  • Configurable via TRAEFIK_VER environment variable