Gerardo Zamudio about Linux, open source, and Internet

New Blog

After a week of testing and development, I've finally switched my site over to Jekyll, the static site generator. This allowed me to get rid of PHP and MySQL, which I feel cause too much overhead for a simple site like mine. I also felt Apache had too many features I did not use so I got rid of that and switched to nginx instead. Also note the TLD change, gerardozamudio.mx

Jekyll

The great thing about Jekyll is it's easy to use and configure. There's a great installation guide at the official Jekyll site already so I won't go over that again. Just note you'll need Node.js and Ruby installed in order for it to work.

First, I created the directory that will hold my new site in my shell user's home directory:

jekyll new ~/gerardozamudio.mx
cd ~/gerardozamudio.mx

My site used to run on WordPress so most of the content was stored in the MySQL database. I ran the Jekyll WordPress importer with the following options:

ruby -rubygems -e 'require "jekyll-import";
    JekyllImport::Importers::WordPress.run({
      "dbname"   => "wordpress-db",
      "user"     => "wordpress-user",
      "password" => "password",
      "host"     => "localhost",
      "socket"   => "/var/run/mysql/mysql.pid",
      "table_prefix"   => "wp_",
      "clean_entities" => true,
      "comments"       => true,
      "categories"     => true,
      "tags"           => true,
      "more_excerpt"   => true,
      "more_anchor"    => true,
      "status"         => ["publish"]
    })'

Note that Slackware uses the default PID location of /var/run/mysql/mysql.pid for MySQL so you'll have to set that. This gave me a nice structured directory with all my posts converted to Markdown complete with YAML Front Matter containing the author, comments, tags, etc. WordPress keeps images in /wp-content/uploads by default, but I made an images directory in the root of my site for simpler management, so a little sed magic fixed that:

find ./ -type f -exec sed -i -e 's|https://gerardozamudio.net/wp-content/uploads/|/images/|g' {} \;

I also noticed the posts had been saved with a .markdown extension. Those are not really important in Linux, but I wanted to fix them for my own sanity:

for file in *.markdown ; do mv "$file" "$(echo "$file" | sed 's/\(.*\.\)markdown/\1md/')" ; done

Then it was just a matter of downloading the uploads directory from wp-content in my WordPress site's root directory into my new Jekyll site's root directory and renaming it to images.

WordPress Features

There are some features of WordPress that Jekyll, being a static site generator, does not implement by default. Luckily I future proofed my site so it was easy to port images as well as HTML used in the posts. I didn't have many posts that used a featured image so it was simply a matter of adding a new ![Alt text](/images/leading-image.jpg) line to the top of each post.

Captions

Speaking of images, I am using the captionss CSS library to easily add a nice looking caption to my images. Again, Jekyll does not offer this out of the box but it was a good excuse to get familiar with Liquid and write my own tag. I didn't want to bother with surrounding my images with HTML every time I wanted to add a caption so I created a cap.html file in my _includes folder inside my Jekyll site directory with the following contents:

<div class="center">
<figure class="embed">
    <a href="{{ include.url }}"><img src="{{ include.url }}" alt="{{ include.alt }}"></a>
    <figcaption>
    {{ include.cap }}
    </figcaption>
</figure>
</div>

Whenever I want to use an image with a caption, I can just use the following:

{% include cap.html url="/images/image.jpg" alt="Alt text" cap="Caption" %}

Post Excerpts

WordPress uses the <!--more--> tag to signal post excerpts, and automatically generates a Read more... link. Jekyll does not have this by default, but it can easily be implemented using a loop in the site's posts index with the split Liquid filter:

{% if post.content contains '<!--more-->' %}

    {{ post.content | split:'<!--more-->' | first }}

    <p><a href="{{ post.url }}">Read more &raquo;</a></p>

{% else %}

    {{ post.content }}

{% endif %}

Archives

I didn't bother reinventing the wheel with this one, and shamelessly stole Reyhan Dhuny's archive.html code to make mine. I only added a hyphen between post names and dates and I was good to go.

Finally, I built the site and put my files in the web server's directory:

jekyll build -s /home/gzamudio/gerardozamudio.mx -d /var/www/html/

nginx

Good old nginx. It's hard to believe it's been a decade since this web server came about and it's certainly matured a lot since then. Development is fast and looks to be stable, so I decided to go with the mainline releases. My main goal was serving plain static content so I did not need any of the extra modules that are built in by default. I created a system user to run the daemon:

useradd -r -M -U -c "User for nginx" -d /srv/httpd -s /bin/false nginx

Then I built my package using only 3 modules: http_ssl_module, http_spdy_module, and http_gzip_static_module

./configure \
  --with-http_ssl_module \
  --with-http_spdy_module \
  --with-http_gzip_static_module \
  --with-file-aio \
  --without-http_autoindex_module \
  --without-http_browser_module \
  --without-http_fastcgi_module \
  --without-http_geo_module \
  --without-http_empty_gif_module \
  --without-http_map_module \
  --without-http_proxy_module \
  --without-http_memcached_module \
  --without-http_ssi_module \
  --without-http_userid_module \
  --without-mail_pop3_module \
  --without-mail_imap_module \
  --without-mail_smtp_module \
  --without-http_split_clients_module \
  --without-http_uwsgi_module \
  --without-http_scgi_module \
  --without-http_limit_conn_module \
  --without-http_referer_module \
  --without-http-cache \
  --without-http_upstream_ip_hash_module

SSL

I talked about adding a certificate in a previous post, but I decided to take that a step further and switch to ECDSA for my SSL certificate. Unfortunately Gandi does not offer such certificates so I had to move to Comodo in order to get one. I also set up HSTS and PFS to completely get rid of plain HTTP access to the server. At least Qualys seems to think I did a good job. If you look closely at the configure options above you'll notice I also enabled SPDY, the starting point for HTTP 2.0. Feel free to check it out.