Blog Home

A Real Website

April 21, 2025

Now that I had something to host (Grafana with metrics for my server), I wanted to have a real web address where anyone could access it. I looked at a few different web domain lease platforms, but ultimately recognized Cloudflare as the best choice because of their great offering of services for DNS routing as well as the wide array of protections for DOS attacks and similar. I purchased jamesmassucco.com for $20/yr.

Before allowing traffic to route to my server, I wanted to make sure I understood the security implications, and wanted to ensure that I did everything I could to keep it secure and not put my home network at risk of hacking. I found a great Reddit comment with a lot of the details I needed. The basic steps were:

  1. Tell Cloudflare to route traffic to your website to your public home IP address
  2. Tell Cloudflare to proxy your IP address, so that anyone accessing your site doesn't see your actual home IP address
  3. Tell your server to ONLY accept traffic from Cloudlfare IP addresses

To accomplish points 1 and 2, I configured them via Cloudflare's website. I also realized that my home IP address could change, so I added cloudflare-ddns to my setup - this tool automatically checks your public IP address on a regular cadence and then uses a Cloudlfare API token you provide it to tell Cloudflare your new IP address if it has changed.

To accomplish point 3, I needed a reverse proxy. A reverse proxy is a lot like a router, in that it directs traffic in both directions based on specific allowed/known routes. A reverse proxy can be configured to receive all the traffic hitting your server, and then direct (or block) that traffic to internal services (e.g. Grafana, your website, etc.). I had heard of nginx before but decided that traefik seemed simpler and better suited for my basic use case. With the help of ChatGPT (yes, I get a lot of help from ChatGPT), I set up a basic docker-compose for traefik and told it to only accept traffic from the Cloudflare IP addresses. Since I wanted to be extra, I also wrote a script that would read the Cloudflare IP addresses using curl and then write them to an .env file used by traefik so that if they ever change (which they almost never do), I could easily update them. Automation for the sake of automation? Probably.

Once I had traefik set up, I added labels to the docker-compose entry for Grafana that enabled it as a routable service for traefik and then registered traefik routers for http and https traffic to Grafana. I originally only did https, but couldn't get that to work and during debug found that if I added an http router as well, it would work... I didn't figure out yet why that's required, so for now I just left it in. I registered a sub-domain (grafana.jamesmassucco.com) in Cloudflare and used that as the router source for Grafana traffic, and boom - grafana.jamesmassucco.com was live!

Note on Docker Deployments

At this point, I decided I had too much going on to just have a single docker-compose.yml file, so I decided to a bit of housekeeping organization. I setup a networking/ directory for traefik and cloudflare-ddns, and a monitoring/ directory for Grafana and Prometheus. Each directory got a separate docker-compose.yml file and it's own start.sh script. The start script is really a "restart" script, because it does the following things:

  1. Change to current director (cd "$(dirname "$0")")
  2. Shut down containers (sudo docker compose down)
  3. Update container images from the docker repo (sudo docker compose pull)
  4. Start up containers (sudo docker compose up -d)

The docker compose command only looks at containers managed by the local docker-compose.yml file, so by having separate start.sh scripts in each directory, I can separately restart the services relevant to that aspect of the server. I also set up a top-level start_all.sh that just calls each of the start.sh scripts from the subdirectories, so I can easily redeploy all of the services if needed.

Next up is a deeper dive into security to make triple sure I'm doing everything I can to prevent getting hacked!