Site is (Finally!) Operational!

Published by Jeremy on 2022-06-29

So, this is (hopefully) the one time I'm going to talk about the guts of this site. Odds are most people reading this won't care, but in case you do this post is for you! And if you already understand the concepts I'm describing, jump to the bottom where all the interesting stuff starts.


For those who are old enough, think of DNS as a phone book (or for the young 'uns, your contacts app). A URL like is like a name- while it does describe the person you want to 'call', you can't use it alone. You need a phone number. The phone book (or contacts app) exists to match the name to that number, so you can actually contact them. That's what DNS is- it's a network of servers which turn your URL into an actual IP address (which is the phone number in this case).

Anyways, I chose Cloudflare because it is fast, free, and provides excellent security. Their free plan exists actually to create a symbiotic relationship- it's actually a very interesting business model. You can read more about it here.

Domain Registrars

So, we have our phone book- whenever someone trys to access the site, the DNS will redirect them to us. But, how did we get our site into the phone book? We need to purchase a URL from a Domain Name Registrar, who then buys our URL from ICANN, the Internet Corporation for Assigned Names and Numbers. I went with Cloudflare, because:

  • I was already going to use Cloudflare for DNS, so this is the easiest option.
  • They aren't predatory like GoDaddy. GoDaddy is seriously awful.
  • Google has had pretty high URL costs, but they were otherwise pretty good. Unfortunately, they have now sold their Domains service to Squarespace, so that's not an option.
  • Cloudflare will sell you a URL for exactly what it costs them to purchase it. My URL was ~5 dollars per year, so pretty cheap! Again, Cloudflare provides free or at cost services to individuals and small businesses because they actually gain value from having more sites work with them.


So, now we have our address in a phone book- if you know our name, you can get our phone number. So now we need to put a telephone on the other end, otherwise you'll get nothing when you call us.
Remember, when the user inputs our URL, their DNS looks up our details, and sends them to our IP. Now we have to provide them with a website on the other end. To do this, I am running a little web server that runs a static site. Whenever you go here, your browser gets given the exact same files as any other user. My web server, in this case nginx, serves the same files to all users because it's static- there is only one (unchanging) set of files.

So that's a very oversimplified explanation of how my tiny little site works!

Technical Details

Alright, here's the meaty bits:

  • The static site is generated by Zola, running locally on my machine or on my server
  • The server storing the static files is a QNAP TS-451+ NAS, which is also running nginx. More about this in a minute
  • The QNAP NAS runs nginx in docker, and nginx hosts my static site.
  • Cloudflare is my registrar, DNS, and proxy

Things weren't exactly smooth sailing though... nginx had a few problems. So I downloaded the nginx image from docker hub, and ran it in docker. I started with this command:

docker run --name nethost -d -p 8008:80 -v ~/zola_site/public:/usr/share/nginx/html:ro nginx

But then when I started this up, it threw a 403 at me. A friend (who knows much more about working with unix) was helping me threw it, and we tried a few things. The first one that threw us off track was the permissions. They initially were:

[user@QNAP-4 zola_site]$ ls -la public
-rw-rw----  1   user everyone 12866 2023-06-28 12:20 config.toml
drwxrwx---  7   user everyone  4096 2023-06-28 11:12 content
-rw-rw----  1   user everyone  5129 2023-06-28 11:12 package.json
drwxrwx--- 21   user everyone  4096 2023-06-28 12:24 public
[user@QNAP-4 zola_site]$

So as you see, I am currently owner of these files. I later learned that the problem was that nginx wasn't owner of these files, even though they were shared with nginx, and I even entered the container's command line and verified nginx could access them.
When the docker container was created, nginx was created as user 101 in group 101. All it took to get nginx working was a little bit of a

sudo chown -R 101:everyone ~/zola_site/public

(The 101:everyone is so that nginx retains ownership, but that I can also edit the files on my windows machine over the network)
Now, this solved the problem! But now I just need to make sure I run that command whenever I update the static site files with new ones.... Otherwise nginx will just throw a 403 at all visitors.