Custom Tunnel Hooks
Custom hooks allow you to execute scripts automatically when a tunnel starts or stops.
Hook Locationβ
Create your custom hooks in the .dvs/hooks/ folder of your application:
/app/.dvs/hooks/
βββ tunnel.after_start.sh
βββ tunnel.after_stop.sh
Execution Context
Hooks run inside the DVS container where /app/ is mounted to your application directory on the host. All file paths in hooks should use /app/ as the base path.
Hook Functionsβ
Each hook file must define a specific function:
tunnel.after_start.shβ
#!/bin/bash
# Hook executed after tunnel starts
# Receives tunnel URL as first argument
hook.tunnel.after_start() {
local tunnel_url="$1"
# Your custom code here
echo "Tunnel started at: $tunnel_url"
}
tunnel.after_stop.shβ
#!/bin/bash
# Hook executed after tunnel stops
hook.tunnel.after_stop() {
# Your custom code here
echo "Tunnel stopped"
}
Available Variablesβ
Inside your hooks, you have access to DVS environment variables:
| Variable | Description |
|---|---|
$APP_NAME | Application name |
$APP_RECIPE | Recipe type (wordpress, prestashop, lamp...) |
$APP_ROOT | Application root path on host |
$DVS_DOMAIN | DVS domain (e.g., dvs.sh) |
The local application domain is $APP_NAME.$DVS_DOMAIN.
For tunnel.after_start, the tunnel URL is passed as the first argument ($1).
Use Casesβ
Notify a Slack channelβ
hook.tunnel.after_start() {
local tunnel_url="$1"
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"Tunnel available: $tunnel_url\"}" \
"$SLACK_WEBHOOK_URL"
}
Update external configurationβ
hook.tunnel.after_start() {
local tunnel_url="$1"
# Update .env file with tunnel URL
sed -i "s|APP_URL=.*|APP_URL=$tunnel_url|" /app/.env
}
hook.tunnel.after_stop() {
# Restore local URL
sed -i "s|APP_URL=.*|APP_URL=https://$APP_NAME.$DVS_DOMAIN|" /app/.env
}
Clear cache after tunnel changeβ
hook.tunnel.after_start() {
# Clear application cache
php /app/bin/console cache:clear 2>/dev/null || true
}
hook.tunnel.after_stop() {
php /app/bin/console cache:clear 2>/dev/null || true
}
Execution Orderβ
When starting a tunnel:
- Tunnel container starts
- Recipe hook executes (if defined)
- User hook executes (
tunnel.after_start) app.update_config()is called
When stopping a tunnel:
- User hook executes (
tunnel.after_stop) - Recipe hook executes (if defined)
app.update_config()is called- Tunnel container stops
Notesβ
- Hooks are optional - if the file doesn't exist, it's silently ignored
- Recipe-provided hooks run before user hooks on start, after on stop
- Use
set -ecarefully as it may interrupt the tunnel process on errors