UPDATE: most of the cool stuff I talk about I put in the package webapp
on the Hackage.
The aspiring blogger uses a blogging platform like WordPress or Blogger to go from zero to blog in under thirty seconds. Most people can't code, and those who can usually want to use someone else's code anyway.
Fine. Use bad software if it makes you happy. Wordpress is a precarious concatenation of bunk so fragile, many devoted users will refuse to host them themselves. Nobody has time to appease Wordpress's byzantine architecture.
I want to skip the cruft and go straight for the kill; So I got out the serious programmer's weapons: Haskell & Linux. My solution is significantly better than WordPress on a technical level because it:
- compiles into a single executable
- providing daemonizing, SSL, IO redirection, and more
- is designed to be (type)safe and provable
- doesn't require a complicated environment
- uses software written by intelligent folks (a Berkeley professor wrote the markdown library I use)
The resulting executable manages to stand alone & accomplish what a massive environment fails to do cleanly. There are no interpreters, web servers, admin tools, caching databases, or dependencies needed to run the compilation result.
Before I overhauled my website, it ran using a collage of sub par software. For one, I had been using an unreliable daemonizing tool. Replacing it with Haskell code was trivial:
import Control.Monad (void)
import System.Exit
import System.Posix
daemonize :: FilePath -> IO () -> IO ()
daemonize pidFile program = void $ do
forkProcess $ do
createSession
forkProcess $ do
pidWrite pidFile
h <- openFile "/dev/null" WriteMode
hDuplicateTo h stdout
hDuplicateTo h stderr
hDuplicateTo h stdin
hClose h
installHandler sigHUP Ignore Nothing
program
exitImmediately ExitSuccess
exitImmediately ExitSuccess
But why stop at engulfing smaller ancillary tools, right? Using Redis for caching made me sad. Doing a Redis cache hit is extremely inefficient! So I wrote what's essentially a file-to-memory mapping using FSMonitor
and HashTable
. It leverages Haskell's laziness to provide zero latency as-needed read access to local files. Files can now be "read" incrementally as Warp needs them to construct HTTP responses.
There are two schools of thought on how to deploy such a creation:
- Managed servers (like Heroku)
- DIY servers (AWS, DigitalOcean)
Heroku deployment is easy:
- Set up an AWS bucket to cache build products
- Create a heroku app using Haskell on Heroku
- Set some ENV vars to leverage AWS and use newer GHC & cabal versions
git push heroku master
DIY servers are a bit more complicated, because you're reinventing Heroku.
First, you need a building server. You could use Halcyon, but I used git (and git hooks) receive & build my code without it. Maybe you'll use both. Who knows.
I'll leave exactly how you set it up to your imagination. I did something like:
git push > post-receive > GHC > ssh to production server > grant SETUID/SETGID
The last step is a little complicated; it requires you to write a C program that grants the desired permissions when ran by an underprivileged user. You need to have this C program be SETUID (or SETGID? it's late) to run as root and chmod
your app so it can bind to port 80/443. Have fun making that secure!
There's an obvious advantage to this setup: zero downtime. No production resources need to be diverted to build an executable, and no source code touches production. If you're set up right, there is no way to even see the source code from production! There is a cornucopia of security improvements you can make with this setup.
Great, so what's the point?
Now that you have your own (simple!) blog, you can make it do whatever you want easily. Key shortcuts? no problem. Change the layout? no plugins necessary. Add a tag cloud? about 50 lines of code. Gone are the days of having to research an idiosyncratic plugin API, write a mediocre hack, and pray it works as well as the rest of your blog (spoiler: it won't). Take responsibility for your own blog; don't leave your reputation in the hands of PHP idiots!
Like any worthwhile project, any blog you write (i.e. code up) will probably be neglected; such is the nature of fun projects. Enjoy implementing it, keep dreaming, and use it as an opportunity to hone your CS skills.
As for those looking for advice writing a blog post (probably thanks to a misleading title), go get an English degree!