Notifications
The self-hosted version of Domain Locker supports basic notifications, sent via webhooks. These can alert you about upcoming expirations or important changes to your domains.
The managed version's built-in channels (email, WhatsApp, Signal, etc) rely upon non-free 3rd party services, so they're not available when self-hosting. But Apprise (below) can relay notifications to pretty much any service, including those, and ntfy lets you hook into their API and call whichever third-parties you like.
Push notifications via NTFY
ntfy.sh is a free and simple pub-sub notification service, which can delivery push notifications to your devices, when a webhook is triggered.
It's open source (on GitHub), and can be easily self-hosted, or used via their public instance.
To configure notifications for domain locker, set the following env vars. These can go in your docker-compose (under app --> environment), or within your .env or secret store.
NOTIFY_WEBHOOK_BASE=https://ntfy.sh
NOTIFY_WEBHOOK_TOPIC=my-topic-name
# If your instance is private, authenticate with either a token or credentials
NOTIFY_WEBHOOK_TOKEN=tk_your-access-token
NOTIFY_WEBHOOK_USERNAME=your-username
NOTIFY_WEBHOOK_PASSWORD=your-passwordUse whichever your instance expects. Credentials are useful when ntfy sits behind a reverse proxy doing basic auth, and the token takes precedence if you set both.
Credentials can also be embedded in the base URL (like
NOTIFY_WEBHOOK_BASE=https://user:pass@ntfy.example.com), and will be sent as a
basic auth header.
Push notifications via Discord
Create a webhook in your Discord server (Server Settings, Integrations, Webhooks), then set:
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your-id/your-tokenMessages go to every channel you have configured, so ntfy, Discord and Apprise can all be used at the same time.
Push notifications via Apprise
Apprise delivers notifications to over 100 services (Telegram, email, Matrix, Pushover, etc), through a single self-hosted Apprise API server.
Point Domain Locker at your Apprise API instance, then tell it what to notify. That's either a config key you've saved on the server, or the Apprise URLs themselves:
APPRISE_API_URL=http://apprise:8000
# Either a config key stored in Apprise
APPRISE_KEY=domain-locker
# Or one or more Apprise URLs, separated by commas
APPRISE_URLS=tgram://bot-token/chat-id,mailto://user:pass@gmail.comThe key is used when both are set. By default only the untagged entries of a stored config are notified, so set APPRISE_TAG to target tagged ones, or to all for everything. If your instance sits behind basic auth, put the credentials in the URL, like http://user:pass@apprise:8000.
Expiration reminders
When a domain is soon to expire, you can get notified about it. This is handled by the /api/expiration-reminders endpoint, which needs to be periodically called via a cron job or similar.
You can customize how many days in advance you wanna be notified, by setting the DL_EXPIRATION_REMINDER_DAYS environment variable.
This defaults to 90, 30, 7 and 2 days before expiration, but you can change it to whatever you like.
For example:
DL_EXPIRATION_REMINDER_DAYS='60'- will notify you 2 months before expiration.DL_EXPIRATION_REMINDER_DAYS='30,14,7,3,1'- will notify you 30, 14, 7, 3 and 1 day before expiration.
Change notifications
When something important changes on one of your domains, you can get notified, if you'd like.
This is handled by the /api/domain-updater endpoint, which needs to be periodically called via a cron job or similar.
Choosing notification events
You can decide which change events you want to be notified about on a per-domain basis.
- Either do it individually, by editing each domain:
htt://[your-domain-locker]/domains/[my-domain]/edit
- Or, bulk update notification events all at once:
http://[your-domain-locker]/notifications/edit-events

Supported notification events
| Event Type | Description |
|---|---|
| Domain Expiration | Notifies you when a domain is about to expire, based on the configured reminder days. |
| IP Change | Notifies you when the IP address the domain points to changes. Note: If you use a firewall service like Cloudflare, this is NOT recommended, as the IP address will change frequently. |
| Registrar Change | Notifies you when the domain is transferred to a different registrar. |
| WHOIS Change | Notifies you when any WHOIS records change. |
| DNS Change | Notifies you when any DNS records are added, removed or amended. Note: If data fetching fails, this may trigger false positives. See troubleshooting below. |
| SSL Expiry | Notifies you when an SSL certificate is due to expire. Note: This is not recommended if you have auto-SSL, as the certificates have a short lifespan and are renewed automatically. |
| SSL Change | Notifies you when any attributes in an SSL certificate change. Note: This is not recommended if you have auto-SSL, as the certificates have a short lifespan and so will change frequently. |
| Host Change | Notifies you when the domain is moved to a different host. |
| Security Features Change | Notifies you when any security features on your domain are added, removed or amended. |
If you consistently get false notifications for a specific domain, you may want to disable change notifications for that domain specifically while keeping them enabled for others.
Enabling update crons
There's nothing to do here. The app checks for updates and expirations itself, on a timer, whichever database you're using. You can change how often with the DL_UPDATER_INTERVAL_MINUTES and DL_REMINDERS_INTERVAL_MINUTES env vars.
If you'd rather drive these yourself, set DL_DISABLE_SCHEDULER=true and call the endpoints from your own cron. For example, in your Docker Compose:
updater:
image: alpine:3.20
container_name: domain-locker-updater
restart: unless-stopped
depends_on:
- app
command: >
/bin/sh -c "
apk add --no-cache curl &&
echo '0 3 * * * /usr/bin/curl -s -X POST http://app:3000/api/domain-updater' > /etc/crontabs/root &&
echo '0 4 * * * /usr/bin/curl -s -X POST http://app:3000/api/expiration-reminders' >> /etc/crontabs/root &&
crond -f -L /dev/stdout
"