Configuring a Custom Domain with Cloudflare

Configuring a Custom Domain with Cloudflare

Deploying a website and making it available through a custom domain are two related but separate problems.

My portfolio was already deploying successfully, but I wanted visitors to reach it through dustinjones.dev instead of the default hosting URL. Configuring that required connecting the domain, DNS provider, hosting platform, and HTTPS configuration correctly.

What initially appeared to be a simple domain change became a useful exercise in understanding the infrastructure behind a web request.

Context

The portfolio is an Astro static site stored in GitHub and deployed through GitHub Pages.

After migrating the site to Astro, the generated site was successfully available through the GitHub Pages address:

https://dustinljones.github.io/

However, visiting my custom domain:

https://dustinjones.dev

returned a 404.

That was an important clue.

The application itself was building successfully, and GitHub Pages was capable of serving it. The problem not inside the Astro application. The failure existed somewhere between the custom domain and the hosting platform.

Cloudflare was already managing DNS for dustinjones.dev, so the task became configuring the request path correctly between Cloudflare and GitHub Pages.

Requirements

The domain configuration needed to satisfy several requirements:

The DNS configuration also needed to remain separate from the application itself. Updating site content should be an application deployment concern, while routing the domain should remain an infrastructure concern.

Goals

The immediate goal was straightforward:

https://dustinjones.dev

should serve the same portfolio that was already available through GitHub Pages.

The larger goal was to better understand how the pieces involved in public web hosting fit together.

Instead of treating DNS configuration as a set of values to copy into a dashboard, I wanted to understand the path a request takes from the browser to the deployed site.

Conceptually, the request flow looks like this:

Browser
   |
   v
dustinjones.dev
   |
   v
DNS Resolution
   |
   v
Cloudflare
   |
   v
GitHub Pages
   |
   v
Generated Astro Site

Each layer is responsible for something different, and a failure at any one of them can prevent the domain from working.

Approach

I started by isolating the parts of the deployment that were already functioning.

Since the GitHub Pages URL loaded successfully, I knew several things were already working:

I then focused on the custom-domain configuration.

The process involved verifying three separate areas:

This became the general troubleshooting model for the configuration:

Does the deployment URL work?
        |
       Yes
        |
        v
Does DNS resolve correctly?
        |
       Yes
        |
        v
Does the hosting platform recognize the hostname?
        |
       Yes
        |
        v
Does HTTPS work?

Breaking the problem into layers made it considerably easier to identify where a failure was occurring.

Key Implementation Detail

The most important part of the configuration was understanding the relationship between DNS records and the custom-domain setting in GitHub Pages.

DNS answers a question similar to:

Where should requests for dustinjones.dev go?

GitHub Pages answers a different question:

Do I have a site configured to respond to dustinjones.dev?

Both sides need to agree.

Configuring DNS alone is not sufficient if the hosting platform does not recognize the hostname. Likewise, configuring the custom domain inside GitHub Pages does not help if DNS never directs requests toward GitHub’s infrastructure.

Challenges

The main challenge was that the visible symptom initially looked like an application failure.

A browser displayed a 404, so it would have been reasonable to assume that Astro had generated an incorrect route.

However, the default GitHub Pages URL continued to work.

That meant the same deployed files behaved differently depending on the hostname used to reach them.

The issue was therefore outside the normal application routing path.

This highlighted an important debugging technique: compare working and failing paths and identify where they diverge.

In this case:

Working:
Browser -> github.io -> GitHub Pages -> Astro Site

Failing:
Browser -> dustinjones.dev -> Cloudflare -> ? -> 404

The divergence happened before the application was served.

Another challenge was that several systems expose settings related to domains and HTTPS.

Cloudflare has DNS and SSL settings. GitHub Pages has custom-domain and HTTPS configuration. The browser ultimately evaluates the TLS certificate it receives.

It is easy to think of these as one configuration, but they are separate systems participating in the same request.

Tradeoffs and Decisions

One decision was to keep GitHub Pages as the hosting platform rather than moving the site simply because the custom-domain configuration required troubleshooting.

The deployment itself was already working, so changing hosting providers would have replaced a relatively narrow DNS problem with an entirely new deployment configuration.

I preferred to solve the actual problem rather than change architecture around it.

I also chose to keep Cloudflare as the DNS provider.

Technically, the domain could be managed elsewhere, but Cloudflare gives me a single place to manage DNS and leaves room for additional edge features later.

The tradeoff is that adding Cloudflare introduces another layer into the request path.

That means troubleshooting requires understanding whether a problem originates from:

The additional layer is worthwhile, but only if I understand what responsibility it owns.

Result

The final result was that the portfolio became available through:

https://dustinjones.dev

while continuing to use GitHub Pages as the hosting platform.

The final architecture remained relatively simple:

GitHub Repository
       |
       v
Astro Build
       |
       v
GitHub Pages
       ^
       |
Cloudflare DNS
       ^
       |
dustinjones.dev
       ^
       |
    Browser

This configuration also means that application deployments and domain configuration are largely independent.

When I update the portfolio, GitHub Pages receives a new version of the generated site. The domain continues pointing to the same hosting infrastructure, so normal content deployments do not require DNS changes.

What I Learned

The biggest lesson was that a deployed application and a working domain are not the same thing.

Before this issue, it was easy to mentally group deployment, DNS, and HTTPS together as one process. They are better understood as separate layers.

The application has to build correctly.

The hosting platform has to serve the application.

DNS has to direct the hostname toward the hosting infrastructure.

The hosting provider has to associate the incoming hostname with the correct deployment.

HTTPS then has to establish trust for that hostname.

A failure at any one layer can make the entire site appear unavailable.