Skip to content

Instantly share code, notes, and snippets.

@lgersman
Created June 20, 2024 19:07
Show Gist options
  • Save lgersman/e45e5c930bda8b617411de2fd7a9b2b0 to your computer and use it in GitHub Desktop.
Save lgersman/e45e5c930bda8b617411de2fd7a9b2b0 to your computer and use it in GitHub Desktop.
start a cloudflare quick tunnel (no cloudflare account needed, no cloudflared needs to be installed) to expose your local wp-env development instance to the internet using https
#!/usr/bin/env bash
# starts a cloudflare quick tunnel (no cloudflare account needed, no cloudflared needs to be installed)
# for tunneling a wp-env wordpress site to the internet.
#
# dependencies : bash, docker, jq
#
# the wp-env instance does needed to be started since this script hijacks
# the wp-env instance file "wp-env-home/*/WordPress/wp-config.php"
# the wp-env instance is restarted the quick tunnel will be available
#
# your wp-env wordpress development instance is
# afterwards available using true HTTPS in the public internet
#
# abort the script using ctrl-c/ctrl-d/etc will take your wp-env instance offline and
# cleans up the docker ćontainer
#
# ATTENTION:
# cloudflare has a undocumented rate limit for quick tunnels. so be careful with the script
# if you run the script too often in a short time, the quick tunnel will not be created
#
# a quick tunnel can be used across wp-env restarts so you dont need to run the script again and again
#
# if an quick tunnel could not be openend up an error message will appear
# "failed to unmarshal quick Tunnel: invalid character 'e' looking for beginning of value"
# you should wait for an hour and try aghain - its a rate limit from cloudflare for quick tunnels
#
# autor: lars gersmann <lars.gersmann@gmail.com>
# set the port of the wp-env instance to tunnel (defaults to 8888)
WP_ENV_PORT=${WP_ENV_PORT:-8888}
# docker container name to identify the created cloudflare container
CLOUDFLARE_DOCKER_CONTAINER_NAME="cloudflare-tunnel"
# limit of quicktunnel checks before aborting
QUICKTUNNEL_CHECK_LIMIT=10
# cloudflared metrics port
CLOUDFLARED_METRICS_PORT=55555
if [ -f wp-env-home/*/WordPress/wp-config.php ]; then
echo "wp-env instance is running"
else
echo "wp-env instance is not running"
exit 1
fi
# this is just for safety reasons :
# silently cleanup any existing containers with the same name
# (may happen if something went wrong)
containers=$(docker ps -a -q --filter="name=$CLOUDFLARE_DOCKER_CONTAINER_NAME")
[ -n "$containers" ] && docker rm -f $containers
# run the cloudflared container
# --network=host is used to allow the container to access the host's network
# --rm is used to remove the container when it exits
# --name is used to give the container a name
# --no-autoupdate is used to disable auto-updates
# --metrics is used to expose metrics on localhost:55555
# --url is used to specify the local server to tunnel to
# & is used to run the command in the background
docker run --pull=always --network=host --rm --name $CLOUDFLARE_DOCKER_CONTAINER_NAME cloudflare/cloudflared:latest \
tunnel --no-autoupdate --metrics localhost:$CLOUDFLARED_METRICS_PORT --url http://localhost:$WP_ENV_PORT &
# count of already done quicktunnel checks
quicktunnel_checks=1
# wait for the cloudflared container to be ready
while true; do
# wait 2 seonds before testing cloudflare quicktunnel is available
sleep 2
# send a ready request to the cloudflared container
# (see all quicktunnel / metrics commands here : https://github.com/cloudflare/cloudflared/issues/900#issuecomment-1464758364)
response=$(curl -s http://localhost:${CLOUDFLARED_METRICS_PORT}/ready ||:)
echo "(${quicktunnel_checks}/10) waiting for cloudflared container to be ready ..."
# check if the HTTP status is 200 and the JSON response has a status property of 200
if [[ $(echo $response | jq -r '.status') == "200" ]]; then
echo "cloudflared container is ready"
break
fi
((quicktunnel_checks++))
# if the counter is > QUICKTUNNEL_CHECK_LIMIT, abort the script
if [ $quicktunnel_checks -gt $QUICKTUNNEL_CHECK_LIMIT ]; then
echo "abort : cloudflared container was not ready after 10 attempts"
exit 1
fi
done
cloudflare_url="https://$(curl -s http://localhost:${CLOUDFLARED_METRICS_PORT}/quicktunnel | jq -r .hostname)"
echo "
website is available at: ${cloudflare_url}
Don't forget to shutdown this script using ctrl-c/ctrl-d/etc at the end of the day
to avoid that your wordpress instance is available in the internet 24/7 !
"
# TODO: inject the cloudflare url into the wp-env instance WP_SITEURL and WP_HOME constants
sed -i "/define( 'WP_SITEURL',/s|'[^']*' );$|'$cloudflare_url' );|g" wp-env-home/*/WordPress/wp-config.php
sed -i "/define( 'WP_HOME',/s|'[^']*' );$|'$cloudflare_url' );|g" wp-env-home/*/WordPress/wp-config.php
# not needed
# if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
# $_SERVER['HTTPS'] = 'on';
# }
# wait until cloudflared container or scripts exists (e.g. ctrl-c)
wait
# cleanup/kill the container when the script exits
trap "docker rm -f $(docker ps -a -q --filter="name=$CLOUDFLARE_DOCKER_CONTAINER_NAME") 2 > /dev/null" EXIT SIGINT SIGTERM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment