# Generic Reverse Proxy Architecture ## Overview This document describes a generic reverse proxy architecture that enables internal services to be accessible via public domains. The architecture uses FRP (Fast Reverse Proxy) for tunneling and Traefik for HTTP/HTTPS routing with automatic certificate management. ## Architecture Block Diagram ``` +-------------------+ SSH Commands +-------------------+ | Local Host | ------------------> | Proxy Server | | | | | | +-------------+ | FRP Tunnel | +-------------+ | | | Application | | ------------------> | | FRPS | | | | Service | | | | (Server) | |<--- Public IPs | | | | | | | | Port: 16999 | +-------------+ | | +-------------+ | | | | | | +-------------+ | FRP Client | +-------------+ | | | FRPC | | ------------------> | | Traefik | |<--- Domains | | (Client) | | | | (Router) | | HTTPS/TLS | | | | | | | | | +-------------+ | | +-------------+ | | | | | | +-------------+ | | +-------------+ | | | Docker | | | | Docker | | | | Container | | | | Container | | | +-------------+ | | +-------------+ | +-------------------+ +-------------------+ | | | | +------------------ Volumes ------------------+ | rad-git-sshd-itl-frpc- | +-------------------------------------------+ ``` ## Architecture Components ### Core Components - **FRP (Fast Reverse Proxy)**: Handles TCP/UDP tunneling between internal and external networks - FRPS (FRP Server): Runs on the public-facing server - FRPC (FRP Client): Runs on internal service hosts - **Traefik**: HTTP/HTTPS router with automatic Let's Encrypt certificate management - **Docker & Docker Compose**: Container orchestration and deployment - **SSH**: Secure communication for remote configuration management ### Supporting Elements - **Configuration Storage**: Docker volumes for persistent configuration - **DNS Management**: Domain-to-IP mapping for public access - **Certificate Management**: Automatic SSL/TLS certificate provisioning and renewal ## Prerequisites - FRP (Fast Reverse Proxy) service with frpc and frps - Traefik reverse proxy - Docker and Docker Compose installed - SSH key for remote server access - SSH key at `~/.ssh/itl-devs1` for proxy server access - User permissions for Docker commands - Authentication keys for secure access ## Parameters ### Required Parameters - **Instance Name**: Unique identifier for the service instance (alphanumeric, hyphens, underscores only) - **Internal Service Port**: The port exposed by the target Docker container (e.g., 3000) - **Domain Name**: Public domain for Traefik routing rules - **FRP Server Address**: Public IP address of the FRP server - **FRP Server Port**: Port for FRP communication (default 16999) ### Optional Parameters - **Docker Network**: Network for connecting to internal service container (default uses Docker bridge) - **Proxy Ports**: Custom remote ports for external access (defaults: TCP ports matching internal ports) - **Service Type**: Protocol specification (TCP/UDP/HTTP/HTTPS) ### Environment Configuration The architecture supports environment-based configuration using `.env` files to provide default values: - **Environment Files**: `.env`, `.env.development`, `.env.production` - **Default Values**: Parameters from environment files are used as defaults during script execution - **Interactive Fallback**: If parameters are missing from environment files, scripts will prompt for input - **Auto-Persistence**: Answered parameters are automatically saved to the appropriate `.env` file for future use - **Supported Variables**: - `INSTANCE_NAME`: Default instance name - `INTERNAL_SERVICE_PORT`: Port exposed by the target Docker container (e.g., 3000) - `DOCKER_NETWORK`: Docker network for connecting to internal service container - `FRP_SERVER_ADDR`: FRP server address - `FRP_SERVER_PORT`: FRP server port (default 16999) - `DOMAIN_NAME`: Default domain name - `RAD_REMOTE_PORT`: Remote port for rad proxy (default 8779) - `SSH_REMOTE_PORT`: Remote port for SSH proxy (default 13076) - `WEB_REMOTE_PORT`: Remote port for web proxy (default 13077) - `PROXY_*_PORT`: Dynamic proxy configuration (e.g., `PROXY_API_PORT=8080`) - `PROXY_*_LOCAL_PORT`: Local port for the corresponding proxy (e.g., `PROXY_API_LOCAL_PORT=8000`) ### Dynamic Proxy Configuration The system supports dynamic proxy configuration through environment variables: - **Format**: Use `PROXY_*_PORT` format to define additional proxies - **Examples**: `PROXY_API_PORT=8080`, `PROXY_DATABASE_PORT=5432` - **Local Port Override**: Use `PROXY_*_LOCAL_PORT` to specify a different local port - **Flexibility**: Allows configuration of any number of application-specific proxies ### Internal Service Connection The architecture connects to internal services on the same computer as the script execution: - **Connection Method**: FRP client connects to target service on the same physical/virtual machine - **Local IP**: Connection made via 127.0.0.1 (localhost) to the service port - **Port Configuration**: Target service must be accessible on the specified port (e.g., 3000) - **Service Discovery**: No container name resolution needed, connects directly to localhost - **Local IP Setting**: FRP client configuration uses 127.0.0.1 as the local IP - **Naming Convention**: Container and volume names follow the format `{INSTANCE_NAME}-frpc` ## Outcomes - Public domain connectivity to internal service - Secure encrypted tunnel between internal and external networks - Automatic SSL/TLS certificates via Let's Encrypt - Persistent configuration through Docker volumes - Automated service discovery and routing ## Architecture Flow ### 1. Configuration Phase 1. User provides service parameters via interactive prompts or command-line 2. System validates parameters and checks for existing configurations 3. Generates appropriate FRP client configuration (frpc.toml) 4. Persists configuration to Docker volumes for continuity ### 2. Deployment Phase 1. Creates Docker container with FRP client 2. Establishes connection to FRP server 3. Sets up port forwarding rules 4. Updates proxy server to recognize new instance ### 3. Routing Phase 1. Traefik configuration updated with new routing rules 2. Domain name routes to appropriate internal service 3. Automatic SSL/TLS certificate provisioned 4. Health checks and monitoring established ### 4. Management Phase 1. Persistent configuration for service continuity 2. Backup and recovery mechanisms 3. Restart procedures for configuration changes 4. Service status monitoring ## Real-World Example: Using auto-sys-deploy.sh and update-compose-config.sh ### Example: Deploying a New FRP Client Instance Based on `auto-sys-deploy.sh.md` and `update-compose-config.sh.md`, here's a real-world example of the architecture in action: #### Initial Setup - **Prerequisites**: Docker, SSH key at `~/.ssh/itl-devs1` - **Command**: `./auto-sys-deploy.sh setup-rvs-prxy` #### Interactive Configuration (from auto-sys-deploy.sh) 1. **Instance Name Selection**: - Default: `setup-rvs-prxy-$(date +%Y%m%d-%H%M%S)` - User input: `my-app-instance-20231005-143000` - Validation: alphanumeric, hyphens, underscores only 2. **Docker Network Selection**: - Options: Select from existing networks, custom network, or default - User input: Select network `bridge` or create custom - Outcome: Container runs on specific Docker network 3. **FRP Server Configuration**: - Server Address: `192.168.1.100` (example IP) - Server Port: `16999` (default) - Validation: Ensure server is accessible 4. **Dynamic Proxy Configuration**: - Proxies are configured dynamically based on environment variables following the format `PROXY_*_PORT` - Default rad proxy (if `RAD_REMOTE_PORT` is set): - Local Port: `8776` (default) - Remote Port: Value of `RAD_REMOTE_PORT` environment variable - Name: `rad-my-app-instance-20231005-143000` - Default SSH proxy (if `SSH_REMOTE_PORT` is set): - Local Port: `22` (default) - Remote Port: Value of `SSH_REMOTE_PORT` environment variable - Name: `ssh-my-app-instance-20231005-143000` - Default Web proxy (if `WEB_REMOTE_PORT` is set): - Local Port: Service port or `80` (default) - Remote Port: Value of `WEB_REMOTE_PORT` environment variable - Name: `web-my-app-instance-20231005-143000` - Additional proxies can be configured using `PROXY_*_PORT` environment variables - Format: `PROXY_API_PORT=8080`, `PROXY_DATABASE_PORT=5432`, etc. - The script will create as many proxies as defined by the environment variables 5. **Domain Configuration**: - Input: `myapp.example.com` - Used for Traefik routing rules #### Configuration Generation (from auto-sys-deploy.sh) The script generates `frpc.toml` with: ```toml serverAddr = "192.168.1.100" serverPort = 16999 [[proxies]] name = "rad-my-app-instance-20231005-143000" type = "tcp" localPort = 8776 localIP = "rad-git-sshd-my-app-instance-20231005-143000" remotePort = 8779 [[proxies]] name = "ssh-my-app-instance-20231005-143000" type = "tcp" localPort = 22 localIP = "rad-git-sshd-my-app-instance-20231005-143000" remotePort = 13076 [[proxies]] name = "web-my-app-instance-20231005-143000" type = "tcp" localPort = 80 localIP = "rad-git-sshd-my-app-instance-20231005-143000" remotePort = 13077 ``` #### Container Deployment (from auto-sys-deploy.sh) - Creates Docker volume: `rad-git-sshd-itl-frpc-my-app-instance-20231005-143000` - Starts container: `rad-git-sshd-frpc-my-app-instance-20231005-143000` - Uses image: `snowdreamtech/frpc:0.62.0-alpine3.21` - Mounts config volume: `/etc/frp` #### Proxy Server Configuration (from update-compose-config.sh) The script updates `docker-compose.app.yml` with: **Ports Section:** ```yaml ports: # ... other ports ... # my-app-instance-20231005-143000 Self-hosting ports ==== - "8779:8779/tcp" - "13076:13076/tcp" - "13077:13077/tcp" # ========================= # ... other ports ... ``` **Labels Section:** ```yaml labels: # ... other labels ... # my-app-instance-20231005-143000 Self-hosting labels ==== - "traefik.http.routers.frps-my-app-instance-20231005-143000-http.entrypoints=web" - "traefik.http.routers.frps-my-app-instance-20231005-143000-http.rule=Host(`myapp.example.com`)" - "traefik.http.routers.frps-my-app-instance-20231005-143000-http.service=frps-my-app-instance-20231005-143000" - "traefik.http.routers.frps-my-app-instance-20231005-143000-http.middlewares=http2https@file" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.entrypoints=websecure" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.rule=Host(`myapp.example.com`)" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.service=frps-my-app-instance-20231005-143000" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls=true" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls.certresolver=letsencrypt" - "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls.domains[0].main=myapp.example.com" - "traefik.http.services.frps-my-app-instance-20231005-143000.loadbalancer.server.port=13077" # ========================= # ... other labels ... ``` #### Backup and Service Restart (from update-compose-config.sh) - Creates backup: `docker-compose.app.yml.backup_YYYYMMDD_HHMMSS` - Restarts service with: `./stop.sh && ./start.sh` - Verifies deployment with: `docker logs --tail 50 frps_frps_1` ## Extensibility Points ### Protocol Support - **TCP/UDP**: Native FRP support for any TCP/UDP based service - **HTTP/HTTPS**: Enhanced routing via Traefik with automatic certificates - **Custom Protocols**: Extensible architecture for proprietary protocols ### Service Types - **Web Applications**: HTTP/HTTPS routing with domain-based access - **Database Services**: Secure TCP tunneling for database connections - **SSH Services**: Encrypted access to internal SSH servers - **API Services**: Secure API endpoint exposure ### Scaling Options - **Load Balancing**: Multiple instances behind single domain - **Geographic Distribution**: Multiple proxy servers in different regions - **Protocol Multiplexing**: Multiple services through single tunnel ## Security Considerations - Encrypted tunnels between internal and external networks - Access control through SSH keys and authentication - Firewall isolation of internal services - Automatic certificate management for HTTPS - Docker container isolation ## Maintenance Requirements - Regular backup of configuration files - Certificate renewal monitoring - Connection health monitoring - Log aggregation and analysis - Docker image updates ## Generic Application Examples ### Web Application Deployment - **Parameters**: Instance name, internal web port (80/443), domain name - **Outcome**: Public website accessible via configured domain ### Database Access - **Parameters**: Instance name, internal database port, restricted domain - **Outcome**: Secure external access to internal database ### Custom Service Exposure - **Parameters**: Instance name, custom application port, specific domain - **Outcome**: External access to internal custom service