1) latest cmd running, it will update the latest domain info. to owerwrite the old one, 2) Check if traefik or *-frpc container is running to know which mode even no .env, 3) Automatically processes multiple .env-<domain> files in a single run
This commit is contained in:
parent
ced4f6d900
commit
6d7f9a06f6
72
.env.sample
72
.env.sample
@ -1,72 +0,0 @@
|
||||
# Sample Environment Configuration for Reverse Proxy Architecture
|
||||
# Copy this file to .env, .env.development or .env.production and fill in your values
|
||||
|
||||
# Common
|
||||
# =========================================
|
||||
|
||||
# === Instance Configuration ===
|
||||
INSTANCE_NAME=myapp-3000 # Unique identifier for the service instance (alphanumeric, hyphens, underscores only)
|
||||
# The container and volume name will be {INSTANCE_NAME}-frpc
|
||||
|
||||
# Target server information for proxy connection
|
||||
TARGET_SERVER=WW.XX.YY.ZZ # Target Proxy Server IP/hostname
|
||||
TARGET_USER=your_user_name # Username for SSH access to target server
|
||||
SSH_PORT=22 # SSH port for target server (default 22)
|
||||
|
||||
# SSH key file name (must be in $HOME/.ssh/)
|
||||
SSH_KEY_FILE_NAME=your_key # SSH private key file name in $HOME/.ssh/
|
||||
|
||||
# === Domain Configuration ===
|
||||
DOMAIN_NAME=myapp.example.com # Public domain for Traefik routing
|
||||
|
||||
# Debug flag
|
||||
DEBUG=false # Set to true for additional debug output
|
||||
|
||||
# FRP
|
||||
# =========================================
|
||||
|
||||
# === FRP vs Traefik Mode Configuration ===
|
||||
FRP=true # Set to 'true' to use FRP mode, 'false' to use Traefik-only mode
|
||||
|
||||
# === Internal Service Container Configuration (FRP Mode) ===
|
||||
INTERNAL_SERVICE_PORT=3000 # Port exposed by the target Docker container (e.g., 3000)
|
||||
DOCKER_NETWORK=app-network # Docker network for connecting to internal service container
|
||||
|
||||
# === FRP Server Configuration (FRP Mode) ===
|
||||
FRP_SERVER_ADDR=192.168.1.100 # Public IP address of the FRP server
|
||||
FRP_SERVER_USER=myuser # Username for FRP server (defaults to 'teenfuture')
|
||||
FRP_SERVER_PORT=16999 # Port for FRP communication (default 16999)
|
||||
|
||||
# === Service Configuration ===
|
||||
SERVICE_DOCKER_CONTAINER_NAME=your-app-docker-container # Docker container name for internal service connection
|
||||
|
||||
# === FRP Remote Ports Configuration (FRP Mode) ===
|
||||
PROXY_WEB_PORT=11077 # Remote port for web proxy
|
||||
PROXY_RAD_PORT=8779 # Remote port for rad proxy (default 8779, use 8776 if following standard)
|
||||
PROXY_SSH_PORT=13076 # Remote port for SSH proxy (default 13076)
|
||||
|
||||
# Dynamic Proxy Configuration - Use PROXY_*_PORT format for additional proxies
|
||||
# Examples:
|
||||
# PROXY_API_PORT=8080 # Creates an 'api' proxy to port 8080
|
||||
# PROXY_API_LOCAL_PORT=8000 # Optional local port for the API proxy (defaults to service port)
|
||||
# PROXY_DATABASE_PORT=5432 # Creates a 'database' proxy to port 5432
|
||||
# PROXY_DATABASE_LOCAL_PORT=5433 # Optional local port for database proxy
|
||||
# PROXY_CUSTOM_PORT=9000 # Creates a 'custom' proxy to port 9000
|
||||
|
||||
# Traefik
|
||||
# =========================================
|
||||
|
||||
# === Target Proxy Server Configuration (Traefik Mode) ===
|
||||
# This section is used when FRP=false
|
||||
|
||||
# Destination path for host or docker volume folder deployment
|
||||
DEST_PATH=/ # Destination path on target server
|
||||
|
||||
# Target Application Service information (on the target server)
|
||||
TARGET_SERVICE_NAME=your-app-service # Name of the Docker container running the application service
|
||||
TARGET_SERVICE_PORT=3000 # Port the application service is listening on
|
||||
|
||||
# Traefik configuration
|
||||
TRAEFIK_VER=v3.5.4 # Traefik Docker image version to use
|
||||
LETSENCRYPT_EMAIL=admin@yourdomain.com # Email for Let's Encrypt certificate registration
|
||||
RESTART_TRAEFIK=false # Set to 'true' to restart Traefik after configuration (default: false for dynamic loading)
|
||||
@ -74,10 +74,47 @@ Each domain gets its own `.env-<domain>` file.
|
||||
2. Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
|
||||
**For New Domain Setup:**
|
||||
1. Create `.env-<domain>` file with domain configuration
|
||||
2. Ensure `.env` exists and reverse proxy is running
|
||||
3. Ensure your application service is running
|
||||
4. Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
|
||||
The script supports flexible domain setup with automatic proxy mode detection:
|
||||
|
||||
1. **With `.env-<domain>` file (recommended):**
|
||||
- Create `.env-<domain>` file with domain configuration
|
||||
- Ensure reverse proxy is running (Traefik or FRP)
|
||||
- Ensure your application service is running
|
||||
- Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
|
||||
2. **Without `.env` file (auto-detection):**
|
||||
- Create `.env-<domain>` file with domain configuration
|
||||
- Ensure reverse proxy is running (script will auto-detect mode)
|
||||
- Ensure your application service is running
|
||||
- Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
- Script automatically detects running proxy (Traefik or FRP) and configures accordingly
|
||||
|
||||
3. **Without any config files (interactive wizard):**
|
||||
- Ensure reverse proxy is running
|
||||
- Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
- Script detects running proxy and starts wizard for domain settings
|
||||
|
||||
4. **Batch processing (multiple domains):**
|
||||
- Create multiple `.env-<domain>` files in the same directory
|
||||
- Ensure reverse proxy is running
|
||||
- Ensure all application services are running
|
||||
- Run: `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash`
|
||||
- Script automatically processes all `.env-<domain>` files in batch mode
|
||||
- Example output:
|
||||
```
|
||||
[INFO] Found 3 domain config files, will process all in batch mode
|
||||
[INFO] =========================================
|
||||
[INFO] Processing domain 1 of 3: .env-domain1-com
|
||||
[INFO] =========================================
|
||||
[INFO] Setting up new domain: domain1.com
|
||||
...
|
||||
[INFO] =========================================
|
||||
[INFO] Processing domain 2 of 3: .env-domain2-com
|
||||
[INFO] =========================================
|
||||
...
|
||||
[INFO] Batch processing completed: 3 domain(s) processed
|
||||
```
|
||||
|
||||
## Run this System
|
||||
|
||||
@ -104,26 +141,21 @@ curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
|
||||
If you run the script for a domain that has already been added to the reverse proxy:
|
||||
|
||||
1. **Detection**: The script checks if a configuration file already exists for the domain and service combination
|
||||
2. **Warning**: Displays a warning message:
|
||||
```
|
||||
[WARN] Configuration file app-service-domain-service.yml already exists, it will be overwritten
|
||||
[INFO] This will update the existing domain configuration for my.domain.com
|
||||
```
|
||||
- Configuration File Naming:
|
||||
- Format: app-service-{domain}-{service}.yml
|
||||
- Example: app-service-my-domain-com-myapp.yml
|
||||
- Unique per domain+service combination
|
||||
3. **Update**: The existing configuration is overwritten with the new settings
|
||||
1. **Detection**: The script detects the running proxy mode (Traefik or FRP) automatically
|
||||
2. **Warning**: Displays a warning message that configuration will be overwritten
|
||||
3. **Update**: The existing configuration is updated with the new settings
|
||||
4. **Result**: The domain configuration is updated (not duplicated)
|
||||
|
||||
**Key Points:**
|
||||
- **Safe to re-run**: Running the script multiple times for the same domain is safe
|
||||
- **Configuration is updated, not duplicated**: Each domain+service combination has a unique configuration file
|
||||
- **No service interruption**: Traefik dynamically loads the updated configuration (no restart needed by default)
|
||||
- **No .env required**: Script auto-detects running proxy mode (Traefik or FRP)
|
||||
- **Configuration is updated, not duplicated**: Each domain+service combination has a unique configuration
|
||||
- **No service interruption**:
|
||||
- Traefik: Dynamically loads updated configuration (no restart needed by default)
|
||||
- FRP: Restarts FRP client container to apply new configuration
|
||||
- **Use case**: Useful for updating application port changes or domain routing modifications
|
||||
|
||||
**Example Scenario:**
|
||||
**Example Scenario (Traefik Mode):**
|
||||
```bash
|
||||
# First run - adds my.domain.com
|
||||
curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
@ -131,24 +163,52 @@ curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
|
||||
# Second run - updates my.domain.com (e.g., after port change)
|
||||
curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
# [WARN] Configuration file ... already exists, it will be overwritten
|
||||
# [INFO] This will update the existing domain configuration for my.domain.com
|
||||
# [INFO] Detected running Traefik reverse proxy
|
||||
# [INFO] Setting up new domain: my.domain.com
|
||||
# [INFO] New domain my.domain.com has been configured in Traefik
|
||||
```
|
||||
|
||||
**Example Scenario (FRP Mode):**
|
||||
```bash
|
||||
# First run - adds my.domain.com
|
||||
curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
# [INFO] Creating new configuration for domain my.domain.com
|
||||
|
||||
# Second run - updates my.domain.com (e.g., after port change)
|
||||
curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
# [INFO] Detected running FRP client container: my-instance-frpc
|
||||
# [INFO] Setting up new domain: my.domain.com
|
||||
# [INFO] Generated remote port 12001 for domain my.domain.com
|
||||
# [INFO] New domain my.domain.com has been configured in FRP tunnel
|
||||
```
|
||||
|
||||
### Script Behavior
|
||||
|
||||
### Mode Selection
|
||||
|
||||
Set the `FRP` environment variable to control the deployment mode:
|
||||
The script automatically detects the proxy mode from running containers:
|
||||
|
||||
```bash
|
||||
# Traefik Mode (local reverse proxy on same server)
|
||||
FRP=false ./deploy-traefik.sh setup-rvs-prxy
|
||||
|
||||
# FRP Mode (remote proxy via FRP tunnel)
|
||||
FRP=true ./deploy-traefik.sh setup-rvs-prxy
|
||||
# Auto-detects running proxy (Traefik or FRP)
|
||||
curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
```
|
||||
|
||||
**Manual override (optional):** Set the `FRP` environment variable to force a specific mode:
|
||||
|
||||
```bash
|
||||
# Force Traefik Mode (local reverse proxy on same server)
|
||||
FRP=false ./deploy-rvs-prxy.sh
|
||||
|
||||
# Force FRP Mode (remote proxy via FRP tunnel)
|
||||
FRP=true ./deploy-rvs-prxy.sh
|
||||
```
|
||||
|
||||
**Auto-detection behavior:**
|
||||
- If `traefik` container is running → Traefik mode (`FRP=false`)
|
||||
- If `*-frpc` container is running → FRP mode (`FRP=true`)
|
||||
- If both are running → Traefik mode takes precedence
|
||||
- If neither is running → Interactive wizard
|
||||
|
||||
### Traefik Mode Operations (FRP=false)
|
||||
|
||||
#### Setup
|
||||
@ -192,6 +252,36 @@ FRP=true ./deploy-traefik.sh setup-rvs-prxy
|
||||
6. Update proxy server configuration
|
||||
7. Display container operation commands
|
||||
|
||||
#### Setup New Domain (FRP Mode)
|
||||
When the FRP reverse proxy is already running, you can add new domains:
|
||||
|
||||
- **Prerequisites:**
|
||||
- FRP client container must be running (`${INSTANCE_NAME}-frpc`)
|
||||
- Application service must be running locally
|
||||
- `.env` file with reverse proxy configuration must exist
|
||||
- `.env-<domain>` file with domain configuration (or use interactive wizard)
|
||||
|
||||
- **Process:**
|
||||
1. Run the script: `curl -s "<url>/deploy-rvs-prxy.sh" | bash`
|
||||
2. Script detects existing FRP proxy and domain config
|
||||
3. Validates FRP client container is running
|
||||
4. Validates application service is running
|
||||
5. Generates a new remote port for the domain
|
||||
6. Updates frpc.toml with new proxy configuration
|
||||
7. Restarts FRP client container to apply changes
|
||||
8. Updates proxy server configuration with domain routing
|
||||
9. Domain is now accessible via HTTPS
|
||||
|
||||
- **Configuration Files:**
|
||||
- `.env` - Reverse proxy instance configuration (contains `INSTANCE_NAME`, `FRP_SERVER_ADDR`, etc.)
|
||||
- `.env-<domain>` - Domain-specific configuration (contains `DOMAIN_NAME`, `LOCAL_SERVICE_NAME`, `LOCAL_SERVICE_PORT`)
|
||||
|
||||
- **What Happens:**
|
||||
- A new TCP proxy is added to frpc.toml for the domain's service
|
||||
- A unique remote port is allocated for this domain
|
||||
- Proxy server (FRPS) is updated to route the domain to the new tunnel port
|
||||
- FRP client container is restarted to apply the new configuration
|
||||
|
||||
### Environment Variable Priority
|
||||
|
||||
Configuration files are loaded in the following priority order:
|
||||
|
||||
@ -15,9 +15,11 @@
|
||||
- **Automatic Mode Detection**: Automatically detects whether to setup reverse proxy or add new domain
|
||||
- **Two Deployment Modes**:
|
||||
- **Setup Reverse Proxy**: Deploys Traefik or FRP Tunnel with Traefik
|
||||
- **Setup New Domain**: Adds new domain to existing reverse proxy
|
||||
- **Setup New Domain**: Adds new domain to existing reverse proxy (supports both Traefik and FRP modes)
|
||||
- **Batch Processing**: Automatically processes multiple `.env-<domain>` files in a single run
|
||||
- **Traefik Mode**: Deploy and configure Traefik reverse proxy on the same server as your application
|
||||
- **FRP Mode**: Optional Fast Reverse Proxy support for tunneling connections to a remote proxy server
|
||||
- **FRP Domain Setup**: Add new domains to existing FRP tunnel by allocating new remote ports and updating proxy server configuration
|
||||
- **Automated Configuration**: Dynamic generation of reverse proxy configurations based on `.env` files
|
||||
- **Docker Integration**: Seamless integration with Docker containers and networks
|
||||
- **HTTPS/TLS Support**: Automatic SSL certificate management via Let's Encrypt
|
||||
@ -32,12 +34,19 @@
|
||||
- **No application service check** (application not needed at this stage)
|
||||
- No domain configuration at this stage
|
||||
|
||||
2. **Add domain (`.env` exists, proxy running)**: Setup New Domain
|
||||
- Interactive wizard asks for domain configuration
|
||||
2. **Add domain (proxy running)**: Setup New Domain
|
||||
- Script auto-detects running proxy mode (Traefik or FRP)
|
||||
- Interactive wizard asks for domain configuration (if no `.env-<domain>` exists)
|
||||
- Creates `.env-<domain>` with application settings
|
||||
- **Checks if application service is running**
|
||||
- Configures domain in existing reverse proxy
|
||||
|
||||
**Proxy Mode Detection:**
|
||||
- Script automatically detects running proxy from Docker containers
|
||||
- Traefik mode: detects `traefik` container
|
||||
- FRP mode: detects `*-frpc` containers
|
||||
- Works with or without `.env` file
|
||||
|
||||
```
|
||||
┌────────────┬─────────────────────────────────────┬────────────────────────────────────────────────────────┬────────────────┐
|
||||
│ Scenario │ Configuration │ Wizard Asks For │ Creates │
|
||||
@ -68,6 +77,7 @@
|
||||
│ .env-<domain> exists │ Setup New Domain │ Add domain to existing proxy │
|
||||
│ No .env-<domain> + Proxy running │ Setup New Domain │ Interactive wizard → Create │
|
||||
│ │ │ Check app service → Configure │
|
||||
│ No .env + Proxy running │ Setup New Domain │ Auto-detect mode → Wizard/Config│
|
||||
└────────────────────────────────────────┴─────────────────────┴─────────────────────────────────┘
|
||||
```
|
||||
|
||||
@ -79,6 +89,7 @@
|
||||
- Contains reverse proxy instance settings (FRP mode, Traefik version, etc.)
|
||||
- Created during first-time setup
|
||||
- One file per reverse proxy instance
|
||||
- **Note:** This file is optional for domain setup if proxy is already running (mode auto-detected)
|
||||
|
||||
**Domain-Specific Configuration (`.env-<domain>`):**
|
||||
- Pattern: `.env-<domain-with-dashes>` (e.g., `.env-example-com`, `.env-sub-domain-net`, `.env-app-org-hk`)
|
||||
@ -86,9 +97,24 @@
|
||||
- One file per domain
|
||||
- Multiple domain files can coexist
|
||||
- Accepts any domain format: `.com`, `.net`, `.org`, `.org.hk`, `.com.hk`, subdomains, etc.
|
||||
- **Simplified format:** Only requires 3 variables (see below)
|
||||
|
||||
#### Key Environment Variables
|
||||
|
||||
**Domain-Specific Configuration (`.env-<domain>`):**
|
||||
|
||||
**Required Variables (only 3):**
|
||||
- `DOMAIN_NAME` - Domain name for reverse proxy routing (e.g., `app.example.com`)
|
||||
- `LOCAL_SERVICE_NAME` - Name of the local Docker application container
|
||||
- `LOCAL_SERVICE_PORT` - Port number of the local application service
|
||||
|
||||
**Example `.env-app-example-com`:**
|
||||
```bash
|
||||
DOMAIN_NAME="app.example.com"
|
||||
LOCAL_SERVICE_NAME="my-app-container"
|
||||
LOCAL_SERVICE_PORT="3000"
|
||||
```
|
||||
|
||||
**Reverse Proxy Instance Configuration (`.env`):**
|
||||
|
||||
**Mode Selection:**
|
||||
|
||||
@ -265,6 +265,190 @@ The `deploy` command syncs files from local folder to target server:
|
||||
|
||||
## Workflow
|
||||
|
||||
- i have multiple of `.env-domain` as one folder, like below: ls -al /tmp/domain
|
||||
```
|
||||
total 16
|
||||
drwxrwxr-x 2 teenfuture teenfuture 4096 Mar 7 02:12 .
|
||||
drwxrwxrwt 15 root root 4096 Mar 7 02:11 ..
|
||||
-rw-rw-r-- 1 teenfuture teenfuture 206 Mar 7 02:12 .env-event-cgu-org-hk
|
||||
-rw-rw-r-- 1 teenfuture teenfuture 209 Mar 5 07:12 .env-www2-ivantito-com
|
||||
```
|
||||
- i ran cmd: teenfuture@ssdnodes-69008e84ae541:/tmp/domain$ curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
```
|
||||
[INFO] Loading domain config from .env-event-cgu-org-hk
|
||||
[INFO] Detected running Traefik reverse proxy
|
||||
[INFO] Auto-detected FRP mode: false (from running container)
|
||||
[INFO] Deployment mode: Setup New Domain (found domain config: .env-event-cgu-org-hk)
|
||||
[INFO] Setting up new domain in existing reverse proxy...
|
||||
[INFO] Setting up new domain: event.cgu.org.hk
|
||||
[INFO] Domain configuration loaded from: .env-event-cgu-org-hk
|
||||
[INFO] Checking if Application Service is running locally...
|
||||
[INFO] Application Service is running locally
|
||||
[INFO] Configuring Traefik locally to connect to Application Service...
|
||||
[INFO] Creating new configuration for domain event.cgu.org.hk
|
||||
[INFO] Added configuration for service cgu-react-client on domain event.cgu.org.hk to Traefik (file: app-service-event.cgu.org.hk-cgu-react-client.yml)
|
||||
[INFO] Traefik dynamic configuration added (restart not performed, Traefik should auto-load the configuration)
|
||||
[INFO] If needed, you can manually restart Traefik with: docker restart traefik
|
||||
[INFO] Traefik configured to route traffic to Application Service
|
||||
[INFO] Service will be accessible at: https://event.cgu.org.hk
|
||||
[INFO] New domain event.cgu.org.hk has been configured in Traefik
|
||||
[INFO] Service will be accessible at: https://event.cgu.org.hk
|
||||
```
|
||||
- it handles one `.env-domain`, modify the code which can loop to handle all `.env-domain` setup.
|
||||
- Result
|
||||
Code Changes (deploy-rvs-prxy.sh)
|
||||
|
||||
1. Added global array for domain files:
|
||||
|
||||
1 declare -a DOMAIN_ENV_FILES=()
|
||||
|
||||
2. Modified `load_env()` function:
|
||||
- Collects all .env-<domain> files into DOMAIN_ENV_FILES array
|
||||
- Loads first file for backward compatibility
|
||||
- Reports number of domain files found for batch processing
|
||||
|
||||
3. Modified `main()` function:
|
||||
- Loops through all domain config files in DOMAIN_ENV_FILES array
|
||||
- Processes each domain sequentially with progress indicator
|
||||
- Validates each domain config before processing
|
||||
- Shows batch processing summary at the end
|
||||
|
||||
- Currently situation as: the reverse proxy -> traefik instance is running, and i setup the domain www2.ivantito.com and they both working with `.env` as:
|
||||
```
|
||||
cat .env-www2-ivantito-com
|
||||
# Domain configuration for www2.ivantito.com
|
||||
# Generated by deploy-rvs-prxy.sh on Thu Mar 5 07:12:35 UTC 2026
|
||||
|
||||
DOMAIN_NAME="www2.ivantito.com"
|
||||
LOCAL_SERVICE_NAME="itl-www2-nginx_cntr"
|
||||
LOCAL_SERVICE_PORT="80"
|
||||
```
|
||||
- However, i have a cmd: curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
- it showed:
|
||||
```
|
||||
[INFO] Loading domain config from .env-www2-ivantito-com
|
||||
[INFO] Deployment mode: Setup New Domain (found domain config: .env-www2-ivantito-com)
|
||||
[INFO] Setting up new domain in existing reverse proxy...
|
||||
[INFO] Setting up new domain: www2.ivantito.com
|
||||
[INFO] Domain configuration loaded from: .env-www2-ivantito-com
|
||||
[ERROR] Domain setup for FRP mode is not yet implemented
|
||||
```
|
||||
- Resolve this issue. I assume the latest cmd running, it will update the latest domain info. to owerwrite the old one, finally success to setup, should not like currently as coming out Err.
|
||||
- Result
|
||||
- deploy-rvs-prxy.sh - Implemented FRP Domain Setup
|
||||
|
||||
Modified `setup_new_domain()` function (around line 2194):
|
||||
- Added FRP mode domain setup logic that:
|
||||
- Validates INSTANCE_NAME is set from .env
|
||||
- Checks if FRP client container is running
|
||||
- Validates application service is running locally
|
||||
- Generates a new remote port for the domain
|
||||
- Updates frpc.toml with new proxy configuration
|
||||
- Updates proxy server configuration with domain routing
|
||||
|
||||
Added helper functions (around line 1086):
|
||||
- generate_remote_port() - Generates a unique remote port by checking existing ports
|
||||
- update_frpc_config_for_domain() - Updates frpc.toml with new domain proxy config and restarts FRP container
|
||||
|
||||
How It Works Now
|
||||
|
||||
When running curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash in FRP mode with a domain config:
|
||||
|
||||
1. Script loads .env (reverse proxy config) and .env-<domain> (domain config)
|
||||
2. Detects FRP mode and domain setup mode
|
||||
3. Validates FRP client container is running
|
||||
4. Validates application service is running
|
||||
5. Generates unique remote port (e.g., 12000, 12001, etc.)
|
||||
6. Adds new proxy entry to frpc.toml for the domain
|
||||
7. Restarts FRP client container
|
||||
8. Updates proxy server (FRPS) configuration with domain routing
|
||||
9. Domain becomes accessible via HTTPS
|
||||
- I read your previous result, you mentioned the FRP mode, however, currently, my reverse proxy is running traefik instance, not FRP. I am confused as my current case as same to following `Design_Doc/Operations.md` -> Section "Run this System" -> Section "Re-running for Existing Domain", it does not mentioned FRP mode or traefik mode. For my original design, i aim to have first time setting to design as traefik or frp mode, which should be indicated at `.env`. Then any setting of domain with or without `.env-<domain>`, does not force to have previous instance `.env` at there, but this script can detect the current running instance mode as FRP mode or traefik mode, then setup domain. For the case of "Re-running for Existing Domain", but reverse proxy FRP mode or traefik mode is running, can absent of `.env`, when go with or without `.env-<domain>`, update domain overwrite the old domain setting.
|
||||
- Result
|
||||
- Code Changes (deploy-rvs-prxy.sh)
|
||||
|
||||
1. Enhanced `load_env()` function - Added automatic proxy mode detection:
|
||||
- Detects running traefik container → sets FRP=false
|
||||
- Detects running *-frpc containers → sets FRP=true, extracts INSTANCE_NAME
|
||||
- Loads FRP configuration from volume if .env is missing
|
||||
- Determines deployment mode based on running containers, not just config files
|
||||
|
||||
2. Added `load_frp_config_from_volume()` function:
|
||||
- Extracts FRP_SERVER_ADDR and FRP_SERVER_PORT from frpc.toml in Docker volume
|
||||
- Allows FRP domain setup without .env file
|
||||
|
||||
3. Updated `setup_new_domain()` function - Enhanced FRP mode:
|
||||
- Detects INSTANCE_NAME from running FRP containers if not set
|
||||
- Generates unique remote port for new domain
|
||||
- Updates frpc.toml with new proxy configuration
|
||||
- Restarts FRP client container to apply changes
|
||||
- Updates proxy server configuration with domain routing
|
||||
- My current reverse proxy instance as: docker ps -a
|
||||
```
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
23082fb71d18 traefik:v3.6.9 "/entrypoint.sh --ap…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 127.0.0.1:8080->8080/tcp traefik
|
||||
```
|
||||
- the container name is traefik.
|
||||
- I ran the cmd with following outcome as: curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash
|
||||
```
|
||||
[INFO] Loading domain config from .env-www2-ivantito-com
|
||||
[INFO] Detected running Traefik reverse proxy
|
||||
[INFO] Deployment mode: Setup New Domain (found domain config: .env-www2-ivantito-com)
|
||||
[INFO] Setting up new domain in existing reverse proxy...
|
||||
[INFO] Setting up new domain: www2.ivantito.com
|
||||
[INFO] Domain configuration loaded from: .env-www2-ivantito-com
|
||||
[INFO] Setting up new domain in FRP mode...
|
||||
[ERROR] INSTANCE_NAME is not set and no FRP container detected.
|
||||
[ERROR] Please ensure your .env file contains the reverse proxy configuration.
|
||||
```
|
||||
- i find out it goes into the FRP again, since not detected as traefik mode. What is your algorithm to detect the FRP or traefik mode at a current reverse proxy instance? How to improve? and resolve the above issue.
|
||||
- Result
|
||||
1. Fixed FRP Mode Detection Algorithm (deploy-rvs-prxy.sh)
|
||||
|
||||
Problem: The script was using FRP value from config files instead of detecting from running containers.
|
||||
|
||||
Solution:
|
||||
- Running container detection now always takes precedence over .env settings
|
||||
- Traefik container takes precedence over FRP containers
|
||||
- When a proxy is detected running, FRP variable is always updated based on actual running containers
|
||||
|
||||
New Detection Logic:
|
||||
|
||||
1 1. Check if traefik container is running → FRP=false (Traefik mode)
|
||||
2 2. Check if *-frpc container is running (and no Traefik) → FRP=true (FRP mode)
|
||||
3 3. Always override FRP variable when proxy is detected running
|
||||
|
||||
2. Updated Configuration File Format
|
||||
|
||||
Domain config files (`.env-<domain>`) - Simplified format:
|
||||
|
||||
1 DOMAIN_NAME="event.cgu.org.hk"
|
||||
2 LOCAL_SERVICE_NAME="cgu-react-client"
|
||||
3 LOCAL_SERVICE_PORT="3000"
|
||||
|
||||
Reverse proxy instance config (`.env`) - Full format:
|
||||
- Contains FRP/Traefik instance settings
|
||||
- Used for initial proxy setup
|
||||
- Optional for domain setup (mode auto-detected from running containers)
|
||||
|
||||
3. Created New Files
|
||||
|
||||
- `.env.domain-sample` - Template for domain configuration files
|
||||
|
||||
4. Updated Documentation
|
||||
|
||||
- `Design_Doc/Spec.md` - Added simplified domain config format with example
|
||||
- `.env.sample` - Added note clarifying it's for proxy instance setup
|
||||
|
||||
How It Works Now
|
||||
|
||||
When you run with Traefik container running:
|
||||
|
||||
1 [INFO] Loading domain config from .env-event-cgu-org-hk
|
||||
2 [INFO] Detected running Traefik reverse proxy
|
||||
3 [INFO] Auto-detected FRP mode: false (from running container)
|
||||
4 [INFO] Setting up new domain in Traefik mode...
|
||||
|
||||
- in scenario of proxy running, no matter have or not have `.env-<domain>`, it will execute the "Add domain" task. However, one of domain, eg. my.domain.com, has already added into reverse proxy instance, this command `curl -s "https://www.ivantito.com/app-pub/demos/test/deploy-rvs-prxy.sh" | bash` is executed again, does it re-insert the same command into reverse proxy instance? Let me the current logic, and update into the `Design_Doc/Operation.md` if does not has this description before.
|
||||
- Result -- Design_Doc/Operations.md -> section: "Re-running for Existing Domain"
|
||||
|
||||
|
||||
@ -1,5 +1,62 @@
|
||||
- Before Starting Any Work, Please read the following documents carefully **before taking any actions** on this project: `Readme.md`, `Design_Doc/Spec.md`, `Design_Doc/Operation.md` and `Design_Doc/Tech_Desc.md` **Exception:** You may skip the "AI Prompt" section. These files provide essential background information and project understanding. Only after reviewing them should you proceed with the following tasks.
|
||||
# Before Starting Any Work
|
||||
- Please read the following documents carefully **before taking any actions** on this project: `README.md`, `Design_Doc/Spec.md`, `Design_Doc/Operations.md` and `Design_Doc/Tech_Desc.md`. You may skip the `Design_Doc/Tech_Desc.md` -> "AI Prompt" section and its sub-sections when reading. These files provide essential background information and project understanding. Only after reviewing them should you proceed with the following tasks.
|
||||
|
||||
- <any your prompt msg>
|
||||
# Your Current Tasks
|
||||
- Listing the specific tasks for this session.
|
||||
|
||||
- Upon completion of the code changes specified above, you MUST update all affected documentation to reflect the modifications. This includes, where applicable: `Readme.md`, `Design_Doc/Spec.md`, `Design_Doc/Operation.md` and `Design_Doc/Tech_Desc.md` except the "AI Prompt" section and its child sections, that means skip and untouch this "AI Prompt" section including all its child sections. Each file MUST be updated in accordance with its designated purpose and content guidelines. These guidelines are defined in the "Documentation Overview" section of `Readme.md`.
|
||||
# Quick Reminder: Update the Documents After You Change the Code
|
||||
|
||||
Whenever you finish making code changes, please take a few minutes to update the related documents.
|
||||
This keeps everything clear and up-to-date for everyone on the team.
|
||||
|
||||
## Which files might need an update?
|
||||
Only touch the files that your changes actually affect. The most common ones are:
|
||||
|
||||
- `README.md`
|
||||
- `Design_Doc/Spec.md`
|
||||
- `Design_Doc/Operations.md`
|
||||
- `Design_Doc/Tech_Desc.md`
|
||||
|
||||
## How should you update them?
|
||||
Just follow the style and purpose each file already has.
|
||||
(You can check the "Documentation Overview" part in `README.md` if you're not sure.)
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ CRITICAL RULE for `Design_Doc/Tech_Desc.md` - The "AI Prompt" Section
|
||||
|
||||
**The "AI Prompt" section at the end of `Design_Doc/Tech_Desc.md` must NEVER be modified, deleted, or rewritten by you.**
|
||||
|
||||
### What is the "AI Prompt" section?
|
||||
- It is the section that starts with `# AI Prompt` (level-1 heading)
|
||||
- It is always located at the **very end** of `Design_Doc/Tech_Desc.md`
|
||||
- It contains sub-sections like `## AI Prompt habit as a reminder`, `## Script Code`, `## Doc.`
|
||||
- It contains **task history and instructions from previous sessions** written by the user
|
||||
|
||||
### Why must you NOT touch it?
|
||||
- This section is **written and maintained by the user only**
|
||||
- It contains **accumulated task history** that the user wants to preserve
|
||||
- It is **not documentation** about the project - it is a **working log of tasks**
|
||||
- Other team members (including the user) will update this section manually when needed
|
||||
|
||||
### What you MUST do:
|
||||
✅ **Leave the "AI Prompt" section completely unchanged**
|
||||
✅ **Keep the exact content** that is currently there (do not revert, do not update, do not clean up)
|
||||
✅ **Only edit the technical documentation sections** that come BEFORE the "AI Prompt" section
|
||||
✅ **Ensure "AI Prompt" stays at the end** of the file (do not move it)
|
||||
|
||||
### What you MUST NOT do:
|
||||
❌ **Do NOT delete** the "AI Prompt" section
|
||||
❌ **Do NOT modify** any words, sentences, or formatting inside "AI Prompt"
|
||||
❌ **Do NOT revert** it to an older version
|
||||
❌ **Do NOT clean up** or reorganize its content
|
||||
❌ **Do NOT add** new task results to it (the user does this manually)
|
||||
❌ **Do NOT remove** task history from it
|
||||
|
||||
### Simple rule to remember:
|
||||
> **Everything before `# AI Prompt` = Your responsibility to update**
|
||||
> **Everything from `# AI Prompt` to the end = User's responsibility, DO NOT TOUCH**
|
||||
|
||||
---
|
||||
|
||||
Thank you so much for helping keep the documents accurate and the task history preserved — it makes a big difference to the whole team!
|
||||
|
||||
@ -40,6 +40,9 @@ DEPLOY_MODE=""
|
||||
# Domain configuration file pattern: .env-your-domain-com
|
||||
DOMAIN_ENV_FILE=""
|
||||
|
||||
# Array to store all domain configuration files for batch processing
|
||||
declare -a DOMAIN_ENV_FILES=()
|
||||
|
||||
# Function to load environment variables from .env files
|
||||
load_env() {
|
||||
local proxy_env_loaded=false
|
||||
@ -73,57 +76,86 @@ load_env() {
|
||||
proxy_env_loaded=true
|
||||
fi
|
||||
|
||||
# Step 2: Look for domain-specific configuration files (.env-* pattern)
|
||||
# Step 2: Collect all domain-specific configuration files (.env-* pattern)
|
||||
# These files contain domain-specific settings like DOMAIN_NAME, LOCAL_SERVICE_NAME, LOCAL_SERVICE_PORT
|
||||
# Pattern matches any domain format: .env-example-com, .env-sub-domain-org-hk, etc.
|
||||
# All found files will be processed in batch mode
|
||||
for env_file in .env-*; do
|
||||
# Skip .env.development and .env.production
|
||||
if [ "$env_file" = ".env.development" ] || [ "$env_file" = ".env.production" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -f "$env_file" ]; then
|
||||
echo -e "${BLUE}[INFO]${NC} Loading domain config from $env_file" >&2
|
||||
source "$env_file"
|
||||
domain_env_loaded=true
|
||||
DOMAIN_ENV_FILE="$env_file"
|
||||
break # Load only the first domain file found
|
||||
DOMAIN_ENV_FILES+=("$env_file")
|
||||
fi
|
||||
done
|
||||
|
||||
# Determine deployment mode based on what configuration files exist
|
||||
# Load the first domain file for initial variable setup (backward compatibility)
|
||||
if [ ${#DOMAIN_ENV_FILES[@]} -gt 0 ]; then
|
||||
echo -e "${BLUE}[INFO]${NC} Loading domain config from ${DOMAIN_ENV_FILES[0]}" >&2
|
||||
source "${DOMAIN_ENV_FILES[0]}"
|
||||
domain_env_loaded=true
|
||||
DOMAIN_ENV_FILE="${DOMAIN_ENV_FILES[0]}"
|
||||
|
||||
if [ ${#DOMAIN_ENV_FILES[@]} -gt 1 ]; then
|
||||
log_info "Found ${#DOMAIN_ENV_FILES[@]} domain config files, will process all in batch mode"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 3: Detect proxy mode from running containers
|
||||
# This allows domain setup even without .env file, by detecting running proxy
|
||||
# IMPORTANT: Running container detection takes precedence over .env settings
|
||||
local proxy_running=false
|
||||
local detected_frp_mode=""
|
||||
|
||||
# Check if Traefik is running (takes precedence)
|
||||
if docker ps --filter name=^traefik$ --format '{{.Names}}' | grep -q "^traefik$"; then
|
||||
proxy_running=true
|
||||
detected_frp_mode="false"
|
||||
log_info "Detected running Traefik reverse proxy"
|
||||
fi
|
||||
|
||||
# Check if FRP client is running (look for any *-frpc container)
|
||||
local frpc_containers=$(docker ps --filter name="-frpc$" --format '{{.Names}}' 2>/dev/null || true)
|
||||
if [ -n "$frpc_containers" ]; then
|
||||
# FRP container found, extract instance name from first container
|
||||
local first_frpc=$(echo "$frpc_containers" | head -1)
|
||||
INSTANCE_NAME="${first_frpc%-frpc}"
|
||||
proxy_running=true
|
||||
# Only set FRP mode if Traefik is not detected (Traefik takes precedence)
|
||||
if [ -z "$detected_frp_mode" ]; then
|
||||
detected_frp_mode="true"
|
||||
log_info "Detected running FRP client container: ${first_frpc} (instance: ${INSTANCE_NAME})"
|
||||
|
||||
# Load FRP configuration from volume if .env not loaded
|
||||
if [ "$proxy_env_loaded" = false ]; then
|
||||
load_frp_config_from_volume "$INSTANCE_NAME"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ALWAYS use detected FRP mode when proxy is running (override .env settings)
|
||||
# This ensures the script uses the actual running proxy mode, not stale config
|
||||
if [ "$proxy_running" = true ] && [ -n "$detected_frp_mode" ]; then
|
||||
FRP="$detected_frp_mode"
|
||||
log_info "Auto-detected FRP mode: $FRP (from running container)"
|
||||
fi
|
||||
|
||||
# Determine deployment mode based on what configuration files exist and running proxy
|
||||
if [ "$domain_env_loaded" = true ]; then
|
||||
# Domain config exists - setup new domain
|
||||
DEPLOY_MODE="domain"
|
||||
log_info "Deployment mode: Setup New Domain (found domain config: ${DOMAIN_ENV_FILE})"
|
||||
elif [ "$proxy_running" = true ]; then
|
||||
# Proxy is running (detected from containers) - setup new domain via wizard if no domain config
|
||||
DEPLOY_MODE="domain_wizard"
|
||||
log_info "Deployment mode: Setup New Domain (proxy running, no domain config)"
|
||||
elif [ "$proxy_env_loaded" = true ]; then
|
||||
# Only proxy config exists - check if proxy is already running
|
||||
local proxy_exists=false
|
||||
if [ "$FRP" = "false" ] || [ "$FRP" = "False" ] || [ "$FRP" = "FALSE" ]; then
|
||||
FRP=false
|
||||
if docker ps -a --filter name=^traefik$ --format '{{.Names}}' | grep -q "^traefik$"; then
|
||||
proxy_exists=true
|
||||
fi
|
||||
else
|
||||
FRP=true
|
||||
if [ -n "$INSTANCE_NAME" ]; then
|
||||
local frpc_container="${INSTANCE_NAME}-frpc"
|
||||
if docker ps -a --filter name=^${frpc_container}$ --format '{{.Names}}' | grep -q "^${frpc_container}$"; then
|
||||
proxy_exists=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$proxy_exists" = true ]; then
|
||||
# Proxy exists but no domain config - need domain setup via wizard
|
||||
DEPLOY_MODE="domain_wizard"
|
||||
log_info "Deployment mode: Setup New Domain (proxy running, no domain config)"
|
||||
else
|
||||
# Proxy config exists but proxy not running - setup proxy
|
||||
DEPLOY_MODE="proxy"
|
||||
log_info "Deployment mode: Setup Reverse Proxy (config exists, proxy not running)"
|
||||
fi
|
||||
# Proxy config exists but proxy not running - setup proxy
|
||||
DEPLOY_MODE="proxy"
|
||||
log_info "Deployment mode: Setup Reverse Proxy (config exists, proxy not running)"
|
||||
else
|
||||
# No configuration files found - run interactive wizard
|
||||
# No configuration files found and no proxy running - run interactive wizard
|
||||
echo -e "${YELLOW}[INFO]${NC} No configuration file found." >&2
|
||||
interactive_setup_wizard
|
||||
# Source the newly created files
|
||||
@ -1082,7 +1114,138 @@ extract_all_remote_ports() {
|
||||
echo "${ports[@]}"
|
||||
}
|
||||
|
||||
# Function to execute Docker commands locally (Traefik Mode - runs on same server)
|
||||
# Function to load FRP configuration from volume (when .env is missing)
|
||||
load_frp_config_from_volume() {
|
||||
local instance_name="$1"
|
||||
local volume_name="${instance_name}-frpc"
|
||||
local temp_container="temp-load-config-$(date +%s)"
|
||||
|
||||
log_info "Loading FRP configuration from volume: $volume_name"
|
||||
|
||||
# Create a temporary container to check for existing config
|
||||
if docker volume inspect "$volume_name" >/dev/null 2>&1; then
|
||||
if docker run --rm -d --name "$temp_container" -v "$volume_name:/etc/frp" alpine:latest sleep 10 >/dev/null 2>&1; then
|
||||
if docker exec "$temp_container" test -f /etc/frp/frpc.toml >/dev/null 2>&1; then
|
||||
# Extract server address and port from frpc.toml
|
||||
local server_addr=$(docker exec "$temp_container" grep "^serverAddr" /etc/frp/frpc.toml | cut -d'"' -f2 || true)
|
||||
local server_port=$(docker exec "$temp_container" grep "^serverPort" /etc/frp/frpc.toml | cut -d'=' -f2 | tr -d ' ' || true)
|
||||
|
||||
if [ -n "$server_addr" ]; then
|
||||
FRP_SERVER_ADDR="$server_addr"
|
||||
log_info "Loaded FRP_SERVER_ADDR from volume: $FRP_SERVER_ADDR"
|
||||
fi
|
||||
if [ -n "$server_port" ]; then
|
||||
FRP_SERVER_PORT="$server_port"
|
||||
log_info "Loaded FRP_SERVER_PORT from volume: $FRP_SERVER_PORT"
|
||||
fi
|
||||
fi
|
||||
docker stop "$temp_container" >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to generate a new remote port for domain setup (FRP Mode)
|
||||
generate_remote_port() {
|
||||
if [ "$FRP" = false ]; then
|
||||
log_info "Skipping remote port generation as FRP=false"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get existing remote ports to avoid conflicts
|
||||
local existing_ports
|
||||
existing_ports=$(extract_all_remote_ports)
|
||||
|
||||
# Start from a base port (e.g., 12000) and find an available port
|
||||
local base_port=12000
|
||||
local new_port=$base_port
|
||||
|
||||
# Check if any existing ports conflict
|
||||
while echo "$existing_ports" | grep -qw "$new_port"; do
|
||||
new_port=$((new_port + 1))
|
||||
done
|
||||
|
||||
echo "$new_port"
|
||||
}
|
||||
|
||||
# Function to update frpc.toml with new domain proxy configuration (FRP Mode)
|
||||
update_frpc_config_for_domain() {
|
||||
local new_remote_port="$1"
|
||||
|
||||
if [ "$FRP" = false ]; then
|
||||
log_info "Skipping frpc.toml update as FRP=false"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "Updating frpc.toml with new domain proxy configuration..."
|
||||
|
||||
local volume_name="${THIS_INSTANCE}-frpc"
|
||||
local temp_container="temp-update-config-$(date +%s)"
|
||||
local temp_dir="/tmp/frpc-update-${THIS_INSTANCE}"
|
||||
|
||||
# Create temporary directory
|
||||
mkdir -p "$temp_dir"
|
||||
|
||||
# Get existing configuration
|
||||
local existing_config=""
|
||||
if docker volume inspect "$volume_name" >/dev/null 2>&1; then
|
||||
if docker run --rm -d --name "$temp_container" -v "$volume_name:/etc/frp" alpine:latest sleep 10 >/dev/null 2>&1; then
|
||||
if docker exec "$temp_container" test -f /etc/frp/frpc.toml >/dev/null 2>&1; then
|
||||
existing_config=$(docker exec "$temp_container" cat /etc/frp/frpc.toml)
|
||||
fi
|
||||
docker stop "$temp_container" >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get server address and port from existing config or environment
|
||||
local server_addr="${FRP_SERVER_ADDR}"
|
||||
local server_port="${FRP_SERVER_PORT:-16999}"
|
||||
|
||||
if [ -z "$existing_config" ]; then
|
||||
# No existing config, create new one
|
||||
log_info "Creating new frpc.toml configuration"
|
||||
existing_config="serverAddr = \"${server_addr}\"\nserverPort = ${server_port}\n\n"
|
||||
fi
|
||||
|
||||
# Generate proxy name from domain
|
||||
local proxy_name
|
||||
proxy_name=$(echo "$DOMAIN_NAME" | sed 's/\./-/g' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
# Add new proxy configuration for this domain
|
||||
local new_proxy_config
|
||||
new_proxy_config="[[proxies]]\n"
|
||||
new_proxy_config+="name = \"${proxy_name}-${THIS_INSTANCE}\"\n"
|
||||
new_proxy_config+="type = \"tcp\"\n"
|
||||
new_proxy_config+="localPort = ${LOCAL_SERVICE_PORT}\n"
|
||||
if [ -n "$SERVICE_DOCKER_CONTAINER_NAME" ]; then
|
||||
new_proxy_config+="localIP = \"${SERVICE_DOCKER_CONTAINER_NAME}\"\n"
|
||||
else
|
||||
new_proxy_config+="localIP = \"${THIS_INSTANCE}-app\"\n"
|
||||
fi
|
||||
new_proxy_config+="remotePort = ${new_remote_port}\n\n"
|
||||
|
||||
# Append new proxy config to existing config
|
||||
local full_config="${existing_config}${new_proxy_config}"
|
||||
|
||||
# Write the config to a temporary file
|
||||
echo -e "$full_config" > "${temp_dir}/frpc.toml"
|
||||
|
||||
# Create the volume if it doesn't exist
|
||||
docker volume create "$volume_name" >/dev/null 2>&1 || true
|
||||
|
||||
# Copy the config file to the volume
|
||||
docker run --rm -v "$volume_name:/etc/frp" -v "${temp_dir}:/tmp/source:ro" alpine:latest cp /tmp/source/frpc.toml /etc/frp/frpc.toml
|
||||
|
||||
# Clean up
|
||||
rm -rf "$temp_dir"
|
||||
|
||||
# Restart the FRP client container to apply new configuration
|
||||
log_info "Restarting FRP client container to apply new configuration..."
|
||||
docker restart "${THIS_INSTANCE}-frpc" >/dev/null 2>&1
|
||||
|
||||
log_info "frpc.toml configuration updated successfully"
|
||||
}
|
||||
|
||||
# Function to execute Docker commands locally (Traefik Mode)
|
||||
local_docker_exec() {
|
||||
local command="$1"
|
||||
log_debug "Executing local Docker command: $command"
|
||||
@ -2091,8 +2254,62 @@ setup_new_domain() {
|
||||
log_info "New domain ${DOMAIN_NAME} has been configured in Traefik"
|
||||
log_info "Service will be accessible at: https://${DOMAIN_NAME}"
|
||||
else
|
||||
log_error "Domain setup for FRP mode is not yet implemented"
|
||||
exit 1
|
||||
# FRP Mode domain setup
|
||||
log_info "Setting up new domain in FRP mode..."
|
||||
|
||||
# Ensure INSTANCE_NAME is set (from .env or detected from running container)
|
||||
if [ -z "$INSTANCE_NAME" ]; then
|
||||
# Try to detect from running FRP containers
|
||||
local frpc_containers=$(docker ps --filter name="-frpc$" --format '{{.Names}}' 2>/dev/null || true)
|
||||
if [ -n "$frpc_containers" ]; then
|
||||
local first_frpc=$(echo "$frpc_containers" | head -1)
|
||||
INSTANCE_NAME="${first_frpc%-frpc}"
|
||||
log_info "Detected instance name from running container: ${INSTANCE_NAME}"
|
||||
else
|
||||
log_error "INSTANCE_NAME is not set and no FRP container detected."
|
||||
log_error "Please ensure your .env file contains the reverse proxy configuration."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
THIS_INSTANCE="$INSTANCE_NAME"
|
||||
log_info "Using instance name: ${THIS_INSTANCE}"
|
||||
|
||||
# Check if FRP client container is running
|
||||
local frpc_container="${THIS_INSTANCE}-frpc"
|
||||
if ! docker ps --filter name=^${frpc_container}$ --format '{{.Names}}' | grep -q "^${frpc_container}$"; then
|
||||
log_error "FRP client container '${frpc_container}' is not running!"
|
||||
log_error "Please ensure the reverse proxy is setup first"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if Application Service exists locally
|
||||
if ! check_app_service_local; then
|
||||
log_error "Application Service not found locally. Please ensure the service '$LOCAL_SERVICE_NAME' is running."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate a new remote port for this domain
|
||||
local new_remote_port
|
||||
new_remote_port=$(generate_remote_port)
|
||||
log_info "Generated remote port ${new_remote_port} for domain ${DOMAIN_NAME}"
|
||||
|
||||
# Update frpc.toml with the new proxy configuration
|
||||
update_frpc_config_for_domain "$new_remote_port"
|
||||
|
||||
# Update proxy server configuration
|
||||
local server_addr
|
||||
server_addr=$(extract_frp_server_address)
|
||||
|
||||
if [ -z "$server_addr" ]; then
|
||||
log_error "Failed to extract FRP server address from configuration"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Updating proxy server configuration at ${server_addr}..."
|
||||
update_proxy_server_config "$server_addr" "true" "$new_remote_port"
|
||||
|
||||
log_info "New domain ${DOMAIN_NAME} has been configured in FRP tunnel"
|
||||
log_info "Service will be accessible at: https://${DOMAIN_NAME}"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -2332,7 +2549,52 @@ main() {
|
||||
# Execute based on detected deployment mode
|
||||
if [ "$DEPLOY_MODE" = "domain" ]; then
|
||||
log_info "Setting up new domain in existing reverse proxy..."
|
||||
setup_new_domain
|
||||
|
||||
# Process all domain config files in batch mode
|
||||
if [ ${#DOMAIN_ENV_FILES[@]} -gt 0 ]; then
|
||||
local total=${#DOMAIN_ENV_FILES[@]}
|
||||
local count=0
|
||||
|
||||
for env_file in "${DOMAIN_ENV_FILES[@]}"; do
|
||||
count=$((count + 1))
|
||||
|
||||
# Skip .env.development and .env.production
|
||||
if [ "$env_file" = ".env.development" ] || [ "$env_file" = ".env.production" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "" >&2
|
||||
log_info "========================================="
|
||||
log_info "Processing domain $count of $total: $env_file"
|
||||
log_info "========================================="
|
||||
echo "" >&2
|
||||
|
||||
# Source the domain config file
|
||||
source "$env_file"
|
||||
DOMAIN_ENV_FILE="$env_file"
|
||||
|
||||
# Validate domain config
|
||||
if [ -z "$DOMAIN_NAME" ]; then
|
||||
log_error "DOMAIN_NAME is required in $env_file"
|
||||
continue
|
||||
fi
|
||||
if [ -z "$LOCAL_SERVICE_NAME" ] || [ -z "$LOCAL_SERVICE_PORT" ]; then
|
||||
log_error "LOCAL_SERVICE_NAME and LOCAL_SERVICE_PORT are required in $env_file"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Setup the domain
|
||||
setup_new_domain
|
||||
done
|
||||
|
||||
echo "" >&2
|
||||
log_info "========================================="
|
||||
log_info "Batch processing completed: $count domain(s) processed"
|
||||
log_info "========================================="
|
||||
else
|
||||
# Fallback for backward compatibility
|
||||
setup_new_domain
|
||||
fi
|
||||
elif [ "$DEPLOY_MODE" = "domain_wizard" ]; then
|
||||
log_info "Starting interactive wizard for domain setup..."
|
||||
interactive_setup_wizard
|
||||
|
||||
Loading…
Reference in New Issue
Block a user