summaryrefslogtreecommitdiffstats
path: root/content/post/how-this-blog-works
diff options
context:
space:
mode:
Diffstat (limited to 'content/post/how-this-blog-works')
-rw-r--r--content/post/how-this-blog-works/index.org229
1 files changed, 229 insertions, 0 deletions
diff --git a/content/post/how-this-blog-works/index.org b/content/post/how-this-blog-works/index.org
new file mode 100644
index 0000000..d48dd37
--- /dev/null
+++ b/content/post/how-this-blog-works/index.org
@@ -0,0 +1,229 @@
+#+TITLE: Creating Self-Hosted Hugo Blog with OpenBSD
+#+DATE: 2020-06-17T21:03:26-04:00
+#+DRAFT: true
+#+DESCRIPTION:
+#+TAGS[]: hugo openbsd
+#+KEYWORDS[]:
+#+SLUG:
+#+SUMMARY:
+
+When creating this blog, there were a couple of factors I kept in mind
+while trying to figure out how I was going to set it up. Here's an
+approximate list:
+
+- Simple
+- Version controlled
+- Easy to host on OpenBSD
+- Minimal maintenance
+- Good integration with Emacs
+
+That's how I came up with what I currently use. Let me walk you
+through how I run by blog.
+
+* Framework
+
+ The blog engine is [[https://gohugo.io/][hugo]], a static site generator. I chose this over
+ something dynamic like wordpress for several reasons.
+
+ First of all, it's very easy to manage, blog posts are just simple
+ files written in one of the markup languages hugo supports. Being
+ statically generated is also a massive advantage in terms of
+ maintenance. With something like wordpress, you have to be careful to
+ keep your site and plugins up to date.
+
+ Since there's no dynamic content generation or database involved with
+ hugo, the attack surface is dramatically decreased. No possibility for
+ SQL injection, PHP RATs, accidental shell access, or hacked
+ credentials. The entire site is generated using a single command after
+ a new post is created, and then moved to the web server's root
+ directory.
+
+ Being all flat files also means the entire thing can very easily be
+ tracked using =git= (or maybe [[https://gameoftrees.org/][got]], eventually), in fact that's the
+ recommended way to use hugo. There's no fear I'll accidentally delete
+ something, as I can always go back to a previous commit and restore
+ it.
+
+ Since hugo is written in go, it's trivial to compile on OpenBSD, and
+ is actually available directly from the OpenBSD package manager right
+ out of the gate.
+
+ Maybe the most important thing to be however, is that hugo natively
+ supports org-mode markup. I write all my notes, both personal and work
+ related, in org-mode. It makes converting my notes into blog posts
+ really easy. It also lets me leverage my existing Emacs setup, which
+ comes in handy often. While it's not very well documented, since
+ org-mode markup is a bit of a second class citizen in the hugo world,
+ it's pretty easy to figure out.
+
+* Prerequisites
+
+ This can be hosted on a very cheap VPS since it only has to serve
+ static pages. For OpenBSD hosting I would recommend either [[https://www.vultr.com/][Vultr]] or
+ [[https://openbsd.amsterdam/][OpenBSD Amsterdam]].
+
+** Server
+ The only thing that's required on the host server is =git=, although
+ you could even get away without that if you chose to host your git
+ repository elsewhere, like on github.
+
+ #+BEGIN_SRC shell
+ pkg_add git
+ #+END_SRC
+
+** Local machine
+ On the local machine you'll need both =git= and =rsync=. Both might
+ already be installed depending on the system you're on. If not,
+ check your package manager for details on how to install them. In
+ the case of Ubuntu or Debian it would be
+
+ #+BEGIN_SRC shell
+ sudo apt install git rsync
+ #+END_SRC
+
+ or for Fedora
+
+ #+BEGIN_SRC shell
+ sudo dnf install git rsync
+ #+END_SRC
+
+* Version Control
+
+ I wanted to try to keep things as simple as possible for this. The
+ "origin" for the blog is simply a bare git repository in the =blog=
+ user's home directory.
+
+** Setting up the blog user
+
+ First I set up the blog user
+ #+BEGIN_SRC shell
+ useradd -m blog
+ #+END_SRC
+
+ I then placed my public SSH key in its =authorized_keys= file
+
+ #+BEGIN_SRC shell
+ mkdir -m 700 /home/blog/.ssh
+ cp /root/.ssh/authorized_keys /home/blog/.ssh/
+ chown -R blog:blog /home/blog
+ #+END_SRC
+
+ I then logged in as the blog user and initialize the bare git
+ repository.
+
+ #+BEGIN_SRC shell
+ su blog
+ cd # cd with no arguments goes to home directory
+ git init --bare blog.git
+ #+END_SRC
+
+** Cloning the repository
+
+ Cloning the repository onto my local machine is very easy at this
+ point. As long as my private keys are in the =blog= user's
+ =authorized_keys=, git will take care of the rest.
+
+ #+BEGIN_SRC shell
+ # on my local machine
+ git clone blog@lambda.cx:blog.git
+ #+END_SRC
+
+ I can now work on the blog as I would any other git repository,
+ pulling with =git pull= and pushing with =git push=.
+
+* Web server
+
+ Since this blog is going to be hosted on OpenBSD, we don't need to
+ install a web server, as it already comes with one built in.
+
+ Setting up =httpd= couldn't be easier, the configuration syntax is
+ very straight forward. If you would like to see a full breakdown of
+ the options available, check out the man page with =man
+ httpd.conf=. The example configuration in =/etc/examples/httpd.conf=
+ is also a good starting point.
+
+ In this case the simplest configuration would be as follows
+
+ # js chosen for prism.js syntax highlighting
+ #+BEGIN_SRC js
+ server "blog.lambda.cx" {
+ listen on * port 80
+ root "/htdocs/blog.lambda.cx"
+ }
+ #+END_SRC
+
+ Despite how it looks, the =htdocs= folder doesn't reside in the
+ system root (=/=) directory. It actually lives in =/var/www/htdocs=,
+ and only appears that way because =httpd= gets automatically
+ =chroot='ed in =/var/www/= for security reasons.
+
+ For more information about how to set up SSL with Let's Encrypt,
+ check out [[{{< ref "post/letsencrypt-on-openbsd" >}}][this post]].
+
+* Using Hugo
+
+ There's not much to say here. Hugo's [[https://gohugo.io/][website]] has good documentation
+ on how to get started creating a blog using their program. I'll be
+ covering the intricacies of using org-mode with hugo in the future.
+
+* Deployment
+
+ The system used to deploy this blog is incredibly simple, involving
+ only =rsync=, =hugo=, and a small shell script.
+
+** Server
+ First you have to allow the =blog= user to write to the website
+ root. We'll do this by making it the owner of
+ =/var/www/htdocs/blog.lambda.cx=.
+
+ #+BEGIN_SRC shell
+ chown -R blog /var/www/htdocs/blog.lambda.cx
+ #+END_SRC
+
+** Local machine
+
+ This is the script used to deploy the website. It's placed in the
+ root of the hugo git repository.
+
+ #+BEGIN_SRC shell
+ #!/bin/sh
+ set -e
+
+ cd '$(dirname "$0")'
+ hugo
+ rsync -va --progress --rsync-path="/usr/bin/openrsync" public/ blog@lambda.cx:/var/www/htdocs/lambda.cx/blog
+ #+END_SRC
+
+ Going through it line by line:
+
+ - ~set -e~ Tells the shell to exit if any commands fail instead of
+ continuing execution. If ~hugo~ has a problem and exits with an
+ error, don't sync with the server.
+ - ~cd '$(dirname "$0")'~ Changes to the script's directory. This is
+ used in case you're running it from somewhere else.
+ - ~hugo~ Compile the website into static files located in the
+ =public= directory.
+ - ~rsync -va --progress --rsync-path="/usr/bin/openrsync" public/
+ blog@lambda.cx:/var/www/htdocs/lambda.cx/blog~ This one is bigger
+ so I'll break it down.
+ - =rsync= A command that synchronizes files between two directories
+ - =-v= Be verbose, this is optional but I like it
+ - =-a= Stands for "archive": copy recursively, keep
+ permissions, etc. See the =rsync= man page if you're curious.
+ - =--progress= Show progress, also optional
+ - ~--rsync-path="/usr/bin/openrsync"~ This line is very important
+ for OpenBSD servers. OpenBSD has its own =rsync= implementation
+ called =openrsync=. Without this argument, =rsync= will connect
+ to the server, see that the =rsync= command doesn't exist, and
+ fail.
+ - =public/= Specify which folder we want to sync. The trailing
+ =/= is important. Without it =rsync= will copy the folder
+ instead of the folder's contents, which is what we want.
+ - =blog@lambda.cx:/var/www/htdocs/lambda.cx/blog= Login to user
+ =blog= on server =lambda.cx=, syncing files with the
+ =/var/www/htdocs/lambda.cx/blog= directory.
+
+ The reason to use =rsync= here instead of something like =scp= is
+ that =rsync= won't upload files it doesn't need to, so if 3/4 of
+ the files didn't change when you updated the blog, it won't waste
+ time re-uploading them.