Inspiration

When preparing to hike the Pacific Crest Trail (PCT), I knew I wanted to record my adventures somewhere, some way, some how. At the time, it wasn’t really important to me if it were open to the public or not, but I wanted my friends & family to be able to follow along. If nothing else, the social accountability would keep me writing :-)

I had a vision of what I wanted, and had a requirements list that looked like this:

  • Must be able to be updated offline
    • Of course I can’t publish when offline, but I need to be able to write full posts offline and have them sync/post with the original timestamps when I’m back online.
  • Must have an Android app
  • Must be able to restore to a new phone (in case mine falls off a cliff or something)
  • Must be able to attach my current location
  • Nice to have the ability to fuzz my location for a period of time
  • Must be free for readers .. and ideally me

I took this list of requirements and went shopping. I looked at Wordpress (custom blog and/or their commercial offerings), Medium, Jekyll, and a bunch of others. They all came up short in some way or another.

So, I went ahead and did the dumbest thing possible: I decided that in my last few months, I was going to spin up an entire backend, web frontend, and custom Android app.

And then rely on it with virtually no testing, and no way of fixing it. What could go wrong?

Iterations

Over the years, the app has gone through many iterations. The end result is basically still the same, but the under-the-hood implementations have changed as my needs have evolved.

Version 1 (~2016)

The initial version was only for the PCT – a single trip. It was built on Google App Engine (GAE), using Java. The web frontend was rendered using J2EE or something else terrible. However, it was the hammer I knew, and time was very much not on my side.

Behind the GAE backend was a database of some kind – it doesn’t matter, because it’s not even supported by Google anymore.

This database was updated by an Android app that I had written, which could compose posts, attach pictures & captions, attach a location (populated while writing the app), and save to a Protocol Buffer. When I was online, I could then trigger a sync and have everything upload to the backend, which would unpack the data and store it in the database.

When the website was rendered, it would see whether a given post was visible yet. Each post had an “authored” time and a “visible” time – by default, the “visible” time was 48 hours after the “authored” time.

Nothing was cached, the app did disk read/write on the UI thread, and everything was terrible. But it worked.

About halfway through the trip, however, the web frontend completely collapsed. I had been resizing images at serve-time, and the page had been getting slower and slower and slower, and eventually exceeded GAE’s serving limits. I was in the wilderness with just my phone and no automated deployments, so .. well, too bad. I could still upload data, so that’s what I did.

Version 1.1 (~2017)

Shortly after that, I was scheduled to meet some friends in Lake Tahoe as I passed through. I asked one of them to bring a computer that I could borrow for an hour to fix my site, and he did, and I did. I just added some caching to the image-resizing bit of logic and that was sufficient to get the site loading again.

I resumed my hike and it happily limped along (as did I, in real life), and it worked for the rest of the hike.

Version 2 (~2017)

Once I was back in civilization, I had another trip fast-approaching. This was another trip down the Grand Canyon, and I wanted to chronicle this new adventure on my old platform. The old version, however, didn’t support more than one trip – the entries weren’t namespaced!

With time again not on my side, I got to work shoe-horning in multi-trip support. It was completed in time for my new trip, and I even set up redirects for all of the old posts so that no one would be upset!

The Android app got zero love, however. No one used this except for me.

Version 3 (~2019)

After I moved to Norway, I wanted to continue to update my friends & family back home on my adventures. I was also now a professional web developer, so I was a little embarrassed to have such a terrible site.

I eventually rewrote the app in Next.js, leveraging a [Firebase] database for the backend. This time, however, the site would be statically rendered, since it doesn’t change very often.

Version 4 (~2025)

The current version is now rewritten using Hugo, served just from Markdown files in a private GitHub repo. I don’t need much location-fuzzing these days, and I don’t have any long trips planned. However, I wanted to learn more about Hugo and drop the React-based static site, so I rewrote it again.

At this point, the entire “admin” (content management) aspect is gone – no longer are there separate apps. Well, it’s just any Markdown editor, I guess.

Reflections

In the end, it worked out well enough. I would do things a lot differently today (like set up automated deployments), but this was honestly good enough for what I needed it to do.

I’m still pleased with it :-)