Professional web-based management system for Cloudflare Tunnels with advanced monitoring, health checks, and automation
A powerful, modern web interface for managing Cloudflare Tunnels (cloudflared) on Linux. Created for system administrators who need reliable tunnel management with enterprise features like health monitoring, auto-restart, environment tagging, and Discord notifications - all without requiring systemd or root permissions.
- Why Cloudflare Tunnel Manager?
- Features
- Prerequisites
- Installation
- Quick Start
- Production Setup with PM2
- Usage Guide
- Advanced Features
- API Documentation
- Configuration
- Troubleshooting
- Contributing
- License
Managing Cloudflare Tunnels via command line is tedious. This tool provides:
✅ Beautiful Web Interface - Manage all tunnels from your browser
✅ No Systemd Required - Uses PM2 for process management
✅ Health Monitoring - Auto-restart failed tunnels
✅ Environment Tags - Organize Production, Staging, Development
✅ Bulk Operations - Start/stop/delete multiple tunnels
✅ Discord Alerts - Get notified when tunnels fail
✅ Zero Downtime - Tunnels survive server reboots
✅ Advanced Routing - One tunnel, multiple backend services
✅ Dark Mode - Easy on the eyes for late-night ops
Perfect for: DevOps engineers, system administrators, developers managing multiple Cloudflare Tunnels across different environments.
-
Tunnel Management
- Create, start, stop, restart, and delete tunnels via web UI
- Real-time tunnel status monitoring with color-coded indicators
- Live log viewer with auto-refresh
- Process tracking across app restarts
-
Cloudflare Integration
- Automatic tunnel creation via Cloudflare API
- Auto-configure DNS records (CNAME)
- Zone ID management per tunnel
- Secure credential storage
- API token or Global API Key support
-
Linux System Integration
- Auto-detect cloudflared installation
- One-click cloudflared installer for Ubuntu 24.04
- Process management without root permissions
- Automatic cleanup of orphaned processes
-
🏷️ Environment Management
- Tag tunnels as Production, Staging, or Development
- Color-coded badges (Green/Yellow/Blue)
- Filter tunnels by environment
- Click badge dropdown to change environment instantly
-
❤️ Health Checks & Auto-Restart
- HTTP health check monitoring with configurable intervals (10s+)
- Custom health check paths (e.g.,
/health,/api/status) - Automatic tunnel restart on health check failure
- Real-time health status display (healthy/unhealthy)
- Reduces downtime to near-zero
-
🚀 Auto-Startup (PM2 Integration)
- Mark tunnels to auto-start when app launches
- Toggle auto-startup with a single checkbox
- Works perfectly with PM2 process manager
- Survive server reboots without systemd
- No root permissions required
-
🔔 Discord Notifications
- Global webhook integration
- Notifications for: tunnel stopped, crashed, health check failed, started
- Color-coded Discord embeds (Red/Orange/Green)
- Keep your team informed in real-time
-
💾 Backup & Disaster Recovery
- Export all tunnels and settings to JSON
- Import configuration from backup file
- Migrate between servers easily
- Version control your tunnel configs
-
🔐 Security
- Password-protect the entire dashboard
- Session-based authentication (24h timeout)
- Full UI restriction when unauthenticated
- Beautiful gradient login screen
- Logout functionality
-
🌙 Dark Mode
- Complete dark theme support
- Persistent preference (localStorage)
- Reduced eye strain for night operations
- Works on all screens including login
-
📦 Bulk Operations
- Select multiple tunnels with checkboxes
- Bulk start, stop, or delete operations
- Environment-based filtering for bulk actions
- Progress feedback for each operation
-
🔀 Advanced Routing
- Path-based routing within single tunnel
- Multiple backend services (e.g.,
/api→3000,/app→8080) - Reduce tunnel count, save on limits
- Dynamic service configuration
Before installing Cloudflare Tunnel Manager, ensure you have:
- Node.js v14 or higher (Download)
- npm (comes with Node.js)
- Ubuntu 24.04 or compatible Linux distribution
- Cloudflare Account with API access (Sign up)
- cloudflared - Cloudflare Tunnel daemon (Installation guide)
- PM2 - Process manager for Node.js (Install guide below)
# Clone the repository
git clone https://github.com/codewizdevs/cloudflare-tunnel-manager.git
cd cloudflare-tunnel-manager
# Or download and extract ZIP from GitHub releasesFollow the official Cloudflare guide to install cloudflared on your system: Cloudflare Tunnel Installation
For Ubuntu/Debian:
# Download and install
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
# Verify installation
cloudflared --versionnpm installThis will install:
- Express.js (web server)
- Axios (HTTP client for Cloudflare API)
- Body-parser (request parsing)
- Express-session (authentication)
Rename config.sample.js to config.js and change the server port if needed:
module.exports = {
port: 3000, // Change to your preferred port
// ... other settings
};Or set environment variable:
export PORT=8080For Development/Testing:
npm startFor Production (Recommended):
# Install PM2 globally
sudo npm install -g pm2
# Start with PM2
npm run pm2:start
# Configure auto-start on boot
npm run pm2:startup
# Run the sudo command it outputs
# Save PM2 configuration
npm run pm2:saveOpen your browser and navigate to:
http://localhost:3000
Or from another machine (replace with your configured port if changed):
http://YOUR_SERVER_IP:3000
- Go to Cloudflare API Tokens
- Click "Create Token" → "Create Custom Token"
- Set permissions:
- Account → Cloudflare Tunnel → Edit
- Zone → DNS → Edit
- Account → Account Settings → Read
- Click "Continue to summary" → "Create Token"
- Copy the token (you won't see it again!)
- Open
http://localhost:3000 - Click "Settings" in the navigation
- Go to "Cloudflare API" tab
- Paste your API token
- Click "Save Settings"
- System will authenticate and auto-detect your Account ID
If the system shows "Requirements Not Installed":
- Click "Install Cloudflared" button
- Wait for installation to complete
- Refresh the page
- Click "Create Tunnel"
- Fill in the form:
- Tunnel Name:
my-first-tunnel - Zone ID: Your Cloudflare Zone ID (find in Cloudflare dashboard)
- Local Port:
8080(or your service port) - Hostname:
app.example.com(full domain required) - Environment:
production
- Tunnel Name:
- Optional: Enable health checks and auto-startup
- Click "Create Tunnel"
- Find your tunnel in the list
- Click "Start" button
- Watch the status indicator turn green
- Click "Logs" to view connection details
Visit your configured hostname (e.g., https://app.example.com)
Your local service on port 8080 is now accessible via Cloudflare Tunnel! 🎉
For production environments, use PM2 to ensure zero-downtime operation.
- ✅ Auto-restart on crashes
- ✅ Start on server boot (no systemd config needed)
- ✅ Log management and rotation
- ✅ Process monitoring
- ✅ Works perfectly with tunnel auto-startup feature
# 1. Install PM2 globally
sudo npm install -g pm2
# 2. Start the application
cd /path/to/cloudflare-tunnel-manager
npm run pm2:start
# 3. Configure startup on boot (ONE TIME ONLY)
npm run pm2:startup
# Copy and run the command it outputs (requires sudo)
# 4. Save current PM2 state
npm run pm2:save
# 5. Verify it's running
npm run pm2:status# View live logs
npm run pm2:logs
# Check status
npm run pm2:status
# Restart after updates
npm run pm2:restart
# Stop the app
npm run pm2:stop- Create tunnels and enable "Auto-startup" checkbox
- When PM2 starts the app, marked tunnels auto-start
- Server reboot → PM2 starts app → Tunnels auto-start
- Zero manual intervention required!
-
Click "Create Tunnel"
-
Enter required information:
- Tunnel Name: Friendly identifier
- Zone ID: From Cloudflare dashboard (Domain → Overview → Zone ID)
- Local Port: The port your service runs on (e.g., 3000, 8080)
- Hostname: Full domain like
app.example.com(NOT justapp) - Environment: Select Production, Staging, or Development
-
Click "Create Tunnel"
- Follow basic tunnel steps above
- Enable "Health Checks" checkbox
- Configure:
- Interval: How often to check (default 30s)
- Health Path: Endpoint to check (e.g.,
/health)
- Enable "Auto-restart on failure"
- Enable "Auto-startup" for critical tunnels
- Create tunnel
Route different URL paths to different backend services:
- Fill in basic tunnel info
- Scroll to "Advanced Routing"
- Click "+ Add Service"
- Add services:
- Path:
/api→ Port:3000 - Path:
/admin→ Port:9000 - Path:
/app→ Port:8080
- Path:
- Create tunnel
Result: app.example.com/api → localhost:3000, app.example.com/admin → localhost:9000, etc.
- Start: Click green "Start" button
- Stop: Click yellow "Stop" button (when running)
- Restart: Click blue "Restart" button (when running)
- View Logs: Click "Logs" button for real-time output
- Click the environment badge (e.g., "production")
- Select new environment from dropdown
- Badge updates instantly
- Click the "Auto-startup" checkbox on tunnel card
- Enabled: Tunnel auto-starts when app starts
- Disabled: Manual start required
- Use "Environment Filter" dropdown
- Show only: All, Production, Staging, or Development
- Combine with bulk operations
- Check boxes next to tunnels
- Click "Bulk Actions" button
- Choose: Start All, Stop All, or Delete All
- Confirm action
- Click "Export" button
- Downloads JSON file with:
- All tunnel configurations
- Application settings
- Timestamp
- Click "Import" button
- Select backup JSON file
- Click "Import"
- Tunnels merge with existing
Use case: Migrate to new server, disaster recovery, clone setup
- Settings → Cloudflare API tab
- Select "API Token" (recommended)
- Paste your token
- Optional: Enter Account ID (auto-detected if empty)
- Click "Save Settings"
-
Create Discord webhook:
- Discord Server → Settings → Integrations → Webhooks → New Webhook
- Copy webhook URL
-
Settings → Notifications tab
-
Paste webhook URL
-
Click "Save Settings"
You'll receive notifications for:
- 🛑 Tunnel stopped (red)
- 💥 Tunnel crashed (red)
⚠️ Health check failed (orange)- ✅ Tunnel started (green)
- Settings → Security tab
- Enable "Password Protection"
- Enter a strong password
- Click "Save Settings"
- Page reloads → Login screen appears
To disable if locked out: Edit data/settings.json, set passwordProtection.enabled to false, restart app.
- Click moon/sun icon in navbar
- Preference saved automatically
- Applies to all screens including login
What it does: Monitors your backend service and auto-restarts tunnel if it becomes unhealthy.
Setup:
- Enable when creating tunnel
- Set interval (e.g., 30 seconds)
- Set health path (e.g.,
/healthor/) - Enable auto-restart
How it works:
- Every X seconds, makes HTTP request to
http://localhost:PORT/health-path - If response is 4xx/5xx or connection fails → marks unhealthy
- If auto-restart enabled → automatically restarts tunnel
- Displays health badge on tunnel card
Example use case: Production API that should always be up. Health check every 30s, auto-restart enabled. If API crashes, tunnel restarts within 30s.
Organize tunnels by purpose:
- Production (Green) - Live, customer-facing services
- Staging (Yellow) - Pre-production testing
- Development (Blue) - Development and testing
Features:
- Filter view by environment
- Color-coded visual organization
- Bulk operations per environment
- Change environment via badge dropdown
Workflow example:
- Create tunnel in "development"
- Test thoroughly
- Click environment badge → change to "staging"
- Final tests
- Click environment badge → change to "production"
One tunnel, multiple backend services with path-based routing.
Example configuration:
Hostname: app.example.com
Services:
/api → localhost:3000 (API server)
/admin → localhost:9000 (Admin panel)
/static → localhost:8080 (Static assets)
Result:
app.example.com/api/users→ Your API on port 3000app.example.com/admin/dashboard→ Admin on port 9000app.example.com/static/logo.png→ Static server on port 8080
Benefits:
- Save on tunnel limits
- Consolidate multiple services
- Simpler DNS management
- One tunnel to rule them all
The Problem: After server reboot, you need to manually start tunnels.
The Solution: Auto-startup checkbox + PM2
Setup:
- Install PM2 and configure startup (see Production Setup)
- Enable "Auto-startup" on critical tunnels
- Reboot server
- PM2 starts app → App auto-starts marked tunnels
Benefits:
- ✅ Zero manual intervention after reboot
- ✅ No systemd configuration
- ✅ No root permissions for tunnel management
- ✅ Works with health checks and auto-restart
Manage multiple tunnels simultaneously.
Common scenarios:
Stop all staging tunnels:
- Filter: "Staging"
- Select all visible tunnels
- Bulk Actions → Stop All
Delete all development tunnels:
- Filter: "Development"
- Select tunnels to remove
- Bulk Actions → Delete All
- Confirm
Start all production tunnels:
- Filter: "Production"
- Select all
- Bulk Actions → Start All
When password protection is enabled, include session cookie with requests.
GET /api/system/status- Check cloudflared installationPOST /api/system/install- Install cloudflared
POST /api/auth/login- Login with passwordPOST /api/auth/logout- LogoutGET /api/auth/status- Check auth status
GET /api/tunnels- List all tunnelsGET /api/tunnels/:id- Get tunnel detailsPOST /api/tunnels- Create tunnelDELETE /api/tunnels/:id- Delete tunnel (full cleanup)POST /api/tunnels/:id/start- Start tunnelPOST /api/tunnels/:id/stop- Stop tunnelPOST /api/tunnels/:id/restart- Restart tunnelGET /api/tunnels/:id/status- Get statusGET /api/tunnels/:id/logs- Get logsPOST /api/tunnels/:id/autostartup- Toggle auto-startupPOST /api/tunnels/:id/environment- Change environment
POST /api/tunnels/bulk/start- Start multiplePOST /api/tunnels/bulk/stop- Stop multiplePOST /api/tunnels/bulk/delete- Delete multiple
GET /api/backup/export- Export configurationPOST /api/backup/import- Import configuration
GET /api/settings- Get settingsPOST /api/settings- Update settings
Change the server port by editing config.js:
module.exports = {
port: 8080, // Your preferred port
// ... other settings
};Or use environment variable:
export PORT=8080
npm startFor production, set a custom session secret:
export SESSION_SECRET="your-random-secure-secret-here"Or edit config.js:
sessionSecret: 'your-random-secure-secret-here'Check cloudflared installation:
cloudflared --versionCheck tunnel logs:
- Click "Logs" button on tunnel card
- Look for error messages (shown in red)
Verify credentials file:
ls -la tunnel-configs/
# Should see tunnel_xxx-credentials.json filesTest backend service manually:
curl http://localhost:PORT/health-path
# Should return 200 OKCheck health check configuration:
- Ensure interval is reasonable (not too frequent)
- Verify health path is correct
- Check service is actually running
Wait for DNS propagation: 1-2 minutes
Clear local DNS cache:
sudo systemd-resolve --flush-cachesVerify in Cloudflare:
- Dashboard → Your Domain → DNS
- Look for CNAME:
your-hostname→tunnel-id.cfargotunnel.com
Test DNS resolution:
nslookup your-hostname.example.com 1.1.1.1Manual recovery:
# Edit settings file
nano data/settings.json
# Find and change:
"passwordProtection": {
"enabled": false # Change to false
}
# Save and restart
npm run pm2:restart # Or: npm startFind and kill process manually:
# Find cloudflared processes
ps aux | grep cloudflared
# Kill by PID
kill <PID>Reconfigure PM2 startup:
npm run pm2:startup
# Run the sudo command it provides
npm run pm2:saveTest reboot:
sudo reboot
# After reboot, check:
npm run pm2:statuscloudflare-tunnel-manager/
├── server.js # Express server
├── package.json # Dependencies
├── ecosystem.config.js # PM2 configuration
├── backend/
│ ├── cloudflareApi.js # Cloudflare API integration
│ ├── dataStore.js # JSON data persistence
│ ├── healthCheck.js # Health monitoring
│ ├── monitoring.js # Uptime tracking
│ ├── notifications.js # Discord webhooks
│ ├── systemCheck.js # System requirements
│ └── tunnelManager.js # Tunnel lifecycle management
├── public/
│ ├── index.html # Main web interface
│ ├── css/
│ │ ├── style.css # Custom styles
│ │ └── dark-mode.css # Dark theme
│ └── js/
│ └── app.js # Frontend JavaScript
├── data/ # Auto-created on first run
│ ├── credentials.json # Cloudflare API credentials
│ ├── tunnels.json # Tunnel configurations
│ └── settings.json # App settings
└── tunnel-configs/ # Auto-created on first run
├── tunnel_xxx.yml # Cloudflare tunnel config
└── tunnel_xxx-credentials.json
- Enable password protection for production deployments
- Use API tokens instead of Global API Key
- Restrict API token scope to only required permissions
- Keep credentials secure -
data/folder is gitignored - Use HTTPS if exposing the management interface externally
- Regular backups - export configuration weekly
Contributions are welcome! Here's how you can help:
- Report bugs - Open an issue with details
- Suggest features - Share your ideas
- Submit PRs - Fork, code, and submit pull requests
- Improve documentation - Help others get started
# Fork the repository on GitHub
# Clone your fork
git clone https://github.com/YOUR_USERNAME/cloudflare-tunnel-manager.git
cd cloudflare-tunnel-manager
# Install dependencies
npm install
# Run in development mode with auto-reload
npm run dev
# Make your changes
# Test thoroughly
# Submit PR to https://github.com/codewizdevs/cloudflare-tunnel-manager- Backend: Node.js, Express.js
- Frontend: Vanilla JavaScript, Tabler UI
- Storage: JSON files (no database required)
- Process Management: PM2 (optional but recommended)
- API Integration: Cloudflare API v4
- System Integration: Linux process management
Why these choices:
- No database = Simple deployment
- Vanilla JS = No build step, fast loading
- Tabler UI = Modern, professional design
- PM2 = Production-ready process management
ISC License - Free to use, modify, and distribute.
Built by CodeWizDev - Professional web development and DevOps solutions.
Visit: codewizdev.com
If this tool saves you time, please:
- ⭐ Star this repository
- 🐛 Report bugs you find
- 💡 Suggest features you need
- 📢 Share with other DevOps engineers
- Issues: GitHub Issues
- Documentation: See PM2_SETUP.md for detailed PM2 guide
- Cloudflare Docs: Cloudflare Tunnel Documentation
cloudflare tunnel, cloudflared manager, tunnel management, web interface, cloudflare zero trust, tunnel automation, health monitoring, pm2 integration, devops tools, linux tunnel manager, cloudflare api, tunnel dashboard, cloudflare tunnel gui, reverse proxy, tunnel monitoring
Made with ❤️ by CodeWizDev