Skip to content

Custom Share Providers

You can customize the built-in providers or create your own share providers in .ddev/share-providers/.

Customizing Built-in Providers

Take Ownership of a Built-in Provider

  1. Edit the provider script (e.g., .ddev/share-providers/ngrok.sh)
  2. Remove the #ddev-generated line at the top
  3. Make your changes
  4. DDEV will never overwrite this file again

Create a Custom Variant

# Copy built-in provider
cp .ddev/share-providers/ngrok.sh .ddev/share-providers/my-ngrok.sh

# Edit my-ngrok.sh:
# - Remove '#ddev-generated' line
# - Customize as needed

# Use your variant
ddev share --provider=my-ngrok

Creating a New Provider

Create a new executable script in .ddev/share-providers/:

#!/usr/bin/env bash
set -euo pipefail

# Start your tunnel tool
mytunnel http "$DDEV_LOCAL_URL" &
TUNNEL_PID=$!

trap "kill $TUNNEL_PID 2>/dev/null || true" EXIT

# Capture public URL (however your tool exposes it)
URL=$(get-tunnel-url)

# Output URL to stdout (CRITICAL: first line only)
echo "$URL"

# Wait for tunnel to exit
wait $TUNNEL_PID

Provider Script Contract

Every share provider must follow this contract:

Input (Environment Variables)

Variable Description
DDEV_LOCAL_URL Local URL to tunnel (e.g., http://127.0.0.1:8080)
DDEV_SHARE_ARGS Provider-specific arguments (optional)

All standard DDEV environment variables are also available.

Output

  • stdout: Public URL (first line only - captured by DDEV)
  • stderr: Logs, status messages (passed through to user)

Lifecycle

  1. Validate tool is installed
  2. Validate required environment variables
  3. Start tunnel process in background
  4. Capture public URL (via API, stdout, file, etc.)
  5. Output URL to stdout
  6. Wait for tunnel process to exit

Signal Handling

Providers must handle SIGINT (Ctrl+C) and SIGTERM gracefully. Use trap to cleanup background processes:

cleanup() {
    if kill -0 $PID 2>/dev/null; then
        kill $PID 2>/dev/null || true
    fi
}
trap cleanup EXIT

Hooks Integration

After the tunnel URL is captured, DDEV sets the DDEV_SHARE_URL environment variable and runs pre-share hooks. This allows you to alter projects as needed (like WordPress ddev wp search-replace, for example).

Example .ddev/config.share.yaml:

hooks:
  pre-share:
    - exec: |
        echo "Tunnel URL: ${DDEV_SHARE_URL}"
        wp search-replace ${DDEV_PRIMARY_URL} ${DDEV_SHARE_URL}

Troubleshooting Custom Providers

Provider not found:

Error: share provider 'foo' not found

Check that .ddev/share-providers/foo.sh exists and is executable:

ls -la .ddev/share-providers/
chmod +x .ddev/share-providers/foo.sh

Provider outputs no URL:

Error: provider 'ngrok' did not output a URL

Common causes: tool not installed, authentication required, no internet. Debug by running the provider directly:

export DDEV_LOCAL_URL=http://127.0.0.1:8080
.ddev/share-providers/ngrok.sh