-
-
Notifications
You must be signed in to change notification settings - Fork 700
Enhance ddev share to capture and expose ngrok URL to hooks and output #7784
Copy link
Copy link
Closed
Milestone
Description
Problem Statement
When using ddev share, the ngrok public URL is only displayed in ngrok's complex terminal output. This creates challenges for:
- CMS configuration: Systems like TYPO3, WordPress, and others need the base URL updated in their configuration files when sharing
- Automation: Hooks cannot access the ngrok URL because
pre-shareruns before ngrok starts - User experience: The actual share URL is buried in ngrok's verbose output, making it hard to find and copy
Current Behavior
// cmd/ddev/cmd/share.go (simplified flow)
ProcessHooks("pre-share") // Runs BEFORE ngrok starts - URL not available
StartNgrok() // Ngrok URL generated here
WaitForExit()
ProcessHooks("post-share") // Runs AFTER ngrok exits - too lateProposed Enhancement
Modify ddev share to:
- Start ngrok
- Poll ngrok's local API (
localhost:4040/api/tunnels) to capture the public URL - Export the URL as an environment variable (
DDEV_SHARE_URL) - Move
pre-sharehook execution to after capturing the URL (or create a newpost-share-starthook) - Display the URL prominently in output
- Clean up on exit
Implementation Approach
// After starting ngrok (around line 79 in share.go)
util.Success("Running %s %s", ngrokLoc, strings.Join(ngrokArgs, " "))
// Wait for ngrok to be ready and get the public URL
var publicURL string
for i := 0; i < 10; i++ {
time.Sleep(500 * time.Millisecond)
publicURL, err = getNgrokPublicURL()
if err == nil {
break
}
}
if publicURL != "" {
os.Setenv("DDEV_SHARE_URL", publicURL)
util.Success("╔════════════════════════════════════════════════════════")
util.Success("║ ngrok tunnel active at:")
util.Success("║ %s", publicURL)
util.Success("╚════════════════════════════════════════════════════════")
// NOW run pre-share hooks with URL available
err = app.ProcessHooks("pre-share")
if err != nil {
util.Failed("Failed to process pre-share hooks: %v", err)
}
}
// Helper function
func getNgrokPublicURL() (string, error) {
resp, err := http.Get("http://localhost:4040/api/tunnels")
if err != nil {
return "", err
}
defer resp.Body.Close()
var result struct {
Tunnels []struct {
PublicURL string `json:"public_url"`
} `json:"tunnels"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", err
}
if len(result.Tunnels) > 0 {
return result.Tunnels[0].PublicURL, nil
}
return "", fmt.Errorf("no tunnels found")
}Benefits
1. CMS Configuration Automation
TYPO3 example using .env file:
# .ddev/config.yaml
hooks:
pre-share:
- exec-host: |
# Update .env file with ngrok URL
if [ ! -z "$DDEV_SHARE_URL" ]; then
ddev dotenv set BASE_DOMAIN="${DDEV_SHARE_URL#https://}"
echo "Updated BASE_DOMAIN to $DDEV_SHARE_URL"
fi
post-share:
- exec-host: |
# Restore original domain
ddev dotenv set BASE_DOMAIN="$(ddev describe -j | jq -r .raw.primary_url | sed 's|https\?://||')"TYPO3 site config (config/sites/main/config.yaml):
base: 'https://%env(BASE_DOMAIN)%/'2. WordPress Configuration
hooks:
pre-share:
- exec: "wp search-replace '${DDEV_PRIMARY_URL}' '${DDEV_SHARE_URL}' --skip-columns=guid"
post-share:
- exec: "wp search-replace '${DDEV_SHARE_URL}' '${DDEV_PRIMARY_URL}' --skip-columns=guid"3. Better User Experience
Clean, prominent output:
Starting ddev-d11-web ... done
Running ngrok http http://d11-web:80
╔════════════════════════════════════════════════════════
║ ngrok tunnel active at:
║ https://abc123.ngrok-free.app
╚════════════════════════════════════════════════════════
Your site is now publicly accessible!
Press Ctrl-C to stop sharing.
4. Documentation & Testing
Hooks can save the URL for documentation or automated testing:
hooks:
pre-share:
- exec-host: echo "$DDEV_SHARE_URL" > .ddev/share-url.txt
- exec-host: "curl -s '$DDEV_SHARE_URL' > /dev/null && echo 'Site is accessible!'"Alternative Considered
Reserved ngrok domains: Users can use ngrok_args: "--domain my-reserved.ngrok-free.app" with a free static domain, but this:
- Requires manual ngrok account configuration
- Limits users to one static domain (ngrok free tier)
- Still doesn't make the URL easily visible in output
Related Issues
This enhancement would solve similar problems for:
- Drupal (base URL configuration)
- Laravel (APP_URL in .env)
- Symfony (various URL configurations)
- Magento (base URL settings)
- Any CMS that needs URL configuration updates
Implementation Checklist
- Add
getNgrokPublicURL()helper function - Modify share flow to capture URL after ngrok starts
- Export
DDEV_SHARE_URLenvironment variable for hooks - Reorder hook execution (pre-share after URL capture)
- Add prominent URL display in output
- Update documentation with hook examples
- Add tests for URL capture functionality
- Consider adding
ngrok_portconfig option (default: 4040) for custom ngrok API ports
Documentation Updates Needed
- Update
hooks.mdwithDDEV_SHARE_URLvariable documentation - Add CMS-specific examples (TYPO3, WordPress, etc.)
- Document ngrok API port configuration if customizable
- Add troubleshooting section for cases where URL capture fails
Created with Claude Code
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
Done