Skip to content

Instantly share code, notes, and snippets.

@irazasyed
Last active January 22, 2024 06:16
Show Gist options
  • Save irazasyed/46295bc3b823bb3b13c9acd51b96b4ad to your computer and use it in GitHub Desktop.
Save irazasyed/46295bc3b823bb3b13c9acd51b96b4ad to your computer and use it in GitHub Desktop.
Instructions on How to use Cloudflare Argo Tunnel to Share Laravel Valet Site on macOS and Helper Bash Script

How to use Cloudflare Argo Tunnel to Share Laravel Valet Site on macOS

Set up a tunnel locally

1. Download and install cloudflared

brew install cloudflare/cloudflare/cloudflared

2. Authenticate cloudflared

cloudflared tunnel login

3. Create a tunnel and give it a name

cloudflared tunnel create <NAME>

💡 Default tunnel name I've setup in the cf bash script below is local, so you could set it as local too.

Confirm that the tunnel has been successfully created by running:

cloudflared tunnel list

More details: Set up a tunnel locally.

Add DNS Record

Add DNS record for your tunnel.

cloudflared tunnel route dns <Tunnel Name> subdomain.yourdomain.com

Example assuming local is your tunnel name:

cloudflared tunnel route dns local local.yourdomain.com

Download cf Script

Download the given cf script and store it at a location where you can easily access and make it executable:

chmod +x cf

If you've used a different tunnel name other than the default local, then make sure to update the TUNNEL_NAME in cf script.

Usage

Go into any of your valet site's directory and fire:

cf

If everything goes well, then your local site should now be exposed to the internet via Cloudflare Tunnel and accessible at local.yourdomain.com.

#!/usr/bin/env bash
# This script is meant to be run from the root of a Laravel project.
# It will start a Cloudflare tunnel to the project's domain.
# It will also pass through any parameters to the Cloudflare tunnel.
# For example, you can run `cf --metrics`
#
# By default, it'll try to use a global config file but a project level config file is also supported.
# If you have a cf-tunnel.yml file in the root of your project, it will be passed through to the Cloudflare tunnel,
# optionally you can pass a custom config file too.
#
# To pass custom config, use the `--config /path/to/config.yml` file.
#
# If you have multiple sites linked to the same directory, it will use the
# first one it finds.
#
# If you have a secure site, it will use port 60.
#
# If you have a custom TLD, it will use that.
#
# If you have a custom tunnel name, you can set it in the TUNNEL_NAME
# variable below.
# Set your tunnel name
TUNNEL_NAME=local
# Default parameters to pass to Cloudflare
PARAMS=()
HOST="${PWD##*/}"
TLD=$(valet tld)
PORT=80
if ! command -v cloudflared > /dev/null 2>&1; then
echo "Error: cloudflared is not installed or cannot be found."
exit 1
fi
# Check for parameters to pass through to Cloudflare (these will start with '-' or '--')
for ARG in "$@"; do
case "$ARG" in
--config) CONFIG_FLAG=true;;
-*) PARAMS+=("$ARG");;
*) PARAMS+=("'$ARG'");;
esac
done
# Add --config flag if cf-tunnel.yml exists and --config is not already present
if [ -f "cf-tunnel.yml" ] && [ "${CONFIG_FLAG:-false}" != true ]; then
PARAMS+=("--config" "cf-tunnel.yml")
fi
# Find the first linked site for the current dir, if one exists
for LINK in ~/.config/valet/Sites/*; do
if [[ "$(readlink "$LINK")" = "$PWD" ]]; then
HOST="${LINK##*/}"
break
fi
done
# Decide the correct PORT: uses 60 for secure, else 80
if grep --quiet --no-messages 443 ~/.config/valet/Nginx/"$HOST"*; then
PORT=60
fi
# Lowercase the host to match how the rest of our domains are looked up
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')
# Start the Cloudflare tunnel
sudo -u "$USER" cloudflared tunnel \
--http-host-header "$HOST.$TLD" \
--url "localhost:$PORT" \
"${PARAMS[@]}" \
run "$TUNNEL_NAME"
exit 0
@IamSwap
Copy link

IamSwap commented Oct 20, 2023

Super! Thanks a lot.

I have modified it a little to work with Herd (https://herd.laravel.com/).

I have also added a wildcard CNAME record (*) to use it like {project}.yourdomain.com

ScreenShot 2023-10-20 at 12 50 31@2x

#!/usr/bin/env bash

# This script is meant to be run from the root of a Laravel project.
# It will start a Cloudflare tunnel to the project's domain.
# It will also pass through any parameters to the Cloudflare tunnel.
# For example, you can run `cf --metrics`
#
# By default, it'll try to use a global config file but a project level config file is also supported.
# If you have a cf-tunnel.yml file in the root of your project, it will be passed through to the Cloudflare tunnel, 
# optionally you can pass a custom config file too.
#
# To pass custom config, use the `--config /path/to/config.yml` file.
#
# If you have multiple sites linked to the same directory, it will use the
# first one it finds.
#
# If you have a secure site, it will use port 60.
#
# If you have a custom TLD, it will use that.
#
# If you have a custom tunnel name, you can set it in the TUNNEL_NAME
# variable below.

# Set your tunnel name
TUNNEL_NAME=local

# Default parameters to pass to Cloudflare
PARAMS=()
HOST="${PWD##*/}"
TLD=$(herd tld)
PORT=80

if ! command -v cloudflared > /dev/null 2>&1; then
  echo "Error: cloudflared is not installed or cannot be found."
  exit 1
fi

# Check for parameters to pass through to Cloudflare (these will start with '-' or '--')
for ARG in "$@"; do
    case "$ARG" in
        --config) CONFIG_FLAG=true;;
        -*) PARAMS+=("$ARG");;
        *) PARAMS+=("'$ARG'");;
    esac
done

# Add --config flag if cf-tunnel.yml exists and --config is not already present
if [ -f "cf-tunnel.yml" ] && [ "${CONFIG_FLAG:-false}" != true ]; then
    PARAMS+=("--config" "cf-tunnel.yml")
fi

# Find the first linked site for the current dir, if one exists
for LINK in ~/Library/Application Support/Herd/config/valet/Sites/*; do
    if [[ "$(readlink "$LINK")" = "$PWD" ]]; then
        HOST="${LINK##*/}"
        break
    fi
done

# Decide the correct PORT: uses 60 for secure, else 80
if grep --quiet --no-messages 443 ~/Library/Application Support/Herd/config/valet/Nginx/"$HOST"*; then
    PORT=60
fi

# Lowercase the host to match how the rest of our domains are looked up
HOST=$(echo "$HOST" | tr '[:upper:]' '[:lower:]')

# Start the Cloudflare tunnel
sudo -u "$USER" cloudflared tunnel \
    --http-host-header "$HOST.$TLD" \
    --url "localhost:$PORT" \
    "${PARAMS[@]}" \
    run "$TUNNEL_NAME"

exit 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment