ukhorsecremations.co.uk/.ddev/share-providers/cloudflared.sh
Stewart Walter 08d696985a Site build
2026-05-01 12:28:23 +01:00

100 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#ddev-generated
# cloudflared share provider for DDEV
# Documentation: https://docs.ddev.com/en/stable/users/topics/sharing/
#
# To customize: remove the 'ddev-generated' line above and edit as needed.
#
# Quick tunnel (default): Creates a temporary URL like https://xxx.trycloudflare.com
# No configuration needed - just run `ddev share --provider=cloudflared`
#
# Named tunnel (custom domain): Use your own domain managed by Cloudflare
# 1. Create tunnel: cloudflared tunnel create my-tunnel
# 2. Add DNS: cloudflared tunnel route dns my-tunnel mysite.example.com
# 3. Configure: ddev config --share-provider-args="--tunnel my-tunnel --hostname mysite.example.com"
# (--hostname tells DDEV what URL to display; DNS routing is done in step 2)
# 4. Run: ddev share --provider=cloudflared
set -euo pipefail
# Enable debug output if DDEV_DEBUG or DDEV_VERBOSE is set
if [[ "${DDEV_DEBUG:-}" == "true" ]] || [[ "${DDEV_VERBOSE:-}" == "true" ]]; then
set -x
fi
# Validate cloudflared is installed
if ! command -v cloudflared >/dev/null 2>&1; then
echo "Error: cloudflared not found in PATH." >&2
echo "Install from https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflare-tunnel/downloads/" >&2
exit 1
fi
# Validate required environment variables
if [[ -z "${DDEV_LOCAL_URL:-}" ]]; then
echo "Error: DDEV_LOCAL_URL not set" >&2
exit 1
fi
# Start cloudflared and capture output
echo "Starting cloudflared tunnel..." >&2
# Parse args to determine tunnel mode
# --tunnel and --hostname are DDEV-specific and stripped before passing to cloudflared
ARGS="${DDEV_SHARE_ARGS:-}"
TUNNEL_NAME=""
HOSTNAME=""
# Check for named tunnel mode (--tunnel flag present)
# Supports both --tunnel my-tunnel and --tunnel=my-tunnel
if [[ "$ARGS" =~ --tunnel([[:space:]]+|=)([^[:space:]]+) ]]; then
TUNNEL_NAME="${BASH_REMATCH[2]}"
ARGS=$(echo "$ARGS" | sed -E 's/--tunnel([[:space:]]+|=)[^[:space:]]+//')
fi
# Extract hostname if present (for URL output only - not passed to cloudflared)
# Supports both --hostname mysite.example.com and --hostname=mysite.example.com
if [[ "$ARGS" =~ --hostname([[:space:]]+|=)([^[:space:]]+) ]]; then
HOSTNAME="${BASH_REMATCH[2]}"
ARGS=$(echo "$ARGS" | sed -E 's/--hostname([[:space:]]+|=)[^[:space:]]+//')
fi
# Normalize whitespace left over from stripping flags
ARGS=$(echo "$ARGS" | sed -E 's/[[:space:]]+/ /g;s/^ //;s/ $//')
# For named tunnels with known hostname, output URL immediately
URL_FOUND=""
if [[ -n "$HOSTNAME" ]]; then
echo "https://$HOSTNAME" # Output to stdout - CRITICAL: This is captured by DDEV
URL_FOUND="https://$HOSTNAME"
fi
# Build and run the cloudflared command, piping all output through the reader
# Using --protocol http2 for better compatibility
if [[ -n "$TUNNEL_NAME" ]]; then
echo "Using named tunnel: $TUNNEL_NAME" >&2
echo >&2
echo "Running command: cloudflared --url $DDEV_LOCAL_URL --protocol http2${ARGS:+ $ARGS} tunnel run $TUNNEL_NAME" >&2
echo >&2
cloudflared --url "$DDEV_LOCAL_URL" --protocol http2 $ARGS tunnel run "$TUNNEL_NAME" 2>&1
else
echo >&2
echo "Running command: cloudflared tunnel --url $DDEV_LOCAL_URL --protocol http2 $ARGS" >&2
echo >&2
cloudflared tunnel --url "$DDEV_LOCAL_URL" --protocol http2 $ARGS 2>&1
fi | while IFS= read -r line; do
# For quick tunnels, look for the cloudflared URL in the output
# Exclude api.trycloudflare.com which appears in error messages
if [[ -z "$URL_FOUND" ]] && [[ "$line" =~ https://[a-z0-9-]+\.trycloudflare\.com ]]; then
POTENTIAL_URL="${BASH_REMATCH[0]}"
if [[ ! "$POTENTIAL_URL" =~ api\.trycloudflare\.com ]]; then
URL_FOUND="$POTENTIAL_URL"
echo "$URL_FOUND" # Output to stdout - CRITICAL: This is captured by DDEV
fi
fi
# Show non-info output to user (warnings, errors, etc.); show all in verbose mode
if [[ "${DDEV_VERBOSE:-}" == "true" ]] || [[ ! "$line" =~ " INF " ]]; then
echo "$line" >&2
fi
done