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:
- Setup Reverse Proxy: Deploys new Traefik or FRP Tunnel with Traefik
- 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)
- Domain format: Any domain format supported (
.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-prxyexists, proxy not running → Setup Reverse Proxy.env.rvs-prxyexists, 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):
- Interactive wizard asks for proxy instance settings
- Creates .env.rvs-prxy with Traefik/FRP settings
- Validation checks proxy settings (TRAEFIK_VER, LETSENCRYPT_EMAIL)
- Deploys reverse proxy
- Shows message: "Next: Run the script again to setup your first domain or port"
Second Run (.env.rvs-prxy exists, proxy running):
- Detects running proxy
- Interactive wizard asks for domain or port settings
- Creates .env- or .env-port- with settings
- Validation checks domain/port settings
- Checks if application service/container is running
- Configures domain/port in existing reverse proxy
- Shows: "Service will be accessible at: https://domain.name or http://host-ip:port"
Three Deployment Modes:
- Setup Reverse Proxy - Deploys Traefik or FRP Tunnel
- Setup New Domain - Adds domain-based routing
- 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-prxyfile 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_NAMEenvironment variable - Generates timestamped default names
- Saves selections to
.envfor future runs
3. Docker Network Selection (select_docker_network)
- Lists available Docker networks
- Supports custom network names
- Remembers previous selections via
.parafile in volume (FRP mode)
4. Configuration Generation
- FRP Mode: Generates
frpc.tomlwith 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)
-
Pre-request Checks
- Verify Docker command permissions
-
Application Service Verification (
check_app_service_local)- Confirms target service is running locally
- Verifies connection to
traefik-publicnetwork
-
Traefik Container Creation (
create_traefik_container_local)- Creates
traefik_datavolume for persistence - Generates dynamic configuration with:
- Dashboard routing
- HTTP to HTTPS redirect
- Security headers
- Creates
traefik-publicDocker network - Uses Docker Compose for container orchestration
- Detects Docker version for command compatibility (
docker composevsdocker-compose)
- Creates
-
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 serverlocal_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/udpenables HTTP/3 QUIC on UDP port 443 - These are injected into both the docker-compose.yml
command:section and thedocker runcommand - 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>argsEXTRA_PORT_MAPPINGS: array of port mappings inhost:container/protocolformatEXTRA_COMPOSE_ENTRYPOINTS: YAML lines for docker-compose.yml command sectionEXTRA_COMPOSE_PORTS: YAML lines for docker-compose.yml ports section
FRP Mode Implementation
Setup Flow
- Instance Setup: Prompt for instance name
- Port Configuration: Prompt for internal service port
- FRP Config Generation (
generate_frpc_config)- Extracts existing configuration from volume
- Supports dynamic proxy configurations via
PROXY_*_PORTvariables - Generates
frpc.tomlwith TCP proxy rules
- Container Start (
start_docker_container)- Creates volume if not exists
- Starts frpc container with configuration mounted
- Proxy Server Update (
update_proxy_server_config)- Uploads dynamic configuration script to proxy server
- Updates
docker-compose.app.ymlwith 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 proxyPROXY_<NAME>_LOCAL_PORT: Defines local port (defaults toINTERNAL_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_PATHon target server - Uses rsync for efficient synchronization with
--deleteoption
Logging and Debugging
Logging Functions:
log_info(): Green [INFO] messageslog_error(): Red [ERROR] messageslog_warn(): Yellow [WARN] messageslog_debug(): Blue [DEBUG] messages (only whenDEBUG=true)
Status Commands:
check_status_on_target(): Shows Traefik and Application service statusview_traefik_logs(): Displays last 50 lines of Traefik logs
Error Handling
- Uses
set -efor 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 composefor Docker 20.10.0+ - Falls back to
docker-composefor older versions - Handles Compose file version field (deprecated in v2.0+)
Traefik Version:
- Default:
v3.6.9 - Configurable via
TRAEFIK_VERenvironment variable