Goatcounter and the Pursuit of Geocities Nostalgia - Part 2

Now it is 2022. 25 years later. (We won’t talk about those 25 years, I think that might end up as a novel/memoir/you-talk-too-much-Rio book.) I am finally back online on this very website. What is the first thing I want? A WEBCOUNTER. Yes, tell me how many people have seen rio.pink! And tell everyone else who comes to the page, no secrets here! So cool!

I did some half-hearted searches of Github. This thing should be pretty simple right? Scrape an access log from your server, display it on the page, and you’re good to go. I found some class projects and really simple implementations of this basic idea. I could write this myself as a bash script and save a bit of my dignity.

The question was, were there any other ways to collect the data? The log scraping would definitely work but I wanted to see what else was out there. My search led me to GoatCounter.

Some cool features! It has a pretty dashboard and everything!

Privacy and data collection is a big deal to me. Once again, that is a whole nother blog post and/or book, but lets just say if I tell you something about myself please don’t turn around and sell it without telling me.

The GDPR saga is pretty interesting to me. How companies have reacted to the new privacy laws in the EU, the endless cookie acceptance pop-ups, and more. The GoatCounter website has a bit more info on how it applies to them here.

It’s not 100% clear that Goatcounter is compliant, but it sure as hell isnt Google Analytics. No cookies are kept. A hash identifies the client but does not store any data. The salt is rotated every 4 hours and is deleted permanently after 8. So far, so good.

Now, here is where I get a bit ambivalent. There are two versions of GoatCounter. One is hosted by GoatCounter themselves. The other is a self-hosted service. Me, being the “let’s pick the hard one for fun, I wanna do it myself, it will be all mine and you cant have it :P” sort of person went for self-hosted. Of course, that tends to be a bit more complex. The documentation for the self-hosted variant is a bit…vague. The README file on Github has some info but not enough to really help you get it set up.

The documentation on the website itself does not mention self-hosting much at all. The Getting Started page really only contains the code to copy onto the page to be counted and a few integrations with other frontends. For the rest of the docs: a few extended features and use cases are there, but it assumes a lot of prior knowledge (about Javascript, APIs, DNS, HTTP headers, URL queries, and more). For the most part, they tried to make it really really easy to help non-technical people switch from Google Analytics, but it’s easy until it’s not. This is not a judgement in any way, Goatcounter is beautiful and simple, and user docs are one of the hardest parts of making software. It would be so easy to make the non-self-hosted version a paid service, but they didn’t. The developers should absolutely be lauded for Goatcounter, and if you end up using it I encourage you to donate as I plan to.

So here was my plan:

  • get Goatcounter set up on a subdomain as a virtual host of rio.pink.
  • somehow get only the pageview data (literally just an integer) and incorporate it into my page.
  • Turn this integer into one of the cool old-school Geocities counters in a lovely shade of pink.

OK so here we go.

Part 1 - Set Up Goatcounter

This site seemed much more helpful than the Github README (but they linked to it!) and applied directly to my situation. But…it’s just a script. They wrote a script for you to run that would “do everything” (that should set off alarm bells in your head, see my last post and my issues with python-archinstall for a cautionary tale).

I looked at the script first. (ALWAYS LOOK AT A RANDOM SCRIPT BEFORE RUNNING IT OMG IT MIGHT HURT YOUR LIL COMPUTER, PROTECT HER)

It looked ok. Download the latest release, supply a subdomain for the goat and a login for the web interface, create the goat user and group, install, set up db, get the systemd service setup, that’s that. No funny business, but it seemed…too easy. How does it know which web server software you are using? Apache uses virtual hosts, how does it set those up? How does it deal with SSL certs? OK, maybe the goatcounter release itself does that. (creepy foreshadowing music plays)

Of course it didn’t work. I got some gnarly errors which I don’t remember offhand and am not looking up because writing this is taking way too long already. Did some more internet research and found this.

OK, now we’re talking. This tutorial is using Apache, which is what I use. Good sign…there is info on how things actually work…really good sign…the commands you need are explained clearly…looking better and better.

Here’s where it all went to hell, but this is totally my fault. I had tried to set up virtual hosts before for a few other failed projects…my config files were embarrassingly messy. A graveyard of commented-out attempts at trying to make things work, spread across multiple files and directories. Yikes. In any case, I followed the tutorial and added the code below to my httpd.conf (obviously example.com was customized):

ServerName stats.example.com
ServerAlias www.stats.example.com

ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/

ErrorLog /var/log/httpd/stats.example.com-error.log
CustomLog /var/log/httpd/stats.example.com-access.log combined

Lo and behold, the goatcounter dashboard loaded on the first try. Hallelujah!

OK but no stats…I need to tell it which site to grab pageviews from. Goatcounter itself very helpfully gives you the code to add to your site. When the special person who finds their way to rio.pink loads the page, it will tell goatcounter they are there by loading a script…from the goatcounter subdomain, which is on a weird port (5000). The ProxyPass config value above…is using an http url. If you have ever gone to a webpage that only supports HTTP, you might see something like this:

a screenshot from Firefox with the warning: \"HTTPS-Only Mode Alert. Secure Site Not Available. You\’ve enabled HTTPS-Only Mode for enhanced security, and a HTTPS version of www.towelday.org is not available. What could be causing this? Most likely, the website simply does not support HTTPS. It\’s also possible that an attacker is involved. If you decide to visit the website, you should not enter any sensitive information like passwords, emails, or credit card details. If you continue, HTTPS-Only Mode will be turned off temporarily for this site.\" There are buttons underneath to \"Continue to HTTP site\" or \"Go Back\"

There’s something wrong with the SSL certificate that the page is supposed to have. It’s not secure. Bad things could happen. Your browser only wants to protect you, can you blame it?

Here we go again, commence troubleshooting.

As directed, I had added the following code to rio.pink/index.html.

<script data-goatcounter="https://goat.rio.pink:5000/count"
        async src="//goat.rio.pink:5000/count.js"></script>

I loaded the page, eagerly looked at the dashboard: no views. :(

I went back to rio.pink and hit F12 for developer tools. In the console tab I saw the error. It was trying to load this count.js file and…something was wrong with the cert? Once again it would be a pain to give you the actual error because I didn’t have “persist logs” on in Firefox developer tools. Believe me though, this was a certificate thing.

I think this is getting way way way too long. Let me sum up what happened: I currently had a cert from ZeroSSL. It was not a wildcard cert (*.rio.pink) so this goat subdomain didn’t get a cert assigned. I tried to use Let’s Encrypt’s free certs and their certbot tool to make it right. All those f***ed up config files I mentioned gave me hell, I spent many hours tweaking virtual host settings to try and get this right. Certbot made its own config files specific to Apache, adding to the confusion. The mod_proxy Apache module (remember ProxyPass?) wanted its own special treatment. In the end I got it working, the counter went up when I visited the site. YAY! The next part should be easy, right?

Part 2 - Make rio.pink show pageviews to the visitor

So, Goatcounter has a way to display your view count on the specified page. ( This is where the docs started to get…less helpful.) The first part tells you what to add to integrate JavaScript:

<script>
    // Append to the <body>; can use a CSS selector to append somewhere else.
    window.goatcounter.visit_count({append: 'body'})
</script>
<script data-goatcounter="https://MYCODE.goatcounter.com/count"
        async src="//gc.zgo.at/count.js"></script>

But then it says:

You want to make sure the count.js script is loaded before calling this; for example:

<script>
    var t = setInterval(function() {
        if (window.goatcounter && window.goatcounter.visit_count) {
            clearInterval(t)
            window.goatcounter.visit_count({append: 'body'})
        }
    }, 100)
</script>
<script data-goatcounter="https://MYCODE.goatcounter.com/count"
        async src="//gc.zgo.at/count.js"></script>

OK so the last part is identical. I guess I don’t copy that. Looking at the code, I guess I need everything surrounding window.goatcounter.visit_count({append: 'body'}), including the var declaration and the included if statement, etc. So wait, I don’t use the first code snippet at all? Or I have to copy the second one in before the first? If I didn’t really understand what was going on with this code (read: non-technical user), I would be pretty confused. Why show the first snippet?

Then it says “You can also remove the async attribute”. Wait, why would I want to do that? What does it mean? What will it do?

We see a little example of the counter:

a rectangular image with a purple border and text that says “Views for this page - 794 - stats by Goatcounter”

Um…not quite my style, but all we want is the number anyway right?

After this we are given options to pass to the goatcounter.visit_count() function. This all made sense to me somewhat, and though I am not a CSS pro I knew enough to add everything to the style option. I never did figure out how to get attr to work, there are no examples anywhere.

(…here is the embarrassing bit. After reading about the other ways to display a view counter, I scrolled down, saw “Direct URLs”, skimmed it, and realized that wasn’t what I wanted. Below that was “JSON”. I assumed this was not what I wanted, and didn’t even read it.

It was exactly what I wanted.)

ANYWAY let’s pretend that part doesn’t exist, so I don’t have to regret spending so many hours trying to get the HTML graphic thingy to work. :(

…Here is what I ended up with for the style tag:

                              iframe {
                                 background-color: #000;
                              }
                              #gcvc-for {                               
                                 font-size: 0px;
                              } 
                              #gcvc-views {
                                 font-size: 15px;
                                 width: 100%;
                              }
                              div { 
                                 text-align: left;
                                 font-weight: normal;                                 
                                 line-height: 0.5;
                                 width: 100%; 
                                 height: 40px; 
                                 border-style: none; 
                                 background-color: #C3766C; 
                                 color: #F9E5E4; 
                                 font-family: monospace; 
                                 font-size: 25px; 
                                 border-style: none;
                              }
                              body { 
                                 background-color: #C3766C;
                                 width: 240px; 
                              }
                        'width: '50', height: '40''

I am not a fan of CSS. I would consider it an actual nightmare, in fact. The position of “frontend developer” ranks slightly below “sewage processing plant technician” on my desired job list. Because of CSS. To get the code above I hacked and hacked and hacked, and it’s still not quite what I want.

Anyway I’m assuming you got here through the index page, so you might have seen my little redesign. I moved some stuff around, including adding the social media links on the right side of the main block and some other tweaks. I also found this cute font on Nerd Fonts called Monofur, it looks right on my browser but I’m not sure if it works for anyone else.

TA-DA!

Part 3 is going to be using that view count number to make a Geocities-style counter. Unfortunately that CSS headache from above is for naught because I’m just going to use this JSON thing. Keep an eye on the homepage, soon you may see something like this:

A counter with the number 046372. Each digit is in a yellow star

(The above image is from Dokodemo: a small rectangular icon that says DOKODEMO in rainbow colors with a laughing white cat which is my current 90s web inspiration and nostalgia fix.)

blogbit~

2022-07-31

pinkblog



what a time to be alive

since 7/30/22, there have been this many visitors: