<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>simonh.uk - web</title><link href="https://simonh.uk/" rel="alternate"></link><link href="https://simonh.uk/feeds/web.atom.xml" rel="self"></link><id>https://simonh.uk/</id><updated>2025-02-07T00:00:00+00:00</updated><subtitle>Simon Harrison :: Burton on Trent :: UK</subtitle><entry><title>Topic Time Vampires</title><link href="https://simonh.uk/2025/02/07/topic-time-vampires/" rel="alternate"></link><published>2025-02-07T00:00:00+00:00</published><updated>2025-02-07T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2025-02-07:/2025/02/07/topic-time-vampires/</id><summary type="html">	&lt;p&gt;Wait! Subscribe now so you never miss a post.&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Time vampires" src="/img/2025-02-07/vampire.webp" title="Time vampires" /&gt;&lt;/p&gt;

	&lt;p&gt;There is a problem that web surfers have always had to deal with but has become even more pervasive. The &lt;em&gt;topic time vampires&lt;/em&gt; I call them. &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s for short. I&amp;#8217;ve recently discovered that the topic of photography has enticed many of them away from whatever they were wasting peoples time with previously.&lt;/p&gt;

	&lt;h2&gt;What is a &lt;span class="caps"&gt;TTV&lt;/span&gt;?&lt;/h2&gt;

	&lt;p&gt;They are Youtubers / bloggers who are trying to build or grow their &lt;em&gt;niche&lt;/em&gt;. They target keywords / phrases that web surfers are typing (or speaking) in to search engines and hope we will land on their site or channel. Their aim is not to give useful or original information, it&amp;#8217;s to convince you they&amp;#8217;re an expert. Very rarely will you encounter an expert. Most of them are imposters. Imitators. They just copy / rehash each others content. Or worse, steal other peoples content and pass it off as there own.&lt;/p&gt;

	&lt;h2&gt;A History Lesson&lt;/h2&gt;

	&lt;p&gt;&lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s were rampant back in the mid to late 2000&amp;#8217;s especially in the &amp;#8220;make money online&amp;#8221; niche (as they called it). Man, I wasted hours, going round in circles. &lt;strong&gt;Everyone&lt;/strong&gt; pretended they were an expert. Everyone had a link to an affiliate program that would teach you &amp;#8220;all the secrets&amp;#8221;. They would do whatever they could to waste as much of your time &lt;em&gt;on purpose&lt;/em&gt;. Really. You see, back then (not sure about today), the search engines rewarded pages that kept a visitor reading. It was in the &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s interest to waffle on for screenfuls of content, while actually writing &lt;strong&gt;nothing&lt;/strong&gt; of any value. All that was required was to pepper the article with the keywords and boom, they&amp;#8217;d climb a bit higher towards the coveted number one spot. &lt;/p&gt;

	&lt;h2&gt;Enter the &amp;#8220;Influencers&amp;#8221;&lt;/h2&gt;

	&lt;p&gt;Since the web has shifted from static pages of text based results to multimedia content, chasing the top spot on any particular search engine is no longer enough. The &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s potentially lucrative audience could be one of the many intranets: Instagram, Facebook etc. Or, the searcher might prefer to watch a video instead of reading an article. So now the &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s must have a presence on every platform. Or at least all the big ones. &lt;/p&gt;

	&lt;h2&gt;How to Detect a &lt;span class="caps"&gt;TTV&lt;/span&gt;?&lt;/h2&gt;

	&lt;p&gt;If it&amp;#8217;s a website, popups (of any kind)&lt;sup class="footnote" id="fnrev6bfde009a8774a968c0c434f386b414d-1"&gt;&lt;a href="#fn6bfde009a8774a968c0c434f386b414d-1"&gt;1&lt;/a&gt;&lt;/sup&gt; should usually be enough to encourage usage of your browsers &lt;em&gt;back&lt;/em&gt; button. Youtubers who have sponsored videos and pester you to &amp;#8220;click that subscribe button&amp;#8221; should set off alarm bells. If in doubt, watch or read a couple of their offerings and ask yourself, &amp;#8220;did I get what the title suggested?&amp;#8221;&lt;/p&gt;

	&lt;h2&gt;They&amp;#8217;re Just Trying to Make a Living!&lt;/h2&gt;

	&lt;p&gt;I know some people will object to my characterising all these people as &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s, but as the old saying goes &amp;#8220;if it walks like a duck&amp;#8230;&amp;#8221;. I mean seriously, how many Youtubers do we &lt;em&gt;need&lt;/em&gt; to be making photography vids? &lt;/p&gt;

	&lt;h2&gt;Find the Source(s)&lt;/h2&gt;

	&lt;p&gt;Searching for &amp;#8220;take better photos&amp;#8221; on Youtube returns the following result on the first &amp;#8220;page&amp;#8221;:&lt;/p&gt;

	&lt;p&gt;5 Ways To Take Better Photos&amp;#8230; (2022)&lt;/p&gt;

	&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=GZ8nnbdmihA"&gt;&lt;img alt="" src="/img/2025-02-07/five-yt.webp" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;The source:&lt;/p&gt;

	&lt;p&gt;Photo Tip: Five for Five (2011)&lt;/p&gt;

	&lt;p&gt;&lt;a href="https://www.dpreview.com/articles/8366339635/photo-tip-five-for-five"&gt;&lt;img alt="" src="/img/2025-02-07/five-web.webp" /&gt;&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;This of course may not be the source, but I&amp;#8217;m sure the Youtuber discovered the concept from elsewhere. Shame he didn&amp;#8217;t bother to mention it in his video. It took me 10 seconds to find the above article, by the way.&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;m sure many, many more easy examples could be found if needed. &lt;/p&gt;

	&lt;h2&gt;There aren&amp;#8217;t any Shortcuts&lt;/h2&gt;

	&lt;p&gt;The bottom line, and the point of this post, is that there aren&amp;#8217;t any shortcuts to learning / mastering / becoming something. The most efficient way to get what you want may be to be invest in a book, or go on a course that will cover the fundamentals. It may be tempting to do a search on &amp;#8220;become a better photographer&amp;#8221; or &amp;#8220;take better photos&amp;#8221; but be aware, those phrases will lead you to &lt;span class="caps"&gt;TTV&lt;/span&gt;&amp;#8217;s. Every time. Your time is their paycheck. &lt;/p&gt;


	&lt;h2 class="footnotes"&gt;Footnotes&lt;/h2&gt;

	&lt;p class="footnote" id="fn6bfde009a8774a968c0c434f386b414d-1"&gt;&lt;sup&gt;1&lt;/sup&gt; With the exception of those highly annoying cookie consent dialogues.&lt;/p&gt;</content><category term="web"></category><category term="opinion"></category></entry><entry><title>Interesting Websites &amp; Blogs January 2025</title><link href="https://simonh.uk/2025/01/13/interesting-websites-blogs-january-2025/" rel="alternate"></link><published>2025-01-13T00:00:00+00:00</published><updated>2025-01-13T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2025-01-13:/2025/01/13/interesting-websites-blogs-january-2025/</id><summary type="html"></summary><content type="html">	&lt;p&gt;&lt;img alt="John Matthews Photo" src="/img/2025-01-13/dog_walker.webp" title="John Matthews Photo" /&gt;&lt;/p&gt;

	&lt;h2&gt;Intro&lt;/h2&gt;

	&lt;p&gt;This is a series I&amp;#8217;ve been planning for a few months (but not got round to until now). My aim is to give a shout out to other websites and blogs that I think you might find interesting. I&amp;#8217;ve deliberately avoided including any professional bloggers, influencers, those types. &lt;/p&gt;

	&lt;h3&gt;&lt;a href="https://johnmathews.is/"&gt;John Matthews&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;Writes on a wide range of topics &amp;#8212; programming, photography, money, current affairs. Something for everyone here. Very nicely designed site, clean and minimal(ish). &lt;/p&gt;

	&lt;p class="info"&gt;The photo at the top of the page is &lt;a href="https://johnmathews.is/static/images/photos/dog_walker.jpeg"&gt;Dog Walker&lt;/a&gt; from John&amp;#8217;s site.&lt;/p&gt;

	&lt;h3&gt;&lt;a href="http://syndicate.lubiki.pl/"&gt;Syndicate Unofficial Site&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;I loved the game &lt;em&gt;Syndicate Wars&lt;/em&gt; on the Playstation. Actually completed it too! Sites like this one used to all over the net in the 90&amp;#8217;s / 00&amp;#8217;s. Not so much now. Have a look at how much work went it this.&lt;/p&gt;

	&lt;h3&gt;&lt;a href="http://www.theraider.net/"&gt;The Raider.Net&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;Indiana Jones. Nothing else! Looks like this hasn&amp;#8217;t been updated since about 2008 but it&amp;#8217;s still got an active messageboard / forum. I&amp;#8217;m no superfan (though I&amp;#8217;ve seen all the films apart from Dial of Destiny), but there&amp;#8217;s an enormous amount of content here that you can only marvel at.&lt;/p&gt;

	&lt;h3&gt;&lt;a href="https://www.containsmoderateperil.com/"&gt;Contains Moderate Peril&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;TV, music, movies, gaming. A fine example of a guy with obviously wide ranging interests publishing whatever takes his fancy.&lt;/p&gt;

	&lt;h3&gt;&lt;a href="https://rahim.li/"&gt;Alvan Rahimli&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;Found this site from the site above. Specifically, the &lt;em&gt;blog questions challenge&lt;/em&gt; page. Yes, I too will be completing it. Anyway, I digress&amp;#8230;&lt;/p&gt;

	&lt;p&gt;Alvan&amp;#8217;s site is very well laid out and clean. His blog just has whatever he feels like writing about (same here). A good example of a personal blog that just exists &lt;em&gt;because he can&lt;/em&gt;.&lt;/p&gt;

	&lt;h3&gt;&lt;a href="https://herman.bearblog.dev/"&gt;Herman Martinus&lt;/a&gt;&lt;/h3&gt;

	&lt;p&gt;Creator of the &lt;a href="https://bearblog.dev/"&gt;bear blog&lt;/a&gt; platform (which I just found). Up until &lt;em&gt;today&lt;/em&gt; I&amp;#8217;ve advised people to just use Blogger if they want to quickly get a blog up and running. Hmmm. Maybe I was wrong.&lt;/p&gt;

	&lt;h2&gt;Afterword&lt;/h2&gt;

	&lt;p class="warn"&gt;If you know of a site I should include next time, please email me below! If I included your site, but you want it removed, also send me an email.&lt;/p&gt;</content><category term="web"></category><category term="opinion"></category></entry><entry><title>The Little to Big GoAccess Tutorial</title><link href="https://simonh.uk/2025/01/02/the-little-to-big-goaccess-tutorial/" rel="alternate"></link><published>2025-01-02T00:00:00+00:00</published><updated>2025-01-04T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2025-01-02:/2025/01/02/the-little-to-big-goaccess-tutorial/</id><summary type="html">	&lt;p&gt;Is there anybody out there? Or in here?&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="GoAccess Logo" src="/img/2025-01-02/goaccess.webp" title="GoAccess Logo" /&gt;&lt;/p&gt;

	&lt;h2 class="readme"&gt;&lt;span class="caps"&gt;README&lt;/span&gt;&lt;/h2&gt;

	&lt;p&gt;Hello internet surfers! The goal of this post is to set up &lt;a href="https://goaccess.io/"&gt;GoAccess&lt;/a&gt; for server side reporting of our website visitors (and other stuff eventually). Here&amp;#8217;s the program description from their website:&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;GoAccess is an open source real-time web log analyzer and interactive viewer that runs in a terminal in *nix systems or through your browser. It provides fast and valuable http statistics for system administrators that require a visual server report on the fly.&lt;/em&gt;&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;The plan is to start with the vanilla (default) configuration and slowly tweak settings to end up with a lean and accurate reporting system for our site. I&amp;#8217;ll publish new parts as time allows. My server information is:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Debian 12.8&lt;/li&gt;
		&lt;li&gt;Apache 2.4.62&lt;/li&gt;
		&lt;li&gt;GoAccess 1.7 (from Debian repository)&lt;/li&gt;
	&lt;/ul&gt;

	&lt;h2 class="question"&gt;Why Are We Doing This?&lt;/h2&gt;

	&lt;p&gt;Client-side javascript analytics scripts have a &lt;em&gt;big&lt;/em&gt; drawback. Look at the screenshot below:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="uBlock Ad Blocker" src="/img/2025-01-02/ublock_origin.webp" title="uBlock Ad Blocker" /&gt;&lt;/p&gt;

	&lt;p&gt;See the problem? Simple Analytics, which I&amp;#8217;ve been trying out, is massively under reporting my visitors. That might have something to do with over &lt;strong&gt;900 million&lt;/strong&gt; people (including me) are using ad blockers! Luckily we have access to our server logs, and that&amp;#8217;s going to give us far more accurate statistics. Let&amp;#8217;s dive in!&lt;/p&gt;

	&lt;p&gt;We&amp;#8217;ll start by dealing with crawlers.&lt;/p&gt;

	&lt;h2&gt;Part 1 &amp;#8211; Crawlers&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;simon@server:~ [ssh] $ cd /etc/goaccess/&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;simon@server:/etc/goaccess [ssh] $ ll
total 48K
drwxr-xr-x   2 root root 4.0K Aug 20  2023 .
drwxr-xr-x 119 root root  12K Jan  2 16:06 ..
-rw-r--r--   1 root root 3.3K Mar  1  2021 browsers.list
-rw-r--r--   1 root root  21K Jan  4  2023 goaccess.conf
-rw-r--r--   1 root root 1.7K Mar  1  2021 podcast.list&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Let&amp;#8217;s become root, so we don&amp;#8217;t have to bother typing &lt;code&gt;sudo&lt;/code&gt; all the time&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;simon@server:/etc/goaccess [ssh] $ sudo -s
[sudo] password for simon:
root@server:/etc/goaccess#&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Let&amp;#8217;s find out how many lines are in &lt;code&gt;goaccess.conf&lt;/code&gt; as generally the more lines, the more options we can fiddle with&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# cat goaccess.conf | wc -l
757&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;757 lines, so quite a few. As always, I&amp;#8217;ll keep track of changes I make to the file with &lt;span class="caps"&gt;GNU&lt;/span&gt; &lt;span class="caps"&gt;RCS&lt;/span&gt;. I&amp;#8217;ve written a previous post about using &lt;span class="caps"&gt;RCS&lt;/span&gt; for managing configuration files, available &lt;a href="https://simonh.uk/2023/08/25/using-gnu-rcs-for-managing-configuration-files/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# mkdir RCS
root@server:/etc/goaccess# ci -l goaccess.conf
RCS/goaccess.conf,v  &amp;lt;--  goaccess.conf
enter description, terminated with single &amp;#39;.&amp;#39; or end of file:
NOTE: This is NOT the log message!
&amp;gt;&amp;gt; Initial version
&amp;gt;&amp;gt; .
initial revision: 1.1
done
root@server:/etc/goaccess#&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Right, now we&amp;#8217;ve safely got the unedited file checked in, let&amp;#8217;s run goaccess with the default configuration. All we&amp;#8217;re interested in today is how many visitors this site has had &lt;em&gt;today&lt;/em&gt;. Running the command below will output a few screenfuls of information. I want section 9 &amp;#8212; Virtual Hosts&lt;sup class="footnote" id="fnrev165b425764934195b3e3137c1ffd0daa-1"&gt;&lt;a href="#fn165b425764934195b3e3137c1ffd0daa-1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# goaccess /var/log/apache2/other_vhosts_access.log -c

   9 - Virtual Hosts

 Hits     h% Vis.     v% Tx. Amount Data
 ---- ------ ---- ------ ---------- ----
  847 46.93%  172 69.92%  13.55 MiB www.simonh.uk&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;So, we&amp;#8217;re told I&amp;#8217;ve had 172 visitors today. Good luck getting more than that, Google!&lt;sup class="footnote" id="fnrev165b425764934195b3e3137c1ffd0daa-2"&gt;&lt;a href="#fn165b425764934195b3e3137c1ffd0daa-2"&gt;2&lt;/a&gt;&lt;/sup&gt; But, before I officially announce this as the most popular site on the whole internet, I better double check my numbers&amp;#8230;&lt;/p&gt;

	&lt;p&gt;Open &lt;code&gt;/etc/goaccess/goaccess.conf&lt;/code&gt; with your editor of choice, and find the following section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Ignore crawlers from being counted.
# This will ignore robots listed under browsers.c
# Note that it will count them towards the total
# number of requests, but excluded from any of the panels.
#
ignore-crawlers true

# Parse and display crawlers only.
# This will ignore all hosts except robots listed under browsers.c
# Note that it will count them towards the total
# number of requests, but excluded from any of the panels.
#
crawlers-only false

# Unknown browsers and OS are considered as crawlers
#
unknowns-as-crawlers true&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&amp;#8217;m going to first change ignore-crawlers from false to true, and then checkin the change.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# ci -l goaccess.conf
RCS/goaccess.conf,v  &amp;lt;--  goaccess.conf
new revision: 1.2; previous revision: 1.1
enter log message, terminated with single &amp;#39;.&amp;#39; or end of file:
&amp;gt;&amp;gt; Ignore-crawlers = true
&amp;gt;&amp;gt; .
done&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now we&amp;#8217;ll run goaccess again and see how that change has affected our visitors&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# goaccess /var/log/apache2/other_vhosts_access.log -c

   9 - Virtual Hosts

 Hits     h% Vis.     v% Tx. Amount Data
 ---- ------ ---- ------ ---------- ----
  636 41.79%   90 69.23%   7.37 MiB www.simonh.uk&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;So by just ignoring crawlers, my visitors have been nearly halved. I don&amp;#8217;t know whether to be happy or sad about that. But lets keep going. The next obvious thing to do is to set that visitors that are using unknown browsers and OS&amp;#8217;s are also probably crawlers (makes sense). So let&amp;#8217;s throw them away as well! And checkin our change&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root@server:/etc/goaccess# ci -l goaccess.conf
RCS/goaccess.conf,v  &amp;lt;--  goaccess.conf
new revision: 1.3; previous revision: 1.2
enter log message, terminated with single &amp;#39;.&amp;#39; or end of file:
&amp;gt;&amp;gt; unknowns-as-crawlers = true
&amp;gt;&amp;gt; .
done&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Let&amp;#8217;s run goaccess yet again to see if I&amp;#8217;ve lost any more visitors&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  9 - Virtual Hosts

 Hits     h% Vis.     v% Tx. Amount Data
 ---- ------ ---- ------ ---------- ----
  550 78.57%   58 68.24%   6.36 MiB www.simonh.uk&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;So by changing just those two options from false to true, I&amp;#8217;ve wiped out another third of my visitors! You&amp;#8217;ll have to bear with me while I ascend a mountain to contemplate whether &lt;em&gt;ignorance is bliss&lt;/em&gt;, or, &lt;em&gt;the truth shall set you free&lt;/em&gt;. &lt;/p&gt;

	&lt;p&gt;See you in the next part&amp;#8230;&lt;/p&gt;

	&lt;h2&gt;Part 2 &amp;#8211; Emailing the Report&lt;/h2&gt;

	&lt;p&gt;Turns out there are no mountains near me (plus it&amp;#8217;s cold) so I&amp;#8217;ll continue. I wrote a &lt;a href="https://simonh.uk/2021/05/01/get-a-daily-email-report-of-your-website-visitors/"&gt;post&lt;/a&gt; back in 2021 about getting a daily email of visitors using goaccess, which I&amp;#8217;ll slightly modify here. &lt;/p&gt;

	&lt;p&gt;Here is the script we&amp;#8217;ll use which we&amp;#8217;ll call &lt;code&gt;apache_report&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
now=`date +%Y-%m-%d_%H%M%S`
goaccess /var/log/apache2/other_vhosts_access.log --log-format=VCOMBINED -o report_$now.html
gzip report_$now.html
echo &amp;quot;Report&amp;quot; | mail -s &amp;quot;Apache Report - $now&amp;quot; -A report_$now.html.gz &amp;lt;you@youremail.address&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p class="warn"&gt;Remember to change &lt;em&gt;you@youremail.address&lt;/em&gt; to your email address!&lt;/p&gt;

	&lt;p&gt;If you haven&amp;#8217;t got round to setting up a mail server yet, you can follow my &lt;a href="https://simonh.uk/2021/04/16/opensmtpd-for-outgoing-mail-only/"&gt;tutorial&lt;/a&gt; for OpenSMTPD, or find one elsewhere on the net.&lt;/p&gt;

	&lt;p&gt;First thing to do is save &lt;code&gt;apache_report&lt;/code&gt; on the server and check it works.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;simon@server:~/tmp [ssh] $ nano apache_report &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Copy the script above and paste it into your editor. With that saved, let&amp;#8217;s run it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;simon@server:~/tmp [ssh] $ sudo bash apache_report 
 [PARSING /var/log/apache2/other_vhosts_access.log] {256} @ {0/s}
Cleaning up resources...
simon@server:~/tmp [ssh] $ &lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;No errors. Good. Let&amp;#8217;s check our email:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="Apache reports emailed" src="/img/2025-01-02/inbox.webp" title="Apache reports emailed" /&gt;&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;ve sent a few to myself, as you can see. Below is how the email looks on mobile. I&amp;#8217;ve formatted it like this to make it easier to view here on this page:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="Goaccess report" src="/img/2025-01-02/html_report.webp" title="Goaccess report" /&gt;&lt;/p&gt;

	&lt;p&gt;Awesome! The final thing to do in part 2, is set up a cron job so we&amp;#8217;ll get a daily email with our stats.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;simon@server:~/tmp [ssh] $ sudo cp apache_report /etc/cron.daily/
[sudo] password for simon: 
simon@server:~/tmp [ssh] $ ls /etc/cron.daily/
00logwatch     apt-compat                dpkg       mod-pagespeed
apache2        aptitude                  logrotate  ntp
apache_report  bsdmainutils.dpkg-remove  man-db     popularity-contest&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Make our file executable&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;simon@server:~/tmp [ssh] $ sudo chmod+x /etc/cron.daily/apache_report&lt;/code&gt;&lt;/pre&gt;

	&lt;p class="warn"&gt;One thing to warn you about: each email is currently 148kB in size (gzipped). Extracted they are coming out at about 450KB. I know we aren&amp;#8217;t in 1980 anymore, but make sure you&amp;#8217;ve got plenty of storage with your mail provider!&lt;/p&gt;

	&lt;p&gt;The next day @ 06:25:55 my report arrives in my inbox (table below is the vhosts section):&lt;/p&gt;

	&lt;p&gt;&lt;img alt="Goaccess vhosts report" src="/img/2025-01-02/vhosts_report.webp" title="Goaccess vhosts report" /&gt;&lt;/p&gt;

	&lt;h2&gt;Part 3 &amp;#8211; ?&lt;/h2&gt;

	&lt;p&gt;&lt;img alt="Please Stand By" src="/img/standby2.webp" title="Please Stand By" /&gt;&lt;/p&gt;

	&lt;h2 class="footnotes"&gt;Footnotes&lt;/h2&gt;

	&lt;p class="footnote" id="fn165b425764934195b3e3137c1ffd0daa-1"&gt;&lt;sup&gt;1&lt;/sup&gt; Note to self: trim all that trailing whitespace with &lt;code&gt;sed -i 's/[[:space:]]*$//' &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/p&gt;

	&lt;p class="footnote" id="fn165b425764934195b3e3137c1ffd0daa-2"&gt;&lt;sup&gt;2&lt;/sup&gt; I&amp;#8217;m informed that Google shares numbers in the millions or billions. Maybe trillions. Still, 172 should put me in the top 10 I expect.&lt;/p&gt;

	&lt;h2 class="updates"&gt;Updates&lt;/h2&gt;

	&lt;p&gt;&lt;mark&gt;2024-01-04&lt;/mark&gt;: Add &lt;em&gt;why are we doing this?&lt;/em&gt; section to part 1&lt;/p&gt;

	&lt;p&gt;&lt;mark&gt;2024-01-03&lt;/mark&gt;: Add &lt;em&gt;Part 2&lt;/em&gt;&lt;/p&gt;</content><category term="web"></category><category term="analytics"></category><category term="apache"></category><category term="tips"></category></entry><entry><title>It's Time to Get Back on The Internet</title><link href="https://simonh.uk/2024/12/31/its-time-to-get-back-on-the-internet/" rel="alternate"></link><published>2024-12-31T00:00:00+00:00</published><updated>2024-12-31T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2024-12-31:/2024/12/31/its-time-to-get-back-on-the-internet/</id><summary type="html">	&lt;p&gt;Leave those intranets behind&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="The Internet" src="/img/2024-12-31/internet.webp" title="The Internet" /&gt;&lt;/p&gt;

	&lt;h2&gt;An Intranet is not The Internet&lt;/h2&gt;

	&lt;p&gt;Facebook, Twitter/X, Linkedin, Tiktok et al. are all intranets.&lt;/p&gt;

	&lt;p&gt;From &lt;a href="https://en.wikipedia.org/wiki/Intranet"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;&lt;em&gt;An intranet is a computer network for sharing information, easier communication, collaboration tools, operational systems, and other computing services within an organization, usually to the exclusion of access by outsiders. The term is used in contrast to public networks, such as the Internet, but uses the same technology based on the Internet protocol suite.&lt;/em&gt;&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;Pay particular attention to &lt;em&gt;easier communication&lt;/em&gt; as all these intranets are predominantly concerned with their users interacting with each other. Invite your friends! They&amp;#8217;ll love it here.&lt;/p&gt;


	&lt;h2&gt;No, I&amp;#8217;m Not On [&amp;#8230;]&lt;/h2&gt;

	&lt;p&gt;Quite often through my work, I&amp;#8217;ll be asked &amp;#8220;can you whatsapp that photo to to me?&amp;#8221; I reply that I cannot, as I don&amp;#8217;t use it. I never have used it and I never will. Why would I a messaging intranet? I have loads of email addresses, and a phone that can make and receive calls and messages.&lt;/p&gt;

	&lt;p&gt;&amp;#8220;I&amp;#8217;ll share it with you on Facebook!&amp;#8221; I&amp;#8217;m not on there. Just email it mate.&lt;/p&gt;

	&lt;p&gt;I think they sometimes think I&amp;#8217;m a bit odd (I am) for not having accounts that they presume &lt;em&gt;everyone&lt;/em&gt; has. But here&amp;#8217;s the thing&amp;#8230;&lt;/p&gt;


	&lt;h2&gt;It&amp;#8217;s Not Cool Anymore&lt;/h2&gt;

	&lt;p&gt;When these intranets started popping up, it was new and cool. &amp;#8220;Are you on &lt;a href="https://en.wikipedia.org/wiki/Friends_Reunited"&gt;Friends Reunited&lt;/a&gt;?&amp;#8221; Of course I am, we would reply back in about 2000.&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;m just going on my recollections but as I remember it, you would find people you hadn&amp;#8217;t seen in donkeys, send them a message and then if you wanted to, you&amp;#8217;d exchange emails and the site had fufilled it&amp;#8217;s purpose.&lt;/p&gt;

	&lt;p&gt;It was more of a directory of people than anything else. And that was fine. Better, actually.&lt;/p&gt;

	&lt;p&gt;But then, other companies wanted you on &lt;em&gt;their&lt;/em&gt; intranet &lt;em&gt;all the time&lt;/em&gt;. Forget about that old internet thing. We&amp;#8217;ve got everything you&amp;#8217;ll ever need right here. You like games? Check. Got a group that likes to meet up and talk about trains, planes or automobiles? Bring them here! None of you will ever need to stand up again. It&amp;#8217;ll be awesome. Like shopping? We&amp;#8217;ve got loads of ads that&amp;#8217;ll catch your eye. And they&amp;#8217;ll deliver it to you as well.&lt;/p&gt;


	&lt;h2&gt;The Kids Get Angry&lt;/h2&gt;

	&lt;p&gt;One day, the young will rediscover what the internet was once like and how it slowly got worse. How the adults wrung their hands about the rampant grooming and exploitation of &lt;em&gt;children&lt;/em&gt; on various &lt;em&gt;hugely profitable&lt;/em&gt; intranets (that were delighted to have those children on their &amp;#8220;platforms&amp;#8221;). And they&amp;#8217;ll be angry. Quite rightly. They&amp;#8217;ll (re)invent their own internet.&lt;/p&gt;

	&lt;p&gt;Unless the adults lead by example and ditch these awful places. But, they won&amp;#8217;t. &lt;/p&gt;

	&lt;h2&gt;Afterword&lt;/h2&gt;

	&lt;p&gt;Tnanks to these dreadful intranets, here in the UK we now have the &lt;a href="https://www.legislation.gov.uk/ukpga/2023/50/pdfs/ukpga_20230050_en.pdf"&gt;Online Safety Act 2023&lt;/a&gt; (303 pages)!&lt;/p&gt;

	&lt;p&gt;From the &lt;span class="caps"&gt;NSPCC&lt;/span&gt; (UK charity):&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;The Act means that tech companies running social networking sites or search engines must promote online safety by tackling illegal material and content that is harmful to children, conducting regular risk assessments, and properly enforcing age limits.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;Sounds good. Except that the legislation has attracted considerable from criticism from, for example, &lt;a href="https://www.article19.org/resources/uk-online-safety-bill-serious-threat-to-human-rights-online/"&gt;Article 19&lt;/a&gt;, the &lt;a href="https://www.eff.org/pages/uk-online-safety-bill-massive-threat-online-privacy-security-and-speech"&gt;&lt;span class="caps"&gt;FSF&lt;/span&gt;&lt;/a&gt; and many other sites.&lt;/p&gt;</content><category term="web"></category><category term="social media"></category><category term="opinion"></category></entry><entry><title>Why I Prefer Textile Over Markdown</title><link href="https://simonh.uk/2024/12/15/why-i-prefer-textile-over-markdown/" rel="alternate"></link><published>2024-12-15T00:00:00+00:00</published><updated>2025-01-08T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2024-12-15:/2024/12/15/why-i-prefer-textile-over-markdown/</id><summary type="html">	&lt;p&gt;When Markdown isn&amp;#8217;t for you&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Textile Logo" src="/img/logo/textile.webp" title="Textile Logo" /&gt;&lt;/p&gt;

	&lt;h2&gt;Plain Text &amp;gt; Textile Parser &amp;gt; &lt;span class="caps"&gt;HTML&lt;/span&gt;&lt;/h2&gt;

	&lt;p&gt;I write a lot of &lt;span class="caps"&gt;HTML&lt;/span&gt; by hand. Have done for years. But when I started this blog, I knew I&amp;#8217;d stay a lot saner using a tool such as Markdown, Textile or reStructuredText to generate the final markup for me. I know most people use &lt;a href="https://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; but as a contrarian, I chose &lt;a href="https://textile-lang.com/"&gt;Textile&lt;/a&gt;. I&amp;#8217;ve found that Textile gets the balance between ease-of-use and power &lt;em&gt;just right&lt;/em&gt;. &lt;/p&gt;

	&lt;p&gt;Let&amp;#8217;s dive right in and have a look at how you write textile documents.&lt;/p&gt;

	&lt;h2&gt;The Basics&lt;/h2&gt;

	&lt;h3&gt;Headings&lt;/h3&gt;

	&lt;p&gt;Headings are simply h1. to h4. followed by your heading (all on the same line):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;h1. This is my heading&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;will produce&lt;/p&gt;

	&lt;h1&gt;This is my heading&lt;/h1&gt;

&lt;pre&gt;&lt;code&gt;h4. This is my tiny heading&lt;/code&gt;&lt;/pre&gt;

	&lt;h4&gt;This is my tiny heading&lt;/h4&gt;

	&lt;h2&gt;Paragraphs&lt;/h2&gt;

	&lt;p&gt;Paragraphs are blocks of plain text separated by two newlines. You just type as you would in a text editor. The Textile parser will wrap your paragraphs in &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

	&lt;h3&gt;Text formatting&lt;/h3&gt;

	&lt;p&gt;Underscores are used to &lt;code&gt;_emphasise_&lt;/code&gt; text. Bold text needs an &lt;code&gt;*asterisk*&lt;/code&gt; on either side of what you want to be bold. If you want emphasised, bold text, just use both &lt;code&gt;_*together*_&lt;/code&gt;:&lt;/p&gt;

	&lt;p&gt;&lt;em&gt;&lt;strong&gt;really important&lt;/strong&gt;&lt;/em&gt; you understand this. Easy.&lt;/p&gt;

	&lt;h3&gt;Lists&lt;/h3&gt;

	&lt;p&gt;Unordered (bullet) lists use asterisks as well. If you need sublists, add asterisks for each sub-level:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Here is my shopping list
* Milk
* Bread
* Ingredients for cake:
** Eggs
** Chocolate
** Sugar&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Personally, I think that is very easy to remember and use. This will output:&lt;/p&gt;

	&lt;p&gt;Here is my shopping list&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Milk&lt;/li&gt;
		&lt;li&gt;Bread&lt;/li&gt;
		&lt;li&gt;Ingredients for cake:
		&lt;ul&gt;
			&lt;li&gt;Eggs&lt;/li&gt;
			&lt;li&gt;Chocolate&lt;/li&gt;
			&lt;li&gt;Sugar&lt;/li&gt;
		&lt;/ul&gt;&lt;/li&gt;
		&lt;/ul&gt;

	&lt;p&gt;Ordered (numbered) lists use the hash character &lt;code&gt;#&lt;/code&gt; for each list item:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;How to make a cuppa
# Get a cup
## Place teabag and sugar (if desired) into cup
# Boil a kettle
# When boiled add water to cup
# etc.&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Which renders to:&lt;/p&gt;

	&lt;p&gt;How to make a cuppa
	&lt;ol&gt;
		&lt;li&gt;Get a cup
		&lt;ol&gt;
			&lt;li&gt;Place teabag and sugar (if desired) into cup&lt;/li&gt;
		&lt;/ol&gt;&lt;/li&gt;
		&lt;li&gt;Boil a kettle&lt;/li&gt;
		&lt;li&gt;When boiled add water to cup&lt;/li&gt;
		&lt;li&gt;etc.&lt;/li&gt;
	&lt;/ol&gt;&lt;/p&gt;

	&lt;p&gt;The Textile parser will keep track of numbering for you.&lt;/p&gt;

	&lt;h3&gt;Links&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;here is a link to my &amp;quot;website&amp;quot;:https://simonh.uk&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;here is a link to my &lt;a href="https://simonh.uk"&gt;website&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;Link text in double quotes, immediately followed by a colon, then the &lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/p&gt;

	&lt;h2&gt;Additional Textile Features&lt;/h2&gt;

	&lt;p&gt;This is where Textile beats the competition (in my opinion). &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p&amp;gt;. This text is right aligned.
p=. This text is centred.
p&amp;lt;. Back to left aligned (the default).&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Which produces:&lt;/p&gt;

	&lt;p style="text-align:right;"&gt;This text is right aligned.&lt;/p&gt;

	&lt;p style="text-align:center;"&gt;This text is centred.&lt;/p&gt;

	&lt;p style="text-align:left;"&gt;Back to left aligned (the default).&lt;/p&gt;

	&lt;h3&gt;Tables&lt;/h3&gt;

	&lt;p&gt;Example below copied from the Textile website.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;| A | simple | table | row |
| And | another | table | row |
| With an | | empty | cell |

| A | simple | table | row |
| And | another | table | row |
| With an | | empty | cell |&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;There&amp;#8217;s a lot more you can do with tables. Consult the Textile documentation for more info.&lt;/p&gt;

	&lt;h3&gt;Footnotes&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;This line of text has a footnote[1]&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This line of text has a footnote&lt;sup class="footnote" id="fnrev9e43cb55b38d444d8ab4f3d835a73bda-1"&gt;&lt;a href="#fn9e43cb55b38d444d8ab4f3d835a73bda-1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

	&lt;p&gt;At the bottom of your Textile document, you simply write&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn1. This is the footnote text.&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Increment the footnote for each one you created in the document&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fn2. Here&amp;#39;s the second one.&lt;/code&gt;&lt;/pre&gt;

	&lt;h2&gt;Easily Reference &lt;span class="caps"&gt;CSS&lt;/span&gt; Classes and Styles&lt;/h2&gt;

	&lt;p&gt;I love this one and use it throughout my blog and in other projects. Textile allows you to do this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p(some-class). Here is my text&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;which will apply whatever you&amp;#8217;ve defined for &lt;code&gt;some-class&lt;/code&gt;. Below is what I use to put icons before headings and paragraphs (in &lt;code&gt;paper.css&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.info::before {
  content: url(&amp;#39;/img/info.svg&amp;#39;);
  width: 18px;
  vertical-align: middle;
  margin-right: 10px;
  display: inline-block;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;By simply putting this into my textile template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p(info). This paragraph now has an icon placed on the left. Useful for letting a reader know something!&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;that will be rendered to:&lt;/p&gt;

	&lt;p class="info"&gt;This paragraph now has an icon placed on the left. Useful for letting a reader know something!&lt;/p&gt;

	&lt;p&gt;Textile also helpfully lets you apply inline styles.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Do you like the color %{color:yellow;}yellow%?&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;produces this:&lt;/p&gt;

	&lt;p&gt;Do you like the color &lt;span style="color:yellow;"&gt;yellow&lt;/span&gt;?&lt;/p&gt;

	&lt;p&gt;I don&amp;#8217;t use the inline styling very much at all. But if I / you need to, Textile has you covered.&lt;/p&gt;

	&lt;h2&gt;Conclusion&lt;/h2&gt;

	&lt;p&gt;Dean Allen, the guy who created Textile for a &lt;a href="https://textpattern.com/"&gt;&lt;span class="caps"&gt;CMS&lt;/span&gt;&lt;/a&gt; he was writing explained why he created the format (from Wikipedia):&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Textile was developed by Dean Allen in 2002, which he billed as &amp;#8220;a humane web text generator&amp;#8221; that enabled you to &amp;#8220;simply write&amp;#8221;.&lt;/p&gt;&lt;/blockquote&gt;

	&lt;p&gt;I think he did a great job.&lt;/p&gt;

	&lt;h2&gt;Footnotes&lt;/h2&gt;

	&lt;p class="footnote" id="fn9e43cb55b38d444d8ab4f3d835a73bda-1"&gt;&lt;sup&gt;1&lt;/sup&gt; I told you there was a footnote down here!&lt;/p&gt;

	&lt;h2 class="updates"&gt;Updates&lt;/h2&gt;

	&lt;p&gt;&lt;mark&gt;2025-01-08&lt;/mark&gt;: Add &lt;em&gt;Easily Reference &lt;span class="caps"&gt;CSS&lt;/span&gt; Classes and Styles&lt;/em&gt; section.&lt;/p&gt;</content><category term="web"></category><category term="textile"></category></entry><entry><title>Why CGI Programming is Still Useful in 2023</title><link href="https://simonh.uk/2023/08/19/why-cgi-programming-is-still-useful-in-2023/" rel="alternate"></link><published>2023-08-19T00:00:00+01:00</published><updated>2023-08-19T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2023-08-19:/2023/08/19/why-cgi-programming-is-still-useful-in-2023/</id><summary type="html">	&lt;p&gt;Old, but not dead thankfully&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="CGI Logo" src="/img/2023-08-19/cgi.webp" title="CGI Logo" /&gt;&lt;/p&gt;

	&lt;h1&gt;What is &lt;span class="caps"&gt;CGI&lt;/span&gt;?&lt;/h1&gt;

	&lt;p&gt;&lt;a href="https://datatracker.ietf.org/doc/html/rfc3875"&gt;Common Gateway Interface&lt;/a&gt; has been around since the mid 1990&amp;#8217;s. It was the one of the first standards to specify how a server and a program could serve requests. From the &lt;span class="caps"&gt;RFC&lt;/span&gt;:&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;The Common Gateway Interface (&lt;span class="caps"&gt;CGI&lt;/span&gt;) allows an &lt;span class="caps"&gt;HTTP&lt;/span&gt; server and a &lt;span class="caps"&gt;CGI&lt;/span&gt; script to share responsibility for responding to client requests.&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;&lt;span class="caps"&gt;CGI&lt;/span&gt; allows any script or program to be called to serve dynamic content on a website. Needless to say, this was very popular and helped the web to explode from the 90&amp;#8217;s onwards (pretty much everything was written using &lt;span class="caps"&gt;CGI&lt;/span&gt;). One of the amazing things about &lt;span class="caps"&gt;CGI&lt;/span&gt; is that you can use &lt;strong&gt;any&lt;/strong&gt; programming language. C, Perl, Python, Ruby, even Bash. As long as the language has stdin and stdout, it will work. Here is a Bash script showing some system information:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash

echo &amp;quot;Content-type: text/html&amp;quot;
echo &amp;quot;&amp;quot;

echo &amp;#39;&amp;lt;html&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;head&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;title&amp;gt;CGI Bash&amp;lt;/title&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;/head&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;body&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;p&amp;gt;Demo of using GNU Bash with CGI&amp;lt;/p&amp;gt;&amp;#39;

echo &amp;#39;&amp;lt;h2&amp;gt;Hostname&amp;lt;/h2&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;pre&amp;gt;&amp;#39;$(hostname)&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;

echo &amp;#39;&amp;lt;h2&amp;gt;Bash Version&amp;lt;/h2&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;pre&amp;gt;Using &amp;#39;$(bash --version | head -1)&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;

echo &amp;#39;&amp;lt;h2&amp;gt;System Uptime&amp;lt;/h2&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;pre&amp;gt;&amp;#39;$(uptime)&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;

echo &amp;#39;&amp;lt;h2&amp;gt;Current Date&amp;lt;/h2&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;pre&amp;gt;&amp;#39;$(date)&amp;#39;&amp;lt;/pre&amp;gt;&amp;#39;

echo &amp;#39;&amp;lt;/body&amp;gt;&amp;#39;
echo &amp;#39;&amp;lt;/html&amp;gt;&amp;#39;

exit 0&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And the output of above script is:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="screenshot of Bash CGI output" src="/img/2023-08-19/bash_cgi.png" title="screenshot of Bash CGI output" /&gt;&lt;/p&gt;

	&lt;p&gt;Pretty awesome I think. Especially for a few lines of bash. And I&amp;#8217;m sure you&amp;#8217;ve noticed that the output could be &lt;b&gt;anything&lt;/b&gt;. The sky is the limit.&lt;/p&gt;

	&lt;h1&gt;Disadvantages of &lt;span class="caps"&gt;CGI&lt;/span&gt;&lt;/h1&gt;

	&lt;p&gt;A lot of people like to hate &lt;span class="caps"&gt;CGI&lt;/span&gt;. Here are some of the common complaints they will shriek if someone asks a question about using &lt;span class="caps"&gt;CGI&lt;/span&gt; in 2023&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;A new process is started for each request which is horribly inefficient!&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;Yes it is, and for a helluva lot of websites / web services, that&amp;#8217;s not a problem. If is a problem, FastCGI might help you out. Or, switching to a compiled language like C or Go.&lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;It&amp;#8217;s not suitable for creating a full blown site or service!&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;Maybe not. But what if you just want a simple contact form? Or a way of quickly uploading a file to a server (see below). &lt;/p&gt;

	&lt;blockquote&gt;
		&lt;p&gt;It&amp;#8217;s been superseded by better alternatives and is now obsolete!&lt;/p&gt;
	&lt;/blockquote&gt;

	&lt;p&gt;This seems to be the main objection that I see. Perl has dropped &lt;span class="caps"&gt;CGI&lt;/span&gt;.pm from the standard distribution. Python is removing &lt;span class="caps"&gt;CGI&lt;/span&gt; support in version 3.13. &lt;/p&gt;

	&lt;p&gt;I think this in the same mindset that says that people should never use &lt;a href="https://www.gnu.org/software/rcs/"&gt;&lt;span class="caps"&gt;GNU&lt;/span&gt; &lt;span class="caps"&gt;RCS&lt;/span&gt;&lt;/a&gt; now that Git has is a thing. But as I wrote in another post on this site, &lt;span class="caps"&gt;RCS&lt;/span&gt; is perfect for version controlling &lt;strong&gt;single&lt;/strong&gt; files. Like a &lt;span class="caps"&gt;CGI&lt;/span&gt; script for example! Yep, I use &lt;span class="caps"&gt;RCS&lt;/span&gt; for my &lt;span class="caps"&gt;CGI&lt;/span&gt; scripts. &lt;/p&gt;

	&lt;h1&gt;Advantages of &lt;span class="caps"&gt;CGI&lt;/span&gt;&lt;/h1&gt;

	&lt;ul&gt;
		&lt;li&gt;You don&amp;#8217;t have to choose between a static or a dynamic site&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;I have quite a few static sites and quite a few dynamic ones. Usually, I have to decide up front which type I want to make as I&amp;#8217;ll have to use a language that works on the web if I want to generate pages dynamically. The beauty of &lt;span class="caps"&gt;CGI&lt;/span&gt; is that you can have almost everything served statically, and just a few pages served dynamically. As usual with &lt;span class="caps"&gt;CGI&lt;/span&gt;, I don&amp;#8217;t know of another technology that offers this flexibility.&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Use whatever language you want&lt;/li&gt;
		&lt;li&gt;Set up is minimal&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;This is what I use with Apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Enable CGI scripts in cgi-bin directory
ScriptAlias &amp;quot;/cgi-bin/&amp;quot; &amp;quot;/var/www/my-website/cgi-bin/&amp;quot;
&amp;lt;Directory /var/www/my-website/cgi-bin/*&amp;gt;
    Options ExecCGI
	SetHandler cgi-script
	DirectoryIndex
&amp;lt;/Directory&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Done.&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;You can get a service running in minutes&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Just have a cgi-bin directory properly configured and dump your scripts in there. No &amp;#8220;frameworks&amp;#8221;. No config files. Just your &lt;span class="caps"&gt;CGI&lt;/span&gt; scripts. And the &lt;span class="caps"&gt;HTML&lt;/span&gt; files calling those scripts. It makes even the most minimal of minimal frameworks look complicated. &lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;It&amp;#8217;s the &lt;b&gt;right&lt;/b&gt; tool for some jobs&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Most of the web software I write is made with &lt;a href="https://bottlepy.org/docs/dev/"&gt;bottle.py&lt;/a&gt;. But sometimes, even bottle is overkill. A recent example: my son wanted to send me some files. Even though I have accounts for Google Drive, Onedrive, Dropbox etc I thought it was crazy that even though I have multiple web servers, I had no easy way for someone to quickly upload a file to one of them. Well, thanks to &lt;span class="caps"&gt;CGI&lt;/span&gt;, I now have a (very) simple form that lets someone upload a file (10MB maximum) and then sends me an email notifying me. And it was done in about 10 minutes. To set up an equivalent service with Bottle would have probably taken hours.&lt;/p&gt;

	&lt;h1&gt;Security Considerations&lt;/h1&gt;

	&lt;p&gt;As with &lt;strong&gt;any&lt;/strong&gt; service running on the internet, you will need to read some documentation to be aware of security risks. This is not just true for &lt;span class="caps"&gt;CGI&lt;/span&gt;, but for anything. The Apache website linked below has some tips. A search engine will no doubt give you more tips.&lt;/p&gt;

	&lt;h1&gt;Conclusion&lt;/h1&gt;

	&lt;p&gt;There is a reason that in 2023, &lt;span class="caps"&gt;CGI&lt;/span&gt; is still in use and refuses to die: &lt;/p&gt;

	&lt;p&gt;1. It&amp;#8217;s relatively simple to learn and use&lt;br /&gt;
2. You can use whichever programming language you want&lt;br /&gt;
3. It&amp;#8217;s an elegant protocol that solves a real problem&lt;br /&gt;
4. With &lt;span class="caps"&gt;CGI&lt;/span&gt; you can get something up and running quicker than any other technology I&amp;#8217;m aware of.&lt;br /&gt;
5. You can mix static and dynamic content as you please&lt;/p&gt;

	&lt;p&gt;So please, ignore the &lt;span class="caps"&gt;CGI&lt;/span&gt;-&lt;span class="caps"&gt;MUST&lt;/span&gt;-&lt;span class="caps"&gt;DIE&lt;/span&gt;-&lt;span class="caps"&gt;TODAY&lt;/span&gt; crowd and at least keep it in mind as a solution to some of your programming problems. Like many technologies from the &amp;#8220;early web&amp;#8221; (yes. I&amp;#8217;m looking at you WebDAV) &lt;span class="caps"&gt;CGI&lt;/span&gt; solved a problem pretty much as soon as it was discovered and was used for &lt;b&gt;many years&lt;/b&gt;. Some of us still use it happily today and quietly laugh to ourselves at the &amp;#8220;guru&amp;#8217;s&amp;#8221; having nervous breakdowns at the idea that such an old standard could &lt;strong&gt;still&lt;/strong&gt; be used in 2023. &lt;/p&gt;

	&lt;h2&gt;References and Recommended Reading&lt;/h2&gt;

	&lt;p&gt;&lt;a href="https://httpd.apache.org/docs/2.4/howto/cgi.html"&gt;Apache &lt;span class="caps"&gt;CGI&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://www.youtube.com/watch?v=NwRVJX0Ieno"&gt;The Magic of cgi-bin&lt;/a&gt; (Video)&lt;br /&gt;
&lt;a href="https://halestrom.net/darksleep/blog/046_cgi/"&gt;Why I recommend &lt;span class="caps"&gt;CGI&lt;/span&gt; instead of web frameworks&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://en.wikipedia.org/wiki/FastCGI"&gt;Wikipedia FastCGI&lt;/a&gt;&lt;/p&gt;</content><category term="web"></category><category term="web"></category><category term="apache"></category><category term="cgi"></category></entry><entry><title>A Guide to Setting up WebDAV with Apache HTTPD</title><link href="https://simonh.uk/2021/12/25/a-guide-to-setting-up-webdav-with-apache-httpd/" rel="alternate"></link><published>2021-12-25T00:00:00+00:00</published><updated>2021-12-25T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-12-25:/2021/12/25/a-guide-to-setting-up-webdav-with-apache-httpd/</id><summary type="html">	&lt;p&gt;WebDAV &amp;#8211; best thing since sliced bread!&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Apache httpd" src="/img/logo/apache.svg" title="Apache httpd" /&gt;&lt;/p&gt;

	&lt;p&gt;Credits: &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-configure-webdav-access-with-apache-on-ubuntu-18-04"&gt;Digital Ocean&lt;/a&gt; for the WebDAV tutorial. &lt;a href="https://hexeract.wordpress.com/2011/02/25/configure-a-webdav-enabled-webserver-for-multiple-user-folders-and-one-shared-folder/"&gt;hexeract&lt;/a&gt; for his post about multiple WebDAV users. &lt;a href="https://www.raymondcamden.com/2013/02/27/Quick-Tip-Make-Apaches-Directory-Indexes-look-nicer-on-mobile"&gt;Raymond Camden&lt;/a&gt; for the responsive directory index.&lt;/p&gt;

	&lt;p&gt;For a project I&amp;#8217;ve been working on, I needed some place for users to upload and access files. I started off using Google Drive, Sharepoint etc, but I also wanted to have the option of hosting the files myself. &lt;/p&gt;

	&lt;p&gt;So, I looked at all sorts of options (Pydio, Seafile, Owncloud, &lt;span class="caps"&gt;FTP&lt;/span&gt;, WebDAV). I decided to have a stab at WebDAV, mainly due to it being included with Apache through &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_dav.html"&gt;mod_dav&lt;/a&gt;. Initially, I was using file based storage, but the Apache &lt;a href="https://httpd.apache.org/docs/2.4/howto/auth.html"&gt;docs&lt;/a&gt; advise to use a dbm database instead due to being far faster. However, the same docs weren&amp;#8217;t very helpful when it came to using dbm for group management / authorisation. &lt;/p&gt;

	&lt;p&gt;The following is what I did to get everything working. If you want to do something similar yourself, hopefully it will help. I&amp;#8217;m using Debian 11, Apache 2.4.51. &lt;/p&gt;

	&lt;p&gt;First, create a directory for the credentials to live&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# mkdir -p /usr/local/apache2/var&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;code&gt;cd&lt;/code&gt; into the new directory and then create the dbm file that Apache will use for auth. I&amp;#8217;ll add myself and also what groups I belong to. After running command below, you&amp;#8217;ll be prompted for a password. I use &lt;a href="https://linux.die.net/man/1/pwgen"&gt;pwgen&lt;/a&gt; for generating passwords.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# htdbm -ct users.dbm me@mydomain.com &amp;quot;project1,project2&amp;quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The &lt;code&gt;-c&lt;/code&gt; is needed to create the database. &lt;code&gt;-t&lt;/code&gt; is used to add a comment which Apache uses for the group credentials (it would have been nice if the Apache docs stated that!). The most important things to remember are: no spaces in group names, and separate each group with commas. Just stick with alphanumeric characters or an underscore, and you should be golden.&lt;/p&gt;

	&lt;p&gt;Next, we&amp;#8217;ll add a second user who we only want to access project1&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# htdbm -t users.dbm someone@somewhere.com &amp;quot;project1,&amp;quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The next user can only access project2&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# htdbm -t users.dbm user@somewhere.com &amp;quot;project2,&amp;quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If you need to delete a user you can do that like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# htdbm -x users.dbm simon&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I think you can see why setting up access control in this way is such a good idea. You&amp;#8217;ve only got one file to manage. Adding, modifying or deleting users is just one line using &lt;a href="https://httpd.apache.org/docs/2.4/programs/htdbm.html"&gt;htdbm&lt;/a&gt;. And the lookups are super fast. I&amp;#8217;ve been using dbm for session management for years. You might want to install &lt;a href="https://packages.debian.org/bullseye/db-util"&gt;db-util&lt;/a&gt; as well for managing the database.&lt;/p&gt;

	&lt;p&gt;List database members:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;htdbm -l users.dbm&lt;/code&gt;&lt;/pre&gt;

	&lt;h2&gt;Apache setup&lt;/h2&gt;

	&lt;p&gt;You&amp;#8217;ll  need to enable the required modules.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# a2enmod dav
# a2enmod dav_fs
# a2enmod authn_dbm 
# a2enmod authz_dbm&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The following is what I&amp;#8217;m using for my apache.conf&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DavLockDB /usr/local/apache2/var/DavLock
&amp;lt;IfModule mod_ssl.c&amp;gt;
&amp;lt;VirtualHost *:443&amp;gt;
    DocumentRoot &amp;quot;/var/www/files.yoursite.com&amp;quot;
    ServerName files.yoursite.com

    SSLCertificateFile /etc/letsencrypt/live/files.yoursite.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/files.yoursite.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    # Directory Listing Display Options
    IndexOptions +FancyIndexing
    IndexOptions +VersionSort
    IndexOptions +HTMLTable
    IndexOptions +FoldersFirst
    IndexOptions +IconsAreLinks
    IndexOptions +IgnoreCase
    IndexOptions +XHTML
    IndexOptions +NameWidth=*
    IndexOptions +SuppressDescription
    IndexOptions +SuppressHTMLPreamble
    IndexOptions +Charset=UTF-8
    # Make it responsive
    IndexHeadInsert &amp;quot;&amp;lt;meta name=\&amp;quot;viewport\&amp;quot; content=\&amp;quot;width=device-width, initial-scale=1\&amp;quot;&amp;gt;&amp;quot;

    # project1 
    Alias /project1 /var/www/webdav/project1
    &amp;lt;Directory /var/www/webdav/project1&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  project1
    &amp;lt;/Directory&amp;gt;

    # project2
    Alias /project2 /var/www/webdav/project2
    &amp;lt;Directory /var/www/webdav/project2&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm    	
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  project2
    &amp;lt;/Directory&amp;gt;

&amp;lt;/VirtualHost&amp;gt;
&amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;As always check your config is correct&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# apachectl -t
Syntax OK&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Restart Apache&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# systemctl restart apache2&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Each time you have a new project, you can just copy the Alias and directory block, at the bottom like so.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DavLockDB /usr/local/apache2/var/DavLock
&amp;lt;IfModule mod_ssl.c&amp;gt;
&amp;lt;VirtualHost *:443&amp;gt;
    DocumentRoot &amp;quot;/var/www/files.yoursite.com&amp;quot;
    ServerName files.yoursite.com

    SSLCertificateFile /etc/letsencrypt/live/files.yoursite.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/files.yoursite.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf

    # Directory Listing Display Options
    IndexOptions +FancyIndexing
    IndexOptions +VersionSort
    IndexOptions +HTMLTable
    IndexOptions +FoldersFirst
    IndexOptions +IconsAreLinks
    IndexOptions +IgnoreCase
    IndexOptions +XHTML
    IndexOptions +NameWidth=*
    IndexOptions +SuppressDescription
    IndexOptions +SuppressHTMLPreamble
    IndexOptions +Charset=UTF-8
    # Make it responsive
    IndexHeadInsert &amp;quot;&amp;lt;meta name=\&amp;quot;viewport\&amp;quot; content=\&amp;quot;width=device-width, initial-scale=1\&amp;quot;&amp;gt;&amp;quot;

    # project1 
    Alias /project1 /var/www/webdav/project1
    &amp;lt;Directory /var/www/webdav/project1&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  project1
    &amp;lt;/Directory&amp;gt;

    # project2
    Alias /project2 /var/www/webdav/project2
    &amp;lt;Directory /var/www/webdav/project2&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm    	
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  project2
    &amp;lt;/Directory&amp;gt;

    # project3
    Alias /project3 /var/www/webdav/project3
    &amp;lt;Directory /var/www/webdav/project3&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm    	
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  project3
    &amp;lt;/Directory&amp;gt;

&amp;lt;/VirtualHost&amp;gt;
&amp;lt;/IfModule&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Hopefully, this will save someone a few hours of digging around Apache mailing lists. Or looking through the source code for comments. &lt;/p&gt;

	&lt;p&gt;In a future post, I&amp;#8217;ll tackle another item on my todo list &amp;#8211; making the directory listing look a bit better. It&amp;#8217;s not unbearable, but it&amp;#8217;s a bit disappointing that in 2021, the default page is not even responsive. Hence the IndexHeaderInsert override in the apache conf. &lt;/p&gt;

	&lt;h2&gt;October 2023 Update&lt;/h2&gt;

	&lt;p&gt;I forgot to mention I&amp;#8217;m now using &lt;a href="https://httpd.apache.org/docs/2.4/mod/mod_macro.html"&gt;mod_macro&lt;/a&gt; which simplifies setting up new shares:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Macro WebDAVShare $alias&amp;gt;
    Alias /$alias /var/www/myserver.tld/$alias
    &amp;lt;Directory /var/www/myserver.tld/$alias&amp;gt;
        DAV                On
        SSLRequireSSL
        AuthType           Basic
        AuthName           &amp;quot;webdav&amp;quot;
        AuthBasicProvider  dbm
        AuthDBMUserFile    &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        AuthDBMGroupFile   &amp;quot;/usr/local/apache2/var/users.dbm&amp;quot;
        Require dbm-group  admin $alias
    &amp;lt;/Directory&amp;gt;

    &amp;lt;Directory /var/www/myserver.tld/$alias/cgi-bin/*&amp;gt;
        Options ExecCGI
        SetHandler cgi-script
        DirectoryIndex
    &amp;lt;/Directory&amp;gt;
&amp;lt;/Macro&amp;gt;

Use WebDAVShare simon
Use WebDAVShare bob
Use WebDAVShare alice
Use WebDAVShare some_other_site&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&amp;#8217;ve also started using an &lt;code&gt;admin&lt;/code&gt; group. This group can access &lt;strong&gt;any&lt;/strong&gt; webdav share (as shown in the conf). I add myself to that group, so if there&amp;#8217;s a problem with a share, I can access it and troubleshoot any problems.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ htdbm -t users.dbm simon@mydomain.com &amp;quot;admin&amp;quot;&lt;/code&gt;&lt;/pre&gt;</content><category term="web"></category><category term="apache"></category><category term="httpd"></category><category term="webdav"></category><category term="tips"></category></entry><entry><title>Using Pelican with Invoke</title><link href="https://simonh.uk/2021/05/04/using-pelican-with-invoke/" rel="alternate"></link><published>2021-05-04T00:00:00+01:00</published><updated>2021-05-04T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-05-04:/2021/05/04/using-pelican-with-invoke/</id><summary type="html">	&lt;p&gt;No more &amp;#8220;$ history | grep rsync&amp;#8221;&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Pelican Logo" src="/img/logo/pelican.webp" title="Pelican Logo" /&gt;&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;m probably very late to the &lt;a href="http://www.pyinvoke.org/"&gt;Invoke&lt;/a&gt; party, and if you are too, it&amp;#8217;s worth a few minutes of your time to start taking advantage of Invoke for your Pelican administration.&lt;/p&gt;

	&lt;h2&gt;The Old Way&lt;/h2&gt;

	&lt;p&gt;Since I got back into blogging, I was getting sick of:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;pelican content&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Check everything looks good locally:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;pelican --listen&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Publish the site ready for upload to server:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;pelican content -s publishconf.py&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Send changes to server&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;rsync -avc --delete output/ myserver.com:/var/www/simonh.uk/html&lt;/code&gt;&lt;/p&gt;

	&lt;h2&gt;The New Way&lt;/h2&gt;

	&lt;p&gt;&lt;code&gt;# pip3 install invoke&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Open up &lt;code&gt;tasks.py&lt;/code&gt; in the root of your site and check the config section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CONFIG = {
    &amp;#39;settings_base&amp;#39;: SETTINGS_FILE_BASE,
    &amp;#39;settings_publish&amp;#39;: &amp;#39;publishconf.py&amp;#39;,
    # Output path. Can be absolute or relative to tasks.py. Default: &amp;#39;output&amp;#39;
    &amp;#39;deploy_path&amp;#39;: SETTINGS[&amp;#39;OUTPUT_PATH&amp;#39;],
    # Remote server configuration
    &amp;#39;ssh_user&amp;#39;: &amp;#39;you&amp;#39;,
    &amp;#39;ssh_host&amp;#39;: &amp;#39;yoursite.com&amp;#39;,
    &amp;#39;ssh_port&amp;#39;: &amp;#39;22&amp;#39;,
    &amp;#39;ssh_path&amp;#39;: &amp;#39;/var/www/yoursite/html&amp;#39;,
    # Port for `serve`
    &amp;#39;port&amp;#39;: 8000,
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Be sure to check the ssh lines in particular. The &lt;code&gt;ssh_path&lt;/code&gt; was not right for mine, probably from when I ran &lt;code&gt;pelican-quickstart&lt;/code&gt;.&lt;/p&gt;

	&lt;p&gt;Once you start using invoke, you can simply type:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;invoke reserve&lt;/code&gt; which builds, then serves.&lt;br /&gt;
&lt;code&gt;invoke publish&lt;/code&gt; which builds using &lt;code&gt;publishconf.py&lt;/code&gt;, then runs &lt;code&gt;rsync&lt;/code&gt; to your server.&lt;/p&gt;

	&lt;p&gt;I&amp;#8217;ll have to see if I can automate my Mercurial committing and pushing using invoke, next.&lt;/p&gt;

	&lt;p&gt;Here is the relevant section from the pelican documentation: &lt;a href="https://docs.getpelican.com/en/latest/publish.html#invoke"&gt;invoke&lt;/a&gt;&lt;/p&gt;</content><category term="web"></category><category term="pelican"></category><category term="blogging"></category><category term="tips"></category></entry><entry><title>Get a Daily Email Report of Your Website Visitors</title><link href="https://simonh.uk/2021/05/01/get-a-daily-email-report-of-your-website-visitors/" rel="alternate"></link><published>2021-05-01T00:00:00+01:00</published><updated>2021-05-01T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-05-01:/2021/05/01/get-a-daily-email-report-of-your-website-visitors/</id><summary type="html">	&lt;p&gt;apache2 and goaccess analytics to your inbox&lt;/p&gt;</summary><content type="html">	&lt;h2&gt;It&amp;#8217;s too easy not to!&lt;/h2&gt;

	&lt;p&gt;If you haven&amp;#8217;t already:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;# apt install goaccess&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Then, create &lt;code&gt;/etc/cron.daily/apache_report&lt;/code&gt; with the following contents&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
goaccess /var/log/apache2/other_vhosts_access.log --log-format=VCOMBINED -o report.html
gzip report.html
echo &amp;quot;Report&amp;quot; | mail -s &amp;quot;Apache Report&amp;quot; -A report.html.gz you@yourdomain.com&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Remember to change the email address to &lt;em&gt;your&lt;/em&gt; email address &lt;/p&gt;

	&lt;h2&gt;tips&lt;/h2&gt;

	&lt;p&gt;Instead of waiting a day to find out if the script is working correctly, you can copy &lt;code&gt;apache_report&lt;/code&gt; to &lt;code&gt;/etc/cron.hourly&lt;/code&gt; and then &lt;code&gt;cd&lt;/code&gt; into it and run:&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;# run-parts .&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;If all went well, you should have a new email with a nicely formatted html report.&lt;/p&gt;

	&lt;p&gt;Remember to delete the script from &lt;code&gt;/etc/cron.hourly&lt;/code&gt; or you&amp;#8217;ll have a full inbox!&lt;/p&gt;

	&lt;p&gt;Also, I&amp;#8217;m assuming that you&amp;#8217;re using virtual hosts in Apache. If not, you can reference &lt;code&gt;access.log&lt;/code&gt; instead of &lt;code&gt;other_vhosts_access.log&lt;/code&gt;&lt;/p&gt;</content><category term="web"></category><category term="apache2"></category><category term="httpd"></category><category term="mail"></category></entry><entry><title>Tips for Your First Blog</title><link href="https://simonh.uk/2021/04/26/tips-for-your-first-blog/" rel="alternate"></link><published>2021-04-26T00:00:00+01:00</published><updated>2021-04-26T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-04-26:/2021/04/26/tips-for-your-first-blog/</id><summary type="html">	&lt;p&gt;You&amp;#8217;ve got a blog, but, now what&amp;#8230;?&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Man at Typewriter" src="/img/2021-04-26/typewriter.webp" title="Man at Typewriter" /&gt;&lt;/p&gt;

	&lt;h2&gt;Don&amp;#8217;t get distracted&lt;/h2&gt;

	&lt;p&gt;When you use a static site generator or a &lt;span class="caps"&gt;CMS&lt;/span&gt; for your blog, you&amp;#8217;ll quickly find there are &lt;em&gt;enormous&lt;/em&gt; opportunities for theming and customising. In fact, if you&amp;#8217;re not careful, you won&amp;#8217;t have time for anything else. Themes in particular, can have you downloading half the internet. &lt;/p&gt;

	&lt;p&gt;My advice (if you&amp;#8217;re using Pelican) is to click this link on &lt;a href="https://github.com/search?o=desc&amp;q=pelican+themes&amp;s=updated&amp;type=Repositories"&gt;github&lt;/a&gt;. This will show you all Pelican themes that have been recently updated. This is how I found the theme I&amp;#8217;m using here. Thanks, by the way to &lt;a href="https://thebouv.com/"&gt;Anthony Bouvier&lt;/a&gt; who converted this theme from Hugo. It&amp;#8217;s simple, responsive and fast. And that&amp;#8217;s all I (or you) need.&lt;/p&gt;

	&lt;h2&gt;Focus on writing content&lt;/h2&gt;

	&lt;p&gt;Since you&amp;#8217;ve decided to start blogging, I assume you&amp;#8217;ve got things to say?! Personally, I think a blog has value even if nobody ever knows it, or you, exist. Writing is a skill which only gets better with practice. So if you want to write about something but aren&amp;#8217;t sure if anyone else will be interested &amp;#8212; just write it and throw it out there. &lt;/p&gt;

	&lt;h2&gt;Don&amp;#8217;t obssess about &lt;span class="caps"&gt;SEO&lt;/span&gt;&lt;/h2&gt;

	&lt;p&gt;Let&amp;#8217;s face it, neither one of our sites will ever be massive. We&amp;#8217;ve got some things to say and we&amp;#8217;re saying them. Occasionally, we might write a tutorial that gets a bit of traction, but generally things are quiet. Fine by us! After some time blogging, we might set up another one which is focused on making money in some way, but for the moment, we&amp;#8217;re just writing and posting stuff. By all means go to one of the many sites for a &lt;span class="caps"&gt;SEO&lt;/span&gt; check, Bing and Google both do this. But you can always start writing and fix the technical issues when you&amp;#8217;ve got more knowledge.&lt;/p&gt;

	&lt;p&gt;I have Analytics on this site, but it&amp;#8217;s not really needed. I&amp;#8217;ll probably start parsing the Apache logs directly at some point. &lt;/p&gt;

	&lt;h2&gt;Provide value&lt;/h2&gt;

	&lt;p&gt;A short aside. Last year, my partner got very ill and nearly died. She has a Facebook account (I don&amp;#8217;t), and so I asked people to pray for her. Out of courtesy I let them know her status the following day and got lots of comments asking me to keep them updated. So I did. Every day I made a post, often long and detailed about her progress and what I was doing, how the kids were doing, etc. &lt;/p&gt;

	&lt;p&gt;What amazed me was how people responded. After posting, I&amp;#8217;d get messages saying &amp;#8220;I&amp;#8217;ve been looking forward to your daily updates. Keep it up!&amp;#8221; The support was incredible.&lt;/p&gt;

	&lt;p&gt;My point? Even though I had no idea, our story was somehow &lt;em&gt;interesting&lt;/em&gt; to other people. Lots of people. So even if you think something might be boring, you might be completely wrong. &lt;/p&gt;

	&lt;h2&gt;Stay away from controversial topics&lt;/h2&gt;

	&lt;p&gt;It&amp;#8217;s really not worth your trouble. Not yet anyway. Keep things nice and cheerful. Professional, almost. We all have strong opinions about certain things, but let&amp;#8217;s keep our blog cheerful. Remember, what you write could be here forever. &lt;/p&gt;

	&lt;h2&gt;Writing tips&lt;/h2&gt;

	&lt;p&gt;Writing can be hard or easy. It may depend on your level of interest and knowledge of the topic. When I&amp;#8217;m writing a post like this one which is an informative post, I&amp;#8217;ll start off with all my headings. That&amp;#8217;s how my mind works; from broad to specific. Your mind may be set up differently though, and you might want to start writing until you&amp;#8217;re done. Only time will tell what works best for you. &lt;/p&gt;

	&lt;p&gt;Ultimately, you must sit down and start writing though. I like pretty short and direct writing as I assume anyone reading my stuff is no fool. Their time is valuable and I don&amp;#8217;t want to waste it. So keep waffle to a minimum, please.&lt;/p&gt;

	&lt;h2&gt;Be organised&lt;/h2&gt;

	&lt;p&gt;I started emailing myself a while ago if I have a good idea that I can&amp;#8217;t deal with at the time. Not only for blogging, but in general. You may prefer a notebook or a dictaphone (voice recorder). Now that you&amp;#8217;re a writer, you need to capture those thoughts as they tend to evaporate within a few minutes.&lt;/p&gt;

	&lt;h2&gt;Good luck!&lt;/h2&gt;

	&lt;p&gt;And as always, my email is below if you&amp;#8217;ve got something to say.&lt;/p&gt;</content><category term="web"></category><category term="blogging"></category><category term="pelican"></category><category term="tips"></category><category term="writing"></category></entry><entry><title>Fix Your Email Address by Getting a Domain Name</title><link href="https://simonh.uk/2021/04/25/fix-your-email-address-by-getting-a-domain-name/" rel="alternate"></link><published>2021-04-25T00:00:00+01:00</published><updated>2021-04-25T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-04-25:/2021/04/25/fix-your-email-address-by-getting-a-domain-name/</id><summary type="html">	&lt;p&gt;Email addresses should be memorable and personal&lt;/p&gt;</summary><content type="html">	&lt;p&gt;Hi simon_harrison189@myemailprovider.com&lt;/p&gt;

	&lt;p&gt;Ugh.&lt;/p&gt;

	&lt;p&gt;It still amazes me when someone gives me an email address like the above. For the sake of a tenner a year, you can have your own memorable, personalised email.&lt;/p&gt;

	&lt;p&gt;A site that is really good for searching multiple domains is &lt;a href="https://netim.com"&gt;netim.com&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;Here&amp;#8217;s a partial result for European domains for simonharrison:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="simonharrison domains" src="/img/2021-04-25/simonharrison_domains-fs8.png" title="simonharrison domains" /&gt;&lt;/p&gt;

	&lt;p&gt;simonharrison too long? Of course it is. Let&amp;#8217;s try simonh:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="simonh domains" src="/img/2021-04-25/simonh_domains-fs8.png" title="simonh domains" /&gt;&lt;/p&gt;

	&lt;p&gt;These are only a small proportion of the results. The domains are split into geographical regions. Here is what we get for Oceania:&lt;/p&gt;

	&lt;p&gt;&lt;img alt="simonh oceania" src="/img/2021-04-25/simonh_oceania-fs8.png" title="simonh oceania" /&gt;&lt;/p&gt;

	&lt;p&gt;I think you get the point. &lt;/p&gt;

	&lt;p&gt;&lt;code&gt;mail@simonh.be&lt;/code&gt; is far better than &lt;code&gt;simon_harrison189@myemailprovider.com&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;The other major benefit is that once you&amp;#8217;ve registered a domain name, you can forward emails to your awful &lt;code&gt;simon_harrison189@myemailprovider.com&lt;/code&gt; mail account. This way, you&amp;#8217;ll only ever need one email address. I&amp;#8217;ve been doing this since 2002!&lt;/p&gt;

	&lt;p&gt;As to which domain registrar to use, I use &lt;a href="https://www.ovh.co.uk/"&gt;ovh&lt;/a&gt; and &lt;a href="https://www.fasthosts.co.uk/"&gt;fasthosts&lt;/a&gt;. Make sure to shop around and compare prices before you sign up. &lt;/p&gt;</content><category term="web"></category><category term="web"></category><category term="mail"></category></entry><entry><title>Email for Static Website Commenting</title><link href="https://simonh.uk/2021/04/24/email-for-static-website-commenting/" rel="alternate"></link><published>2021-04-24T00:00:00+01:00</published><updated>2021-04-24T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-04-24:/2021/04/24/email-for-static-website-commenting/</id><summary type="html">	&lt;p&gt;I think I might be on to something here&amp;#8230;&lt;/p&gt;</summary><content type="html">	&lt;p&gt;A few months ago, when I resurrected this blog, I decided to put a link at the bottom of each post to let interested readers send me a comment by email. Nothing fancy, just a &lt;code&gt;mailto&lt;/code&gt; with the post title as the subject. I haven&amp;#8217;t had any replies yet, nor any spam, but I&amp;#8217;m surprised it isn&amp;#8217;t more widespread what with the uptake of static site generators.&lt;/p&gt;

	&lt;p&gt;Have I missed something?&lt;/p&gt;

	&lt;h2&gt;Benefits&lt;/h2&gt;

	&lt;ul&gt;
		&lt;li&gt;No need for a new account or a new service. Just utilise the email address &lt;em&gt;everyone&lt;/em&gt; has&lt;/li&gt;
	&lt;/ul&gt;

	&lt;ul&gt;
		&lt;li&gt;There are loads of programs for handling email, detecting spam etc.&lt;/li&gt;
	&lt;/ul&gt;

	&lt;ul&gt;
		&lt;li&gt;It wouldn&amp;#8217;t be too hard to have some email processing scripts on your server to regenerate the page when a comment comes in. A sort of static / dynamic website hybrid&lt;/li&gt;
	&lt;/ul&gt;

	&lt;ul&gt;
		&lt;li&gt;For sites interested in having / building a mailing list, surely this would be the easiest way to get email addresses (with the users permission, obviously)&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;I&amp;#8217;m honestly surprised that if I search for &amp;#8216;static site commenting&amp;#8217; the first result is not:&lt;/p&gt;

	&lt;p&gt;Email&lt;/p&gt;

	&lt;p&gt;Seriously, send me an email if you disagree!&lt;/p&gt;</content><category term="web"></category><category term="pelican"></category><category term="mail"></category><category term="web"></category></entry><entry><title>Pelican Static Paths for Extra / Other Content</title><link href="https://simonh.uk/2021/04/24/pelican-static-paths-for-extra-other-content/" rel="alternate"></link><published>2021-04-24T00:00:00+01:00</published><updated>2021-04-24T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-04-24:/2021/04/24/pelican-static-paths-for-extra-other-content/</id><summary type="html">	&lt;p&gt;Go beyond posts and pages with &lt;span class="caps"&gt;STATIC&lt;/span&gt;_PATHS&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Pelican Logo" src="/img/logo/pelican.webp" title="Pelican Logo" /&gt;&lt;/p&gt;

	&lt;p&gt;I like to have a few directories on my web server for easy access from anywhere. Most importantly, &lt;code&gt;/files/&lt;/code&gt; &lt;/p&gt;

	&lt;p&gt;Of course, Pelican can handle such things. All you need to do is set &lt;code&gt;STATIC_PATHS&lt;/code&gt; in your pelicanconf.py&lt;/p&gt;

	&lt;p&gt;&lt;code&gt;STATIC_PATHS = ['files', 'share', 'public', 'docs']&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;And make sure your static directory is within &lt;code&gt;content&lt;/code&gt; like below:&lt;/p&gt;

	&lt;p&gt;content                                                                         &lt;br /&gt;
├── first post.textile                                             &lt;br /&gt;
├── second post.textile                                                &lt;br /&gt;
├── number three.textile                             &lt;br /&gt;
├── files&lt;br /&gt;
│   └── some document.pdf&lt;br /&gt;
├── pages&lt;br /&gt;
│   ├── about.textile&lt;br /&gt;
│   ├── contact.textile&lt;br /&gt;
│   ├── links.textile&lt;/p&gt;

	&lt;p&gt;Pelican will nicely copy these static files from &lt;code&gt;content&lt;/code&gt; to &lt;code&gt;output&lt;/code&gt; without processing them in any way.&lt;/p&gt;

	&lt;p&gt;See here for more details: &lt;a href="https://docs.getpelican.com/en/latest/content.html#static-content"&gt;Pelican Docs&lt;/a&gt;&lt;/p&gt;</content><category term="web"></category><category term="pelican"></category><category term="web"></category><category term="software"></category></entry><entry><title>Why You Should Always have a Static Personal Website</title><link href="https://simonh.uk/2021/04/22/why-you-should-always-have-a-static-personal-website/" rel="alternate"></link><published>2021-04-22T00:00:00+01:00</published><updated>2021-04-22T00:00:00+01:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2021-04-22:/2021/04/22/why-you-should-always-have-a-static-personal-website/</id><summary type="html">	&lt;p&gt;Speed, Simplicity, Security, Portability, Control&lt;/p&gt;</summary><content type="html">	&lt;h2&gt;Where I show that only a static website gives you&lt;/h2&gt;

	&lt;ul&gt;
		&lt;li&gt;Speed&lt;/li&gt;
		&lt;li&gt;Simplicity&lt;/li&gt;
		&lt;li&gt;Security&lt;/li&gt;
		&lt;li&gt;Portability&lt;/li&gt;
		&lt;li&gt;Control&lt;/li&gt;
	&lt;/ul&gt;

	&lt;h2&gt;But, I&amp;#8217;m on Facebook, Linkedin etc&amp;#8230;&lt;/h2&gt;

	&lt;p&gt;Sorry to have to inform you, but the corps don&amp;#8217;t care about you. At all. &lt;/p&gt;

	&lt;p&gt;Say the wrong thing, write the wrong thing, even &lt;em&gt;like&lt;/em&gt; the wrong thing, and you could be deleted. Many people have. Or, one day they could go the way of the dodo. Along with all your content. Look up Myspace or Google+ if you didn&amp;#8217;t live through those messes.&lt;/p&gt;

	&lt;p&gt;Also, ask yourself &amp;#8212; what value do you get from these platforms? &lt;/p&gt;

	&lt;p&gt;If you do use these types of sites, be sure to drive visitors to your website. Use them as a bypass to &lt;em&gt;your&lt;/em&gt; website. Linger on those sites for as little time as possible. &lt;/p&gt;

	&lt;h2&gt;I use Wordpress, Wix, Medium etc&amp;#8230;&lt;/h2&gt;

	&lt;p&gt;These all have advantages &amp;#8212; lots of options, commenting, seo optimizations (all the bells &amp;amp; whistles). &lt;/p&gt;

	&lt;p&gt;But, do you really need all that for a &lt;em&gt;personal&lt;/em&gt; site? And remember, if you use a companies platform, you no longer have control over your content. Effectively, you&amp;#8217;re at their mercy as you are on the social media platforms! Self hosting a &lt;span class="caps"&gt;CMS&lt;/span&gt; is different of course, but you still have the complexity problem (setting everything up, security, site maintenance, upgrades).&lt;/p&gt;

	&lt;h2&gt;Tell me about static sites then&lt;/h2&gt;

	&lt;p&gt;Glad you asked! Static websites are simply html documents served by your http server (Apache, Nginx). For the last few years, most of us use Static Site Generators, such as &lt;a href="http://getpelican.com"&gt;pelican&lt;/a&gt; that I&amp;#8217;m using for this site. These tools generate the html on our behalf and create rss / atom feeds, sitemaps (loved by search engines), handle pagination and lots of other things.&lt;/p&gt;

	&lt;p&gt;But, at it&amp;#8217;s core, it&amp;#8217;s just html. So, if you fall out with your web hosting provider, you just dump your entire site (a directory) on another server. No faffing about with databases, and minimal configuration of any kind. &lt;/p&gt;

	&lt;p&gt;Plus, static sites work great with revision control tools like &lt;span class="caps"&gt;CVS&lt;/span&gt;, Mercurial or Git. I may do a post on this another day. &lt;/p&gt;

	&lt;h2&gt;Are they suitable for business use?&lt;/h2&gt;

	&lt;p&gt;Lots of companies have (re)realised the benefits of static websites. &lt;a href="http://gohugo.io/showcase"&gt;hugo&lt;/a&gt; has a showcase of sites created using it, as does &lt;a href="https://jekyllrb.com/showcase/"&gt;jekyll&lt;/a&gt;. So, yes. Definately  sutiable for business use.&lt;/p&gt;

	&lt;h2&gt;Which static site generator should I use?&lt;/h2&gt;

	&lt;p&gt;The primary reason why someone chooses one over another is the language they&amp;#8217;re written in. I&amp;#8217;m a Python guy primarily, so I use Pelican. &lt;/p&gt;

	&lt;p&gt;Honestly, they all do the job and having an abundance of choice is a good thing. I believe most of them allow you to import an existing site made by another site generator; similar to converting a Microsoft Word &lt;code&gt;.docx&lt;/code&gt; document to a Libreoffice Writer &lt;code&gt;.odt&lt;/code&gt; document. No big deal.&lt;/p&gt;

	&lt;h2&gt;Conclusion&lt;/h2&gt;

	&lt;p&gt;I wrote at the top that only static websites give you the following desirable features. I&amp;#8217;ll summarise them now:&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Speed&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Nothing is faster than just serving html. It&amp;#8217;s the original purpose of the web &amp;#8212; request a page, deliver the page. &lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Simplicity &amp;amp; Security&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;No databases, no logging users in and out. No caching. No need for https (even though it&amp;#8217;s best practice everywhere nowadays).&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Portability&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Your entire website is a single directory (usually). Back it up, move it from one host to another. It&amp;#8217;s just a folder.&lt;/p&gt;

	&lt;ul&gt;
		&lt;li&gt;Control&lt;/li&gt;
	&lt;/ul&gt;

	&lt;p&gt;Your website, your platform. Host it where you want, even from home if your &lt;span class="caps"&gt;ISP&lt;/span&gt; has ports 80 / 443 open. &lt;/p&gt;

	&lt;h2&gt;The End&lt;/h2&gt;

	&lt;p&gt;Thanks for reading, and as always, email me a comment using the link below if you&amp;#8217;ve something to say.&lt;/p&gt;</content><category term="web"></category><category term="pelican"></category><category term="websites"></category></entry><entry><title>Pre-compress gzip files with Apache</title><link href="https://simonh.uk/2020/02/05/pre-compress-gzip-files-with-apache/" rel="alternate"></link><published>2020-02-05T00:00:00+00:00</published><updated>2020-02-05T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2020-02-05:/2020/02/05/pre-compress-gzip-files-with-apache/</id><summary type="html">	&lt;p&gt;precompress gzip files with Apache&lt;/p&gt;</summary><content type="html">	&lt;p&gt;&lt;img alt="Apache httpd Logo" src="/img/logo/apache.svg" title="Apache httpd Logo" /&gt;&lt;/p&gt;

	&lt;p&gt;Taken from: &lt;a href="https://blog.desgrange.net/post/2017/04/10/pre-compression-with-gzip-and-brotli-in-apache.html"&gt;desgrange.net&lt;/a&gt; &lt;/p&gt;

	&lt;p&gt;Remember to &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod rewrite
sudo a2enmod headers
sudo apachectl configtest&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;in your &lt;code&gt;&amp;lt;VirtualHost&amp;gt;&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;Directory */path/to/my/blog/*&amp;gt;
    RewriteEngine on
    # Gzip
    # If the web browser accept gzip encoding… 
    RewriteCond %{HTTP:Accept-Encoding} gzip
    # …and the web browser is fetching a probably pre-compressed file…
    RewriteCond %{REQUEST_URI} .*\.(css|html|js)
    # …and a matching pre-compressed file exists… 
    RewriteCond %{REQUEST_FILENAME}.gz -s
    # …then rewrite the request to deliver the gzip file
    RewriteRule ^(.+) $1.gz
    # For each file format set the correct mime type (otherwise gzip mime type is returned) and prevent Apache for recompressing the files
    RewriteRule &amp;quot;\.css\.gz$&amp;quot; &amp;quot;-&amp;quot; [T=text/css,E=no-brotli,E=no-gzip]
    RewriteRule &amp;quot;\.html\.gz$&amp;quot; &amp;quot;-&amp;quot; [T=text/html,E=no-brotli,E=no-gzip]
    RewriteRule &amp;quot;\.js\.gz$&amp;quot; &amp;quot;-&amp;quot; [T=application/javascript,E=no-brotli,E=no-gzip]
    &amp;lt;FilesMatch &amp;quot;\.(css|html|js)\.gz$&amp;quot;&amp;gt;
        # Serve correct encoding type
        Header set Content-Encoding gzip
        # Force proxies to cache gzip &amp;amp; non-gzip files separately
        Header append Vary Accept-Encoding
    &amp;lt;/FilesMatch&amp;gt;
&amp;lt;/Directory&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Whilst scouring the web for useful pelican plugins, I came across &lt;a href="https://github.com/getpelican/pelican-plugins/tree/master/gzip_cache"&gt;gzip_cache&lt;/a&gt;&lt;/p&gt;

	&lt;p&gt;The idea is that you have a precompressed html.gz / css.gz / js.gz files alongside your html / css / js files.&lt;/p&gt;

	&lt;p&gt;The above apache2 config &lt;strong&gt;should&lt;/strong&gt; get Apache to serve these already compressed files instead of compressing on the fly. &lt;/p&gt;</content><category term="web"></category><category term="pelican"></category><category term="web"></category><category term="apache"></category><category term="gzip"></category></entry><entry><title>Clunky way to use Rsync to update Static Site</title><link href="https://simonh.uk/2020/02/03/clunky-way-to-use-rsync-to-update-static-site/" rel="alternate"></link><published>2020-02-03T00:00:00+00:00</published><updated>2020-02-03T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2020-02-03:/2020/02/03/clunky-way-to-use-rsync-to-update-static-site/</id><summary type="html">	&lt;p&gt;While I investigate recommended permissions for /var/www&lt;/p&gt;</summary><content type="html">	&lt;h2&gt;A temporary fix&lt;/h2&gt;

	&lt;p&gt;In your working directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rsync -avc output/ example.com:~/tmp/simonh&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the remote dir from above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo rsync -r * /var/www/simonh.uk/html&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;It ain&amp;#8217;t pretty but it&amp;#8217;s working (at least)&lt;/p&gt;</content><category term="web"></category><category term="web"></category><category term="pelican"></category><category term="rsync"></category></entry><entry><title>Where is my name</title><link href="https://simonh.uk/2016/01/04/where-is-my-name/" rel="alternate"></link><published>2016-01-04T00:00:00+00:00</published><updated>2016-01-04T00:00:00+00:00</updated><author><name>Simon Harrison</name></author><id>tag:simonh.uk,2016-01-04:/2016/01/04/where-is-my-name/</id><summary type="html">&lt;p&gt;Getting your name on the first page&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Note: This post is from an old Pelican blog I used to have at simonh.me, which I found on a backup drive on 2025-01-07. It's probably of no use, but reposted for posterity!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;I haven't done much website stuff for quite a few years. So I set myself the goal of creating a few websites to get back into the swing of things. After a bit of research, I decided to use Pelican as it's fairly easy to get going with.&lt;/p&gt;
&lt;p&gt;I don't really have a plan for this site (yet), but I was pleasantly surprised to see my site listed on the fourth page of Google for the search term 'simonh' (after submitting it, of course). This was yesterday. Today, I'm the third result! I wondered how I'm doing for the term 'simon harrison'...&lt;/p&gt;
&lt;p&gt;After going through fifteen(!) pages of search results, I gave up. I can only conclude, I don't exist. Boo hoo. Now, I know that certain organisations that provide results for web searches have changed things to avoid sites from appearing disproportionately high, but my name actually is, simon harrison. So why am I nowhere to be seen? It probably doesn't help that this domain doesn't have simonharrison in it. I noticed that the first four results do have the search term in the domain. &lt;/p&gt;
&lt;h2&gt;The Plan&lt;/h2&gt;
&lt;p&gt;I'm sure the &lt;em&gt;many&lt;/em&gt; other Simon Harrison's are just chuffed to say to their friends "Google Me". Hopefully, soon, I'll be saying the same thing :)&lt;/p&gt;</content><category term="web"></category><category term="web"></category><category term="seo"></category><category term="archived"></category></entry></feed>