How it started vs. How it's going - www.benrowland.net

Too long ago in 2004, this website started. I vividly recall the satisfaction when I typed www.benrowland.net into a browser, and it worked. I ran the website on Tomcat running in a DOS window on my Windows desktop, so it wasn't quite a production-grade deployment. I had pointed my domain name to the IP address allocated to my home computer by my ISP, and there was something magical about watching the internet routing happen the way I'd hoped it would.

But I was more interested in learning about software development than having a stable website, so sometimes the site was up, sometimes it was down, and sometimes half-way inbetween.

Self-hosting taught me a lot. One morning I checked the site, and saw a big angry error page. By this point I was running Linux on my desktop computer, and at some point I'd upgraded and selinux had been activated without me knowing at the time. This is effectively an internal firewall, and was blocking communication between the Apache web server and the Tomcat back-end application container. This sort of thing would happen a lot. Something would go bump in the night, I'd wake up to an error page. I'd Google the error and troubleshoot just to get the site running again.

I was also running an SSH server which allowed me to log in to my computer from anywhere on the internet. This meant there were continual attempts to log in from random hackers all over the world. Of course, I had a secure password so none of these attempts succeeded. At first, I worried about these attempted hacks until I learned this is completely normal, and expected to happen - hackers will port-scan an entire IP range looking for an open port 22, and they will script login attempts using common bad passwords in the hope to find some low-hanging fruit. My logs would be filled up with these failed login attempts until I learned the best practice - use key-based authentication and disallow password logins.

Eventually, the continual trouble-shooting became too much (as well as the need to leave my noisy desktop computer running 24 hours a day). I took the plunge and signed up for a hosting plan. Now my website was running in a datacentre somewhere, instead of under my desk. But this turned out to be expensive - hosting plans which supported Java applications were more expensive than the Apache/PHP alternatives. I'm not sure why - perhaps the additional memory usage of Java web application containers meant less customer deployments could run on a single host.

The cost commitment became hard to justify so I cancelled the plan. I think this website was unavailable for a long time, though of course I still had ownership of the domain.

Things came around again later on, and I got interested in self-hosting again. This time, using a small net-top mini computer which was effectively silent. At this point, I'd gone to Wordpress as a platform as it was much more flexible and secure than my hobby application, and I didn't want to spend all my time maintaining my own blogging software. This was a great way to learn about containerisation. I was running CoreOS which is designed for hosting containers, and was experimenting with running different domains within different containers. I used Nginx Reverse Proxy to route different subdomain names to the appopriate container, each running an Apache instance with a matching virtual host. This spawned an interesting deep-dive into traffic routing with Docker, such as how to serve the front- and back-end of an application from different containers.

For one reason or another, that particular journey lost momentum and the site was undeployed for another year or so. As of sometime in early 2020 the needle has swung back towards using a hosting provider, and this time it's Google Cloud. The site is now generated using Hugo site templates. This more closely matches my intentions for the site at this time - relatively simple content with no need for the features Wordpress provides. Wordpress attracts hacking attempts as it's a very popular platform with known administration endpoints, and so there's definitely a need to follow software updates carefully, as security holes get fixed. Not so with Hugo, as you generate a static website offline from Markup, using some Go scripts.

So now, the site is deployed to a Google Cloud Bucket, which is effectively like Amazon S3. Up until recently there was no HTTPS support, and this was because my domain name was just a CNAME pointing to the GC bucket domain which the content was hosted on. HTTPS connections were not supported by this method, and it took me a little while to figure out how to do it.

At first, I thought I needed an additional CloudFront deployment in front of the GC bucket - this sounded like overkill for what I really needed. Fortunately, I searched again more recently and found that you can easily solve this problem in the Google Cloud UI. You set up a front-end HTTP load balancer with a static IP address, and also a HTTPS front-end which redirects to the former. You then provision a SSL certificate - also easy enough to do within the Google Cloud dashboard. The HTTP front-end can then be pointed at the existing back-end cloud bucket.

This isn't supposed to be an advert for Google Cloud, and indeed there is a downside - there are ongoing costs with this approach. There's a “Global Forwarding Rule Minimum Service Charge”, which works out at maybe £10 or so per month. It can be a bit hard to figure out up-front what your costs are going to be with Google Cloud, but I'm not surprised there would be some sort of cost associated with a permanently allocated static IP address. You need one of these as you need something permanent to point your domain A record to.

Technically though, you aren't charged for a static IP address as long as it's attached to a global forwarding rule, but you do pay for that! You're allowed up to 5 global forwarding rules with the same minimum cost, so I'm at the worst-case for utilisation right now. Ideally, I'd find a reason to set up 4 more domain names under the same account, and it would cost the same as I'm paying now. The alternative is something like Amazon's Route 53, which dynamically resolves domain routing to changing IP addresses. That's an option to look into later on - I have played around a small amount with AWS but never deployed anything yet (outside of work).

I don't think this setup on Google Cloud is too bad. Hopefully I have room to do a lot more without additional cost. I could set up a few more back-ends on their own domains, perhaps even running some fuctional apps. I have an application I'm working on to track daily activities, and eventually I want to deploy this somewhere - but that's for another post.

Developing Your Musicianship - Course 4 of 4

Here's the final “Capstone” composition project for the Developing Your Musicianship course.

It took me over a year to pick up the final part of this four-part course, despite so much enthusiasm to work on this “Capstone” project which was supposed to sum up what I'd learned so far. Part of the reason for the long hiatus was that at the time I wasn't resonating with the restrictions placed on what you can write.

The end result is nothing I'd ever listen to or feel much personal connection to. It sounds more like a TV theme than anything else! But I did have some fun with the off-beat rhythm in the main section, which perhaps gives it some identity. I also really enjoyed stumbling on the surprising chord change (borrowed from the parallel minor key) just before the quieter B-section. There's also a rhythmic change on the surprising chord - it comes a little early to heighten the surprise. If the piece ended by sustaining that surprising chord, it would definitely be reminiscent of a 1980s US TV sit-com scene transition. But maybe that's just me.

Despite feeling a bit cold to the whole accidental TV theme which came out of this project, there was plenty of value in putting a piece of music together and recording it.

Spring Boot, Gradle and Java 11

When upgrading a hobby Spring Boot project to Java 11, there were a few issues which reminded me of how closely related Gradle, the Spring Boot plugin, and the java version you're using are. Naively trying a gradlew bootRun on the project (which was using Gradle 3.1) resulted in this: Could not determine java version from '11.0.5' Fortunately I'd seen that one before, so I upgraded my version of Gradle to 5.

HTTPS and Java - Pitfalls and Best Practices - Part 1

As software developers, we often want to talk to services over the internet, usually using HTTP. However, it’s now very common to see online services using HTTPS – an extension of HTTP which enables secure communications over a network. This move has made life more interesting for developers who want to interact with these services. Most of the time, connecting to a host over HTTPS “just works” from Java, but sometimes things don’t quite work … and Java can be a bit cryptic in how it reports the failure.

HTTPS and Java - Pitfalls and Best Practices - Part 2

Chain of Trust When a Java program connects to a host over HTTPS, it’s important to know you’re really communicating with who you think you are. If I write a program which connects to https://www.example.com, then I’m sending information over a secure channel. How can I be sure I’m not talking to a malicious third party who is somehow intercepting my traffic, such as user credentials? The identity of a server is proven with certificates.

HTTPS and Java - Pitfalls and Best Practices - Part 3

Ciphers So far, we’ve looked at how certificates can support the Authentication property of HTTPS. The certificate also enables a second property of HTTPS – Encryption of the traffic. This encryption is possible because the certificate contains a public key which allows clients to encrypt data, so only those holding the corresponding private key (the website owner) will be able to decrypt. This encryption is achieved using ciphers. There may be a range of ciphers available on both ends of the connection, and the cipher chosen for the communication will be agreed in the initial TLS handshake.

HTTPS and Java - Pitfalls and Best Practices - Part 4

Perfect Forward Secrecy At the present time, with the possibility of data breaches and digital eavesdropping, privacy is an important subject. What’s to prevent a malicious third-party from collecting traffic going to or from a website? It might seem adequate to use HTTPS to encrypt traffic to a website, meaning it’s impossible to decrypt the traffic unless you also have access to the private key. But what if a malicious actor collects encrypted traffic over a long period of time?

Developing Your Musicianship - Course 1 of 4

I spent some time in early 2019 learning more about music composition.

I found a four-part course from Coursera called Developing your Musicianship. This course looked particularly interesting because it went beyond the basics into more interesting subjects such as extended chords.

It's a four-part course, and I was most interested in parts 3 and 4. I couldn't access these parts until I'd completed the first two, so I did need to review some familiar material. It was worthwhile as it gave me good experience writing and finishing composition projects.

Here was the output of part 1 - a twelve-bar Blues progression.