mirror of
https://github.com/ChrispyBacon-dev/DockFlare.git
synced 2026-04-28 03:39:32 +00:00
added CLOUDFLARED METRICS support
This commit is contained in:
parent
967e115451
commit
f75470c7f8
4 changed files with 51 additions and 28 deletions
|
|
@ -78,6 +78,19 @@ TUNNEL_DNS_SCAN_ZONE_NAMES = [name.strip() for name in TUNNEL_DNS_SCAN_ZONE_NAME
|
|||
REQUIRED_VARS_BASE = ["CF_API_TOKEN", "CF_ACCOUNT_ID"]
|
||||
missing_vars = []
|
||||
|
||||
# If set, enables the Prometheus metrics endpoint on the specified port.
|
||||
# The IP is hardcoded to 0.0.0.0 to be accessible within Docker networks.
|
||||
CLOUDFLARED_METRICS_PORT = os.getenv('CLOUDFLARED_METRICS_PORT')
|
||||
if CLOUDFLARED_METRICS_PORT:
|
||||
try:
|
||||
port = int(CLOUDFLARED_METRICS_PORT)
|
||||
if not (1 <= port <= 65535):
|
||||
logging.warning(f"Metrics port {port} is outside the valid range (1-65535). Disabling.")
|
||||
CLOUDFLARED_METRICS_PORT = None
|
||||
except ValueError:
|
||||
logging.warning(f"Invalid value for CLOUDFLARED_METRICS_PORT: '{CLOUDFLARED_METRICS_PORT}'. Must be a number. Disabling.")
|
||||
CLOUDFLARED_METRICS_PORT = None
|
||||
|
||||
if not USE_EXTERNAL_CLOUDFLARED:
|
||||
if not TUNNEL_NAME:
|
||||
REQUIRED_VARS_BASE.append("TUNNEL_NAME")
|
||||
|
|
|
|||
|
|
@ -427,17 +427,10 @@ def start_cloudflared_container():
|
|||
cloudflared_agent_state["last_action_status"] = "Starting/Reconciling..."
|
||||
|
||||
if not docker_client:
|
||||
msg = "Docker client not available."
|
||||
logging.error(msg)
|
||||
cloudflared_agent_state["last_action_status"] = f"Error: {msg}"
|
||||
return False
|
||||
if not tunnel_state.get("token"):
|
||||
msg = "Tunnel token not available."
|
||||
logging.error(msg)
|
||||
cloudflared_agent_state["last_action_status"] = f"Error: {msg}"
|
||||
return False
|
||||
if not config.CLOUDFLARED_NETWORK_NAME or not ensure_docker_network_exists(config.CLOUDFLARED_NETWORK_NAME):
|
||||
logging.error(f"Failed network check/create for '{config.CLOUDFLARED_NETWORK_NAME}'. Cannot start agent.")
|
||||
return False
|
||||
|
||||
token = tunnel_state["token"]
|
||||
|
|
@ -451,7 +444,6 @@ def start_cloudflared_container():
|
|||
if network_mode != config.CLOUDFLARED_NETWORK_NAME:
|
||||
logging.warning(f"Network mismatch for managed agent. Desired: '{config.CLOUDFLARED_NETWORK_NAME}', Actual: '{network_mode}'. Recreation required.")
|
||||
needs_recreate = True
|
||||
|
||||
try:
|
||||
current_image = container.image.tags[0] if container.image.tags else None
|
||||
if current_image != config.CLOUDFLARED_IMAGE:
|
||||
|
|
@ -459,12 +451,29 @@ def start_cloudflared_container():
|
|||
needs_recreate = True
|
||||
except Exception as img_err:
|
||||
logging.warning(f"Could not reliably determine image for running agent container: {img_err}")
|
||||
|
||||
desired_metrics_port = config.CLOUDFLARED_METRICS_PORT
|
||||
port_bindings = container.attrs.get('HostConfig', {}).get('PortBindings', {})
|
||||
|
||||
actual_metrics_port = None
|
||||
if port_bindings:
|
||||
for port_key in port_bindings:
|
||||
if port_key.endswith('/tcp'):
|
||||
actual_metrics_port = port_key[:-4]
|
||||
break
|
||||
|
||||
if desired_metrics_port and actual_metrics_port != desired_metrics_port:
|
||||
logging.warning(f"Metrics port mismatch. Desired: '{desired_metrics_port}', Actual: '{actual_metrics_port}'. Recreation required.")
|
||||
needs_recreate = True
|
||||
elif not desired_metrics_port and actual_metrics_port:
|
||||
logging.warning(f"Metrics port should be disabled, but found port '{actual_metrics_port}' exposed. Recreation required.")
|
||||
needs_recreate = True
|
||||
|
||||
if needs_recreate:
|
||||
logging.info(f"Removing misconfigured agent container '{container.name}' before recreation...")
|
||||
try:
|
||||
container.remove(force=True)
|
||||
container = None
|
||||
container = None
|
||||
except (APIError, requests.exceptions.ConnectionError) as rm_err:
|
||||
logging.error(f"Failed to remove misconfigured agent '{container.name}': {rm_err}. Cannot proceed.")
|
||||
cloudflared_agent_state["last_action_status"] = f"Error: Failed to remove old agent: {rm_err}"
|
||||
|
|
@ -487,37 +496,38 @@ def start_cloudflared_container():
|
|||
logging.info(f"Pulling image {config.CLOUDFLARED_IMAGE}...");
|
||||
docker_client.images.pull(config.CLOUDFLARED_IMAGE)
|
||||
logging.info("Image pull complete.")
|
||||
except APIError as img_err:
|
||||
except Exception as img_err:
|
||||
logging.warning(f"Could not pull image {config.CLOUDFLARED_IMAGE}: {img_err}. Will attempt using local if available.")
|
||||
except requests.exceptions.ConnectionError as e_conn_pull:
|
||||
logging.error(f"Docker connection failed during image pull: {e_conn_pull}")
|
||||
cloudflared_agent_state["last_action_status"] = f"Error: Docker connect pull image."
|
||||
return False
|
||||
|
||||
|
||||
command_parts = ["tunnel"]
|
||||
ports_mapping = {}
|
||||
if config.CLOUDFLARED_METRICS_PORT:
|
||||
metrics_address = f"0.0.0.0:{config.CLOUDFLARED_METRICS_PORT}"
|
||||
command_parts.extend(["--metrics", metrics_address])
|
||||
ports_mapping[f"{config.CLOUDFLARED_METRICS_PORT}/tcp"] = int(config.CLOUDFLARED_METRICS_PORT)
|
||||
logging.info(f"Metrics endpoint will be enabled on {metrics_address}")
|
||||
|
||||
command_parts.extend(["--no-autoupdate", "run", "--token", token])
|
||||
try:
|
||||
container_params = {
|
||||
"image": config.CLOUDFLARED_IMAGE,
|
||||
"command": f"tunnel --no-autoupdate run --token {token}",
|
||||
"command": command_parts,
|
||||
"name": config.CLOUDFLARED_CONTAINER_NAME,
|
||||
"network": config.CLOUDFLARED_NETWORK_NAME,
|
||||
"restart_policy": {"Name": "unless-stopped"},
|
||||
"detach": True,
|
||||
"remove": False,
|
||||
"labels": {"managed-by": "dockflare"}
|
||||
"labels": {"managed-by": "dockflare"},
|
||||
"ports": ports_mapping
|
||||
}
|
||||
new_container = docker_client.containers.run(**container_params)
|
||||
msg = f"Successfully created and started agent container '{new_container.name}' ({new_container.id[:12]})."
|
||||
cloudflared_agent_state["last_action_status"] = msg
|
||||
logging.info(msg)
|
||||
except APIError as create_err:
|
||||
msg = f"Docker API error creating agent container: {create_err}"
|
||||
logging.error(msg, exc_info=True)
|
||||
cloudflared_agent_state["last_action_status"] = msg
|
||||
return False
|
||||
return False
|
||||
except requests.exceptions.ConnectionError as e_conn_run:
|
||||
logging.error(f"Docker connection failed running agent container: {e_conn_run}")
|
||||
cloudflared_agent_state["last_action_status"] = f"Error: Docker connect run agent."
|
||||
return False
|
||||
return False
|
||||
|
||||
time.sleep(2)
|
||||
update_cloudflared_container_status()
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ def main_application_entrypoint():
|
|||
|
||||
logging.info("-" * 52)
|
||||
logging.info("--- DockFlare Starting ---")
|
||||
logging.info(f"--- Version: 1.9.0 ---")
|
||||
logging.info(f"--- Version: 1.9.1 ---")
|
||||
logging.info("-" * 52)
|
||||
|
||||
load_state()
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>DockFlare v1.9.0 - Cloudflare Tunnel ingress Manager</title>
|
||||
<title>DockFlare v1.9.1 - Cloudflare Tunnel ingress Manager</title>
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/output.css') }}">
|
||||
<link rel="preconnect" href="https://rsms.me" crossorigin>
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
<body class="min_h-screen flex flex-col font-sans transition-colors duration-300">
|
||||
<div class="fixed bottom-6 right-[-38px] sm:bottom-7 sm:right-[-35px] z-50 transform -rotate-45 bg-indigo-600 text-white text-xs font-semibold tracking-wider text-center py-1 w-36 shadow-md"
|
||||
style="pointer-events: none;">
|
||||
version 1.9.0
|
||||
version 1.9.1
|
||||
</div>
|
||||
|
||||
<header class="sticky top-0 z-40 w-full backdrop-blur-sm shadow-sm bg-base-100/90">
|
||||
|
|
@ -446,7 +446,7 @@
|
|||
<p class="mb-1"><a href="https://github.com/ChrispyBacon-dev/DockFlare/wiki" target="_blank" rel="noopener noreferrer" class="link link-hover link-primary">DockFlare Documentation</a></p>
|
||||
<p class="mb-1">Enjoying DockFlare? Consider supporting the project!</p>
|
||||
<p><a href="https://github.com/sponsors/ChrispyBacon-dev" target="_blank" rel="noopener noreferrer" class="inline-flex items-center link link-hover"><svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1 text-pink-500" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd" /></svg>Sponsor ChrispyBacon-dev on GitHub</a></p>
|
||||
<p class="mt-2 text-xs opacity-60">DockFlare v1.9.0</p>
|
||||
<p class="mt-2 text-xs opacity-60">DockFlare v1.9.1</p>
|
||||
</div>
|
||||
</footer>
|
||||
<dialog id="add_manual_rule_modal" class="modal">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue