Dynamic DNS with Cloudflare and curl
I have a homelab (a.k.a. a bunch of servers at home).
My internet plan gets me a sticky dynamic IP address (hey, at least it's IPv4). Dynamic IP addressing is great for ISPs, but us homelabbers hate it, because it means our uptime, depends on users, and their configured DNS servers.
There are some services I want to host, but due to their nature, I can't justify the cost of running them on the cloud. They don't require excellent uptime, so hosting them at home, makes sense.
That means: I have to set up dynamic DNS!
My DNS provider for bejarano.io is Cloudflare. I want my services to be available at service.bejarano.io, so I need to setup dynamic DNS with Cloudflare.
Fortunately, Cloudflare offers a great API for it's users, so updating an existing record is a simple HTTP request.
I wrote a simple
bash script with
curl that regurarly checks my public IP address with canihazip.com, and, if it changed, sends and authenticated
HTTP PUT request to Cloudflare and updates the record.
The script is available on GitHub Gist.
Bonus: running it on Docker
One of the servers in my homelab runs a Docker Swarm. Swarm is great because I can write out my stack's configuration in a single Compose file (see Infrastructure as Code) and deploy to a well-known environment.
I run Swarm single-node, you can run multi-node swarms, but for multi-node deployments check out Kubernetes.
To run this script I needed a Docker image with
curl, therefore, three options:
Instead of building an image just with
curl, what I ended up doing is using the
alpine image (which includes
curl during runtime and running the script after that.
The stack file
I run one service per sub-domain, which may sound crazy but this image runs on just 3MB of memory and I'll probably never have more than 10-15 DNS'd services ever.
command: sh -c 'apk add curl; sh /ddns.sh'