You can use FRP! FRP is suitable for scenarios with a public IP (local/router or online server). Compared to Cloudflare Tunnel, it’s more flexible and controllable, and does not require reliance on third-party domain hosting. Here are the precise, implementable FRP solution details, compatible with your tech stack (Docker + local service + online website), focusing on configuration standardization, security, and stability:
https://gofrp.org/zh-cn/docs/setup/
1. Core Logic of the FRP Solution
- Role Division:
- “Server side (frps)”: Deployed on an online server (with public IP, such as your website’s server), responsible for receiving public requests and forwarding them;
- “Client side (frpc)”: Deployed on a local idle computer (running Umami in Docker environment), responsible for forwarding the local Umami service (
localhost:3000) to the server side; - “Reverse Proxy”: The online server uses Nginx/Caddy to configure HTTPS, redirecting domain requests to the FRP server’s mapped port, avoiding direct exposure of ports.
- Data Flow: Online website → Public domain (HTTPS) → Online server Nginx → FRP server → FRP client → Local Umami service.
2. Prerequisites
- Online Server:
- Has a public IP, open 3 ports (FRP communication port: e.g., 7000; Umami mapped port: e.g., 8080; optional FRP panel port: e.g., 7500);
- Installed Nginx/Caddy (for HTTPS reverse proxy);
- Has applied a domain name (e.g.,
umami.your-domain.com), and has resolved the domain to the server’s public IP.
- Local Computer:
- Already deployed Umami via Docker Compose (refer to the previous Docker configuration, ensuring
localhost:3000is accessible); - Installed FRP client (consistent version with the server).
- Already deployed Umami via Docker Compose (refer to the previous Docker configuration, ensuring
- Network Permissions:
- Local computer can access the internet (can connect to the online server’s FRP communication port);
- Router allows local computer to access externally (no additional port mapping required, as FRP uses active connection mode).
3. Detailed Implementation Steps (Server-side/Client-side/Reverse Proxy)
Step 1: Deploy FRP Server (frps) on Online Server
1.1 Download FRP
Choose the latest stable version (recommended v0.50+, to avoid compatibility issues), download the corresponding server architecture (e.g., Linux x86_64):
# Execute on online server (Linux x86_64 example)
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar -zxvf frp_0.52.3_linux_amd64.tar.gz
mv frp_0.52.3_linux_amd64 /usr/local/frp
cd /usr/local/frp
1.2 Configure FRP Server (frps.ini)
Create/modify frps.ini, core configuration for authentication, ports, and logs to ensure security and monitorability:
[common]
# 1. Basic communication configuration
bind_port = 7000 # FRP client-server communication port (must open server firewall)
token = your_strong_frp_token # Authentication token (must be set, prevent unauthorized connections, recommend ≥16 random characters)
# 2. Optional: FRP management panel (for viewing connection status)
dashboard_port = 7500 # Panel access port
dashboard_user = frp_admin # Panel login username
dashboard_pwd = your_dashboard_password # Panel login password (strong password)
# 3. Log configuration (for troubleshooting)
log_file = /var/log/frps.log
log_level = info # Log level: info/warn/error
log_max_days = 7 # Log retention for 7 days
# 4. Connection optimization (reduce disconnection)
tcp_keepalive = 60 # Send heartbeat packets every 60s
max_pool_count = 5 # Maximum connection pool size
1.3 Configure FRP Server to Start Automatically (System Service)
Create a system service file to ensure frps runs automatically after server restart:
sudo tee /etc/systemd/system/frps.service <<EOF
[Unit]
Description=FRP Server (frps)
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/usr/local/frp
ExecStart=/usr/local/frp/frps -c /usr/local/frp/frps.ini
Restart=always # Automatic restart on failure
RestartSec=5 # Restart interval of 5s
[Install]
WantedBy=multi-user.target
EOF
# Enable and start the service
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
# Verify status (ensure no errors)
sudo systemctl status frps
1.4 Open Server Ports (Firewall)
Example for Ubuntu (ufw), open FRP communication port, mapped port, and panel port:
# Open FRP communication port (7000), Umami mapped port (8080), and panel port (7500)
sudo ufw allow 7000/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 7500/tcp
sudo ufw reload
# Verify port openness
sudo ufw status
Step 2: Deploy FRP Client (frpc) on Local Computer
2.1 Download FRP (Consistent with Server Version)
Download the corresponding version based on local computer system (Linux/macOS/Windows):
# Example: Download for Linux/macOS (x86_64)
wget https://github.com/fatedier/frp/releases/download/v0.52.3/frp_0.52.3_linux_amd64.tar.gz
tar -zxvf frp_0.52.3_linux_amd64.tar.gz
mv frp_0.52.3_linux_amd64 ~/frp # Move to user directory
cd ~/frp
2.2 Configure FRP Client (frpc.ini)
Core configuration: connect to server, forward local Umami service, add identity authentication and connection optimization:
[common]
# 1. Server information (must match frps configuration)
server_addr = Your online server public IP # e.g., 123.45.67.89
server_port = 7000 # Same as frps's bind_port
token = your_strong_frp_token # Must be exactly the same as frps's token (case-sensitive)
# 2. Log configuration
log_file = ~/frp/frpc.log
log_level = info
log_max_days = 7
# 3. Connection optimization (prevent disconnection)
tcp_keepalive = 60
pool_count = 3
connect_timeout = 30 # Connection timeout of 30s
# 4. Umami service forwarding rules (core)
[umami-tcp] # Rule name (custom, unique)
type = tcp # Protocol type (Umami is HTTP service, use tcp for stability)
local_ip = 127.0.0.1 # Local Umami service IP (Docker mapped to local, so it's 127.0.0.1)
local_port = 3000 # Local Umami service port (same as Docker Compose mapped port)
remote_port = 8080 # Online server exposed port (same as server firewall opened 8080)
use_compression = true # Enable data compression (reduce bandwidth usage)
use_encryption = true # Enable data encryption (prevent eavesdropping)
2.3 Configure FRP Client to Start Automatically (Depending on System)
Ensure frpc starts automatically after local computer restart:
(1) Linux/macOS (System Service)
# Create system service file (Linux)
sudo tee /etc/systemd/system/frpc.service <<EOF
[Unit]
Description=FRP Client (frpc)
After=network.target docker.service # Wait for network and Docker to start before starting
Requires=docker.service
[Service]
Type=simple
User=jin # Replace with your local username (e.g., jin)
WorkingDirectory=/home/jin/frp # Replace with frpc directory
ExecStart=/home/jin/frp/frpc -c /home/jin/frp/frpc.ini
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
sudo systemctl daemon-reload
sudo systemctl enable frpc
sudo systemctl start frpc
# Verify status
sudo systemctl status frpc
(2) Windows (Task Scheduler)
- Create a batch file
start_frpc.bat, content:@echo off cd /d "C:\Users\jin\frp" # Replace with frpc directory frpc.exe -c frpc.ini - Open “Task Scheduler” → “Create Basic Task”:
- Name:
FRP Client, trigger set to “At startup”, action select “Start a program”, choose the above batch file; - Check “Run whether the user is logged on or not” and “Run with highest privileges”, then test start.
- Name:
Step 3: Configure Reverse Proxy (HTTPS) on Online Server
After FRP forwarding, the online server’s port 8080 is HTTP protocol, needs to configure Nginx/Caddy for HTTPS (to avoid browser interception of Umami tracking scripts).
3.1 Apply Free HTTPS Certificate (Let’s Encrypt)
Quickly apply certificate with Certbot (example for Nginx):
# Install Certbot
sudo apt update && sudo apt install certbot python3-certbot-nginx -y
# Apply certificate (replace with your domain)
sudo certbot --nginx -d umami.your-domain.com
The certificate will be automatically saved to /etc/letsencrypt/live/umami.your-domain.com/.
3.2 Nginx Configuration (Recommended)
Create Nginx configuration file umami.conf:
server {
listen 80;
server_name umami.your-domain.com;
# Force redirect to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name umami.your-domain.com;
# HTTPS certificate configuration
ssl_certificate /etc/letsencrypt/live/umami.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/umami.your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # Only support secure protocols
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# Reverse proxy to FRP mapped port (8080)
location / {
proxy_pass http://127.0.0.1:8080; # Point to local FRP server's remote_port
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # Pass HTTPS protocol identifier
proxy_connect_timeout 60s; # Connection timeout optimization
proxy_read_timeout 60s;
}
# Security headers (prevent XSS, CSRF etc.)
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
}
3.3 Start Nginx and Verify
# Check configuration file syntax
sudo nginx -t
# Restart Nginx
sudo systemctl restart nginx
# Verify HTTPS access
curl -I https://umami.your-domain.com
Return 200 OK and Server: nginx indicates successful configuration, browser access to the domain should open Umami login page.
Step 4: Integrate Umami Tracking Code into Online Website
Same as previous solution, log in to Umami backend (https://umami.your-domain.com), copy tracking code, modify script path and add to online website’s <head> or <body> tag:
<!-- Replace with your Tracking ID and domain -->
<script async src="https://umami.your-domain.com/analytics.js" data-website-id="Your Tracking ID"></script>
- Verification: Access online website, Umami backend “Realtime” page should show real-time visit data.
4. Key Optimization Configurations (Stability + Security)
4.1 Stability Optimization (Avoid Disconnection/Data Loss)
- FRP Connection Keepalive:
- Both client/server configure
tcp_keepalive = 60, send heartbeat packets every 60s to prevent operator disconnection of long connections; - Local computer disable sleep/hibernation (refer to previous solution), ensure FRP client continuously runs.
- Both client/server configure
- Umami Data Persistence:
- Ensure Docker Compose’s
postgres-datadirectory is correctly mounted (ls ~/docker/umami/postgres-datashould have files); - Regularly back up
postgres-datadirectory (e.g., weekly, compress and upload to cloud storage).
- Ensure Docker Compose’s
- FRP Log Monitoring:
- Regularly check server/client logs to troubleshoot disconnection issues:
# Check server log sudo tail -f /var/log/frps.log # Check client log tail -f ~/frp/frpc.log
- Regularly check server/client logs to troubleshoot disconnection issues:
4.2 Security Optimization (Prevent Unauthorized Access)
- FRP Authentication Strengthening:
tokenmust be a strong password (≥16 characters, letters + numbers + special characters), avoid leakage;- Disable FRP panel (if not needed), or only allow your IP to access the panel:
# Add panel IP whitelist in frps.ini dashboard_addr = 0.0.0.0 allow_ports = 8080 # Only allow mapped port 8080 (limit port range)
- Umami Backend Access Restriction:
- Nginx configure IP whitelist, only allow your IP to access Umami backend (
/admin/*path):# Add in 443 server block location ^~ /admin/ { allow 你的公网 IP; # e.g., 111.222.333.444 deny all; # Deny other IPs proxy_pass http://127.0.0.1:8080; # Other proxy_set_header configurations as above } - Disable Umami public statistics page (“Settings” → “General” → uncheck “Public Sharing”).
- Nginx configure IP whitelist, only allow your IP to access Umami backend (
- Prohibit Direct Access to Port 8080:
- Server firewall only allows Nginx process access to port 8080, prohibit external direct access (optional, achieved indirectly via Nginx reverse proxy).
5. Common Troubleshooting (Precise Diagnosis)
- FRP Client Connection Failure:
- Check server IP/port:
server_addrandserver_portare correct, server firewall opens port 7000; - Check token consistency: client/server’s
tokenmust be exactly the same (case-sensitive); - Check network connectivity: local computer execute
telnet serverIP 7000ornc -zv serverIP 7000, confirm port is reachable.
- Check server IP/port:
- Public Access to Umami Returns 502 Error:
- Check local Umami service:
curl http://localhost:3000accessible (ensure Docker container running); - Check FRP forwarding status: log in FRP panel (
https://serverIP:7500), checkumami-tcprule shows “Online”; - Check Nginx configuration:
proxy_passpoints to127.0.0.1:8080, no typos.
- Check local Umami service:
- Online Website Data Not Displayed:
- Check tracking script path: ensure
srcishttps://umami.your-domain.com/analytics.js(consistent with Docker’sTRACKER_SCRIPT_NAME); - Check browser console: F12 view “Network” panel, check if
analytics.jsfails to load (ad blockers may block, temporarily disable testing); - Check Umami logs:
docker-compose logs -f umami-appfor tracking request records.
- Check tracking script path: ensure
- FRP Connection Unstable (Frequent Disconnection):
- Enable
use_compression = trueanduse_encryption = true, reduce network fluctuation impact; - Adjust
tcp_keepaliveto 30s, increase heartbeat frequency; - Check local network: Wi-Fi may cause disconnections, recommend switching to wired network.
- Enable
Summary
The FRP solution fully adapts to your needs. Core advantages: Autonomous control (no reliance on third-party tunnel services), low latency (direct forwarding), flexible configuration. By combining “FRP server/client” + “Nginx HTTPS reverse proxy”, you can achieve stable external service provision of local Umami, online website does not need to modify core architecture, only needs to add tracking code for integration.
Key configurations focus on FRP parameter consistency, HTTPS certificate configuration, IP whitelist restrictions, following the above steps ensures stability and security meet long-term personal website usage needs.
