Project Recap: Automating Blog Deployment with Obsidian and Hugo


I recently implemented an automated workflow for publishing blogs directly from Obsidian to a Hugo-powered website. Inspired by this video from Network Chuck:


I sought to create a similar solution for my current somewhat hodge-podge setup. I also wondered if I could make a simpler, tailored version that fit my existing setup while eliminating steps I felt were unnecessary for my needs. Here’s a breakdown of the project, the challenges I encountered, and lessons learned along the way.

Objective

Streamline the process of publishing blog posts and images from Obsidian to my Hugo website, automating repetitive tasks and improving efficiency across multiple devices.

Initial Setup

Here’s how my workflow started:

  1. Writing: Blog posts were written in Markdown locally, then manually copied into vim on my Hugo server.

  2. Synchronization: I used Syncthing to mirror folders between my local machine and the VPS hosting my Hugo site.

  3. Publishing: The command sudo hugo was run manually on the VPS to push updates live.

While functional, this process felt unnecessarily complex. Maintaining a separate VPS added costs and potential points of failure.

Goals for the New Workflow

• Automate syncing of blog posts and images from Obsidian to Hugo.

• Eliminate the need for a VPS and reduce hosting costs.

• Retain hierarchical structure for images and ensure smooth integration with Hugo.

• Avoid using Git or Hostinger-based workflows as they didn’t align with my existing setup and to avoid extra points of failure.

The New Workflow

Here’s the updated and automated process I implemented:

  1. Obsidian Notes:

All blog content is now created in Obsidian, and I use Obsidian Sync ($10/month) to sync across Linux/Mac OS devices.

I also utilized the templater community plug-in to automatically create a post with the markdown front-matter whenever I created a new note in the blogs folder. Network Chuck accomplished this differently, I believe. Note: This needs to be done on each obsidian app you use separately but it’s really easy to configure.

  1. Script Automation:

A bash script syncs my Obsidian folders for posts and images directly to the Hugo server (which is a remote machine on my local network) using rsync.

#!/bin/bash

# Variables
LOCAL_BLOG_DIR=~/Documents/Obsidian/planetB/philcifone.com/blog/
REMOTE_HOST="192.168.1.165"
REMOTE_USER="phil"
REMOTE_BLOG_DIR="/var/www/philcifone.com/content/blog/"
REMOTE_WEB_DIR="/var/www/philcifone.com/"
LOCAL_IMAGE_DIR=~/Documents/Obsidian/planetB/images/
REMOTE_IMAGE_DIR="/var/www/philcifone.com/static/images/"


# Sync local files to remote server
rsync -avz --delete "$LOCAL_BLOG_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_BLOG_DIR"


rsync -avz --delete "$LOCAL_IMAGE_DIR/" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_IMAGE_DIR"

# SSH into remote host and execute Hugo build
ssh "$REMOTE_USER@$REMOTE_HOST" << EOF
  cd "$REMOTE_WEB_DIR"
  echo "Building the site with Hugo..."
  sudo hugo
EOF

The script also SSHs into the server and runs the sudo hugo command to push the site live.

  1. Hosting Change:

I moved the website hosting from a VPS to a local server, saving $5/month.

Challenges Encountered

  1. DNS trouble:

After changing the DNS IP address to my local network I forgot to open the ports on my router, and while troubleshooting I changed TLS settings without changing them back before realizing my mistake. Thus, I spent some time troubleshooting an easy issue.

  1. Image Synchronization Issues:

Initially, images weren’t showing up on the live site. After triple-checking file paths and permissions, I discovered a missing subfolder in the script variable. Once corrected, images displayed as expected.

  1. Date Translation Bug:

Hugo is incorrectly translating dates from my Obsidian templates. This is still unresolved and requires further debugging.

Key Accomplishments

• Reduced the number of steps from Network Chuck’s process while achieving the same functionality with less points of failure.

• Created a bash script that automates blog and image deployment from any Obsidian-enabled device.

• Simplified hosting and lowered costs by consolidating everything to a local server.

Lessons Learned

  1. Always Verify Scripts: A single missing subfolder caused avoidable frustration.

  2. Backups Are Essential: While I didn’t have to use them, I almost did, and it was nice knowing I had snapshots and backups at the ready.

  3. Toggle settings one at a time: This would have saved me a bunch of time when updating DNS records.

I should know all of these lessons by now, but it’s always helpful to learn them again.

Next Steps

  • Fix the date translation bug in Hugo.

  • Explore additional optimizations, like automating image resizing or compression during deployment.

  • Create similar system for adding images to photography, writing, and painting sections.

  • Save money on Blot and create new Hugo website for Keystone Dreams project.

Conclusion

This project proved to be a valuable learning experience, and a practical project I will use regularly. By automating my workflow, I’ve made blogging easier and more efficient. I now have a scalable solution that works seamlessly across devices, allowing me to focus on writing rather than administration.

phil cifone

is an artist and digital conservator located just outside of Philadelphia, Pennsylvania.


By phil cifone, 2024-12-02