Use DynamicDNS to give your homelab services on your home internet connection a domain name

; Date: Sat Mar 15 2025

Tags: Self Hosting »»»»

A critical step to create a "homelab" is assigning a domain name to your home network connection. Dynamic DNS lets you do this even if your internet service provider changes your IP address from time to time.

The homelab idea is self-hosting services similar to the big-guy cloud services, but in your own home on your own hardware. For example, you might use NextCloud at home rather than Google Workspace, or use Gitea at home rather than GitHub.

Running a homelab means to run services on a computer in your home, making them available to the public Internet. As we all know, a domain name like git.example.com is human-friendly unlike an IP address like 94.23.54.128. That requires two things:

  • The services must be exposed to the Internet with router configuration,
  • and you must have domain names for your home internet connection.

The homelab journey starts by assigning A or AAAA records to the home.example.com domain name. The A and AAAA records must contain the IP address of your home internet connection.

The next step is that, for each service you're self-hosting at home, you add a CNAME record mapping service-name.example.com to home.example.com. With those DNS records you can access services hosted in your home from anywhere by using a domain name. See Homelab architecture, how to safely expose home-based services to the Internet

In this article we're focusing on the first step - how to assign the IP address of your home Internet connection to a domain name you control.

This task is easy if your internet service provider assigns you a static IP address. In such a case, the home IP address doesn't change. In the dashboard for your domain name registrar you add A and AAAA records for home.example.com, and then you're done. Some internet service providers let you assign a domain name like home.ISP-NAME.com to your home IP address. If that's the case you don't need to read the rest of this article, just read the next section, then go about the rest of your day.

But, most internet service providers do not offer a static IP address. Instead, they usually dynamically assign IP addresses as needed, where your IP address changes whenever the ISP chooses. For most people their public IP address is unimportant. But, a homelabber needs a way to dynamically update the DNS A record for their home.example.com domain name any time their public IP address changes.

The people who need to read this article are homelab folks whose ISP dynamically changes their IP address. What you'll find is a free method to dynamically update A/AAAA records in a domain name without using an external service. The solution is a tool, that can be hosted as a Docker image, that uses domain registrar APIs to update DNS records.

Using an ISP assigned static address or ISP DynDNS service

This section is useful if your ISP either gives you a fixed IP address, or has its own dynamic DNS service.

ISP-provided static IP address: In this case, you go to the service in which you configure DNS records for your domain. This could be your domain name service provider, or in my case it is a web hosting provider because the main domain is used for a website. In either case, you add a sub-domain like home.example.com giving it A and optionally AAAA records corresponding to the static IP address for your home internet connection.

ISP-provided dynamic DNS service: Your ISP might offer dynamic DNS on its own, meaning it offers a dynamically updated domain name corresponding to your home internet connection. That domain name will be like home.ISP-NAME.com. You could then go to your domain configuration and add a CNAME like home.example.com pointing to home.ISP-NAME.com.

Once you've taken one of these steps, you're good, and can proceed with assigning CNAMEs pointing to home.example.com or home.ISP-NAME.com for every service in your homelab. You will not need to read the rest of this article. Have a good day.

Typical Home network connected to the Internet

To understand this consider this diagram:

Typical home network

The typical home has a router (cable modem, DSL router, or the like) primarily used for outbound connections to services on the Internet.

The homelabber, however, wants to support inbound connections from the Internet to one or more machines on their home network. In this diagram, minipc1 is a small computer, running Linux, on which several services are running using Docker.

The router has a public IP address assigned by the internet service provider, whether statically or dynamically assigned. The router also manages IP address assignment to machines on the local network. Routers typically have a NAT gateway prevent access to home services from the public Internet, for cybersecurity. However, routers usually can be configured to direct traffic for certain port numbers to a local machine, such as minipc1.

The goal is accessing these services on the home network using domain names that resolve to this Internet connection. That requires configuring A and AAAA records for a DNS name like home.example.com. If/when the IP address changes the A/AAAA records must be updated.

Configuring DNS for your home network

We are discussing how to configure A and AAAA DNS records for home.example.com to support access to services on a home network. A records are used for IPv4 addresses, and AAAA records are used for IPv6 addresses.

The IP address assigned by your Internet Service Provider (ISP) is at least an IPv4 address, and may include an IPv6 address.

Assigning such DNS records causes requests/traffic for our that domain name will arrive at our kome Internet router. What happens beyond that - routing the traffic to the correct service process - is beyond the scope of this article. Instead this article focuses on the task of ensuring the home.example.com domain is dynamically updated with the IP address any time it changes.

The specifics of setting this up depend on whether your ISP dynamically assigns your IP address, and whether your DNS provider offers an API for updating DNS records.

Handling domain name assignment for dynamically assigned IP addresses requires:

  • Determining the IP address of your home internet connection
  • Updating the A record of a DNS entry when required

Dynamic DNS services

Several companies offer a DynDNS service. Useful search terms for finding these services are "Dynamic DNS" and "DDNS". I wrote about a free service, DuckDNS, in an earlier blog post: Remotely access your home network using free dynamic DNS service from DuckDNS.

Any DynDNS service hosts for you a domain name - such as davidhome.duckdns.org - and offers a way to update the A/AAAA records for that domain name. With DuckDNS, that involves running a CURL command every few minutes. Some DDNS services are paid, while others (like DuckDNS) are free.

What we identify in this article is a method to dynamically update DNS records with no dependency on a service. Instead it is self-hostable software using DNS registrar APIs to perform the update.

Automatically determine your external IP address

Run this command:

$ curl https://api64.ipify.org
83.123.42.142

At (www.ipify.org) ipify you'll find several ways to retrieve the public IP address from your home internet connection. The API endpoint shown here will return both IPv4 and IPv6 addresses.

This is the basis of creating a self-hosted dynamic DNS service. You can easily discover your IP address by using a simple command whose output is easy to consume with other software.

Command-line tools to update DNS A records

Now that we know how to automate discovering our external IP address, we need a simple automated method to update the A/AAAA records for your home.example.com domain.

Thankfully, most DNS providers have APIs for updating DNS records. While one could write a little program to deal with your DNS provider, there are multiple open source tools for this.

My DNS provider is Porkbun, so the following exploration is based on that provider. Your mileage may vary.

(ddclient.net) ddclient is an open source tool self-described as "updating dynamic DNS entries for accounts on a wide range of dynamic DNS services." While the documentation looks impressive, I was unable to get it working with my DNS provider (Porkbun). Another tool I found, ddupdate, also may be useful.

After some exploration, (github.com) dns-updater works excellently. It is both a command-line utility, as well as a Docker container, and it supports a long list of DDNS providers and DNS registrars. That includes Porkbun. My web hosting provider, Dreamhost, is also on their list, but I did not try that.

One can try it at the command line by downloading one of their zero-dependency binaries for Linux, Windows or MacOS.

Next you create a configuration file using the examples given in the project repository. For Porkbun, that file looks like so:

{
  "settings": [
    {
      "provider": "porkbun",
      "domain": "home.example.com",
      "api_key": "pk1_d9452....",
      "secret_api_key": "sk1_99ba37....",
      "ip_version": "ipv4",
      "ipv6_suffix": ""
    }
  ]
}

You get the API key by logging in to the Porkbun dashboard and navigating to the page for API Keys.

The API only works for domains where Porkbun is hosting the DNS records. For most of my domains, the DNS records are handled by my web hosting provider as part of their task of hosting my websites. What I did for this experiment is to reconfigure one of my domains to be handled by Porkbun rather than Dreamhost, which allowed the following to work. It also seems possible to configure dns-updater to work with Dreamhost (my web hosting provider).

At Porkbun, to get the API key, login to the dashboard, then in the Account menu select API Access. From that page you can generate an API key.

Using the downloaded binary, you can run this.

export CONFIG_FILEPATH=`pwd`/ddns.json
export PUBLICIP_HTTP_PROVIDERS=ipify
${HOME}/Downloads/ddns-updater_2.9.0_linux_386 ddns.txt

That is - pass two values using environment variables to the ddns-updater program. The syntax for that may be different for shells other than Bash.

When run, the script will print some log messages. If everything is setup right, one of those messages will say the ipv4 address of your chosen domain name will be set to the new IP address.

To make this a deployed service running in the background, use the Docker image at: (hub.docker.com) https://hub.docker.com/r/qmcgaw/ddns-updater

Create a directory wherever you place your docker containers, such as ${DOCKER_BASE}/docker/ddns-updater, and create a compose.yml containing this:

services:
  ddns-updater:
    image: qmcgaw/ddns-updater
    container_name: ddns-updater
    network_mode: bridge
    ports:
      - 8888:8000/tcp
    volumes:
      - ${DOCKER_BASE}/docker/ddns-updater/data:/updater/data
    environment:
      # - CONFIG=
      - PERIOD=5m
      - UPDATE_COOLDOWN_PERIOD=5m
      - PUBLICIP_FETCHERS=all
      - PUBLICIP_HTTP_PROVIDERS=all
      - PUBLICIPV4_HTTP_PROVIDERS=all
      - PUBLICIPV6_HTTP_PROVIDERS=all
      - PUBLICIP_DNS_PROVIDERS=all
      - PUBLICIP_DNS_TIMEOUT=3s
      - HTTP_TIMEOUT=10s

      # Web UI
      - LISTENING_ADDRESS=:8000
      - ROOT_URL=/

      # Backup
      - BACKUP_PERIOD=0 # 0 to disable
      - BACKUP_DIRECTORY=/updater/data

      # Other
      - LOG_LEVEL=info
      - LOG_CALLER=hidden
      # - SHOUTRRR_ADDRESSES=
    restart: always

This is directly from the sample docker-compose.yml in the project repository. You may want to adjust the environment variables.

Create a directory named data and make sure the volume mount above matches. The result must be that your data directory on the host maps to /updater/data inside the container. Create a file, /updater/data/config.json, containing the configuration as above.

The environment variables named like PUBLICIP_HTTP_PROVIDERS refer to a long list of providers like Ipify. See the Docker Hub page for the full list, as well as documentation for all the other environment variables.

Start it using: docker compose up -d

Follow with: docker compose logs -f

This way you'll see the logging output, and can detect if there are errors. If successful, you'll see data about what it's doing, including updating the IP address.

The last check is:

$ ping home.example.com
...

It will take some time for updates to the domain name to propagage. Once it is propagated the ping command will successfully resolve home.example.com to the IP address, and start pinging the public side of your router.

Summary

It had seemed daunting to me to implement, on my own, equivalent functionality to the dynamic DNS providers. There are COMPANIES providing commercial DDNS services. Surely, I thought, it's out of my league to do the same thing using a simple script running on my laptop.

Boy was I wrong.

With the above information, anyone who has Docker running on their computer can have a Dynamically updated DNS name assigned to that computer. It could be running within 10 minutes or so, and require nothing from any kind of 3rd party dynamic DNS service.

About the Author(s)

(davidherron.com) David Herron : David Herron is a writer and software engineer focusing on the wise use of technology. He is especially interested in clean energy technologies like solar power, wind power, and electric cars. David worked for nearly 30 years in Silicon Valley on software ranging from electronic mail systems, to video streaming, to the Java programming language, and has published several books on Node.js programming and electric vehicles.