Sentinel is a lightweight service that automatically updates DNS records when Docker Swarm leadership changes. It ensures high availability by pointing your domain to the current Swarm leader.
- 🔄 Automatic DNS failover for Docker Swarm clusters
- 🔍 Real-time monitoring of Swarm leader changes
- 🌐 DNS record updates via INWX API
- 🔒 Secure and lightweight (built on scratch container)
- 🚀 Easy to deploy and configure
Sentinel runs on each manager node in your Docker Swarm cluster. It:
- Monitors Docker Swarm events for leadership changes
- Updates the DNS record to point to the leader node's IP when changes occur
This project is designed for low-budget environments where virtual IPs are unavailable or when you want to avoid dependencies on third-party load balancers.
Failover time depends on your DNS record TTL, making this solution less suitable for applications requiring zero downtime.
Currently, only INWX is supported.
Feel free to create a pull request to add more providers.
- Docker Swarm cluster with at least one manager node
- INWX account with API access
- ID of the DNS record you want to manage
- Create a Docker secret for the INWX password
echo "mySecurePassword123" | docker secret create inwx_password -
- Copy the docker-compose.yml file and adjust it to your needs
- Deploy as a stack to your Swarm cluster:
docker stack deploy -c docker-compose.yml sentinel
Environment Variable | Description | Default |
---|---|---|
SENTINEL_DOMAIN |
Domain name | example.com |
SENTINEL_RECORD |
Record name (subdomain) | lb |
SENTINEL_INWX_USER |
INWX username | required |
SENTINEL_INWX_PASSWORD |
INWX password | required, if docker secret "inwx_password" not set |
SENTINEL_INWX_RECORD_ID |
ID of the DNS record to update | required |
SENTINEL_LOG_LEVEL |
Logging level (DEBUG, INFO, ERROR) | INFO |
Sentinel can read the public IP address of each node from a Docker Swarm node label. Run the following command on each node to set the "public_ip" label:
PUBLIC_IP=$(curl -s https://api.ipify.org) \
NODE_ID=$(docker info --format '{{.Swarm.NodeID}}') ; \
docker node update --label-add public_ip=$PUBLIC_IP $NODE_ID
To verify that the label was set correctly, run:
docker node inspect $NODE_ID --format '{{ index .Spec.Labels "public_ip" }}'
# Copy and adjust to fit your setup
cp .env.dist .env
# Start development environment
make dev
# View logs
make dev-logs
# Start in detached mode
make dev-detach
# Clean up
make clean
# Build Docker image
make build
Sentinel is built with Go and designed to be lightweight and reliable:
- Zero dependencies: Built on scratch container
- Minimal footprint: Small binary size and memory usage
- Resilient: Automatically reconnects if Docker API connection is lost
- Secure: No shell or unnecessary components in the container
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.