We're going to assume you're running either macOS or a distribution of Linux/BSD for this tutorial. If you're using Windows then there are ways of getting a "Cron" system up and running, along with executing Bash scripts, but this tutorial won't cover that.

Explanation

Civo provides a full API to all of our services, including the DNS setup. So assuming you've pointed your domain name to our DNS servers, you just need to write a small script that will execute on a frequent basis to update our DNS API.

The script will take the following actions:

  1. Lookup via dig the current IP address of home.example.com.
  2. Get the current public IP address of your machine
  3. If the two differ, use our API to update the IP address of home.example.com

We then just need to add it to cron to be run "frequently" (how frequently is up to you, but we'll use hourly - most people's internet connections keep the same IP address for a long time, so it's just to cover router reboots or rare changes).

The script

The first step is to find out what IP address is currently configured for your hostname. Most *nix machines have dig available, so we'll use that but if not, a quick Google search should show you how to achieve the same result with nslookup (another very standard tool):

DNS_IP=$(dig +short home.example.com)

Next we have to get the current public IP address for your machine/home network. There are lots of ways of doing this, but one easy way is to use the dig tool we've already used:

PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)

Now it's a simple matter of if the two don't match up, send the updated IP to the Civo API. Let's put our API key (from the API documentation) in to another variable:

API_KEY=YOUR_TOKEN_HERE

Along with our domain name:

DOMAIN=example.com

In order to update a particular DNS record, we need to find out its ID first. From the DNS API documentation we can make a call to list the DNS domains within our account and then use the jq tool (available using apt-get install jq) to parse the JSON response and extract the ID we need. The jq part is a bit hairy, but you can read more about jq on their manual page.

DOMAIN_ID=$(curl -s -H "Authorization: bearer $API_KEY" https://api.civo.com/v2/dns | \
  jq -r ".[] | select(.name == \"$DOMAIN\") | .id")

If the DNS_IP and the PUBLIC_IP don't match we need to look if there's an existing domain record for this domain and if so delete it, then update with the new value:

if [ "$DNS_IP" != "$PUBLIC_IP" ]; then
  # Fetch the DNS Record ID for home.example.com
  RECORD_ID=$(curl -H "Authorization: bearer $API_KEY" \
    https://api.civo.com/v2/dns/$DOMAIN_ID/records | \
    jq -r ".[] | select(.name == \"home\") | .id")

  # If an ID was returned, then a record exists and we need to delete it
  if [[ !  -z  $RECORD_ID  ]]; then
    curl -s -X DELETE -H "Authorization: bearer $API_KEY" \
      https://api.civo.com/v2/dns/$DOMAIN_ID/records/$RECORD_ID
  fi

  # Now either way, we can add the new DNS record pointing to $PUBLIC_IP
  curl -s -H "Authorization: bearer $API_KEY" \
    https://api.civo.com/v2/dns/$DOMAIN_ID/records \
    -d name=home -d value=$PUBLIC_IP -d type=a
fi

Now, we've walked through it with snippets, we're ready to combine all of these into a single script:

#!/bin/bash

# Remember to update this with your REAL API key
API_KEY=YOUR_TOKEN_HERE
# And update this with your real domain name
DOMAIN=example.com

DNS_IP=$(dig +short home.$DOMAIN @ns0.civo.com)
PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)

DOMAIN_ID=$(curl -s -H "Authorization: bearer $API_KEY" https://api.civo.com/v2/dns | \
  jq -r ".[] | select(.name == \"$DOMAIN\") | .id")

if [ "$DNS_IP" != "$PUBLIC_IP" ]; then
  RECORD_ID=$(curl -s -H "Authorization: bearer $API_KEY" \
    https://api.civo.com/v2/dns/$DOMAIN_ID/records | \
    jq -r ".[] | select(.name == \"home\") | .id")
  if [[ !  -z  $RECORD_ID  ]]; then
    curl -s -X DELETE -H "Authorization: bearer $API_KEY" \
      https://api.civo.com/v2/dns/$DOMAIN_ID/records/$RECORD_ID
  fi
  curl -s -H "Authorization: bearer $API_KEY" \
    https://api.civo.com/v2/dns/$DOMAIN_ID/records \
    -d name=home -d value=$PUBLIC_IP -d type=a
fi

Now you need to save this script somewhere sensible like /usr/local/bin/civo-dynamic-dns.sh, make it executable with chmod +x /usr/local/bin/civo-dynamic-dns.sh and then add it to crontab using crontab -e and adding a line like this:

0 * * * * /usr/local/bin/civo-dynamic-dns.sh

Which will update your IP address on the hour every hour (if it's changed).

This is just one example of something you can easily achieve with our fully featured API, why not go and have a play...