Zalgorithm

How this site is deployed

When the blog was only a static site, I deployed it with the following (executable) script. The variables HD_HUGO_LOCAL_DIR, HD_USER, and HD_HOST are exported from my ~/.bashrc file:

#!/usr/bin/env bash
set -euo pipefail  # Exit on error

# Trap errors
trap 'echo "ERROR: Deployment failed at line $LINENO. Remote deployment aborted."; exit 1' ERR

cd $HD_HUGO_LOCAL_DIR
echo "Starting Hugo deploy process. In ${HD_HUGO_LOCAL_DIR}"

echo "Deleting Hugo public directory"
rm -rf public/

echo "Executing hugo build --environment production"
hugo build --environment production

echo "Deploying to static Hugo directory"
hugo && rsync -avz --delete public/ ${HD_USER}@${HD_HOST}:${HD_HUGO_REMOTE_DIR}

The full build and deploy process

The full build process now requires:

Production deploy script

This (good enough) script handles it all:

#!/usr/bin/env bash
set -euo pipefail  # Exit on error

# Trap errors
trap 'echo "ERROR: Deployment failed at line $LINENO. Remote deployment aborted."; exit 1' ERR

cd $HD_HUGO_LOCAL_DIR
echo "Starting full Hugo deploy process. In ${HD_HUGO_LOCAL_DIR}"

echo "Deleting Hugo public directory"
rm -rf public/

echo "Executing hugo build --environment minimal"
hugo build --environment minimal

cd $HD_EMBEDDINGS_GENERATOR_DIR
echo "In ${HD_EMBEDDINGS_GENERATOR_DIR}"

echo "Deleting chroma/ directory from ${HD_EMBEDDINGS_GENERATOR_DIR}"
rm -rf chroma/

echo "Deleting sqlite/sections.db from ${HD_EMBEDDINGS_GENERATOR_DIR}"
rm sqlite/sections.db

echo "Generating new embeddings and HTML fragments"
.venv/bin/python main.py  # use the directory's venv

echo "Copying Chroma data to ${HD_HOST} /tmp directory"
# NOTE: the trailing slash on the source directory is significant
# it tells rsync to copy the contents of the directory to the destination
# without the trailing slash rsync will copy the directory itself
rsync -avz --delete chroma/ ${HD_USER}@${HD_HOST}:/tmp/chroma-data/

echo "Copying SQLite data to ${HD_HOST} /tmp directory"
rsync -avz --delete sqlite/sections.db ${HD_USER}@${HD_HOST}:/tmp/sections.db

echo "SSHing into ${HD_HOST}"
# NOTE: don't use quotes around 'EOF'; it prevents variables from being expanded
ssh ${HD_USER}@${HD_HOST} << EOF
  set -x
  echo "Copying data into Docker containers"
  docker cp /tmp/chroma-data/. ${HD_DOCKER_CHROMA_CONTAINER}:/data/
  docker cp /tmp/sections.db ${HD_DOCKER_API_CONTAINER}:/data/sections.db

  echo "Restarting Docker services"
  cd ${HD_API_REMOTE_DIR}
  docker compose restart chroma
  docker compose restart api

  echo "Exiting ${HD_HOST}"
EOF

cd $HD_HUGO_LOCAL_DIR
echo "In ${HD_HUGO_LOCAL_DIR}, deleting Hugo minimal build"
rm -rf public/

echo "Building production HTML"
hugo build

echo "Deploying production HTML"
rsync -avz --delete public/ ${HD_USER}@${HD_HOST}:${HD_HUGO_REMOTE_DIR}

echo "Completed Hugo deploy"

Development only deploy script

I can’t be pushing the site to production every time I want to check something.

Local only build:

#!/usr/bin/env bash
set -euo pipefail  # Exit on error

# Trap errors
trap 'echo "ERROR: Deployment failed at line $LINENO. Remote deployment aborted."; exit 1' ERR

cd $HD_HUGO_LOCAL_DIR
echo "Starting local only Hugo deploy process. In ${HD_HUGO_LOCAL_DIR}"

echo "Deleting Hugo public directory"
rm -rf public/

echo "Executing hugo build --environment minimal"
hugo build --environment minimal

cd $HD_EMBEDDINGS_GENERATOR_DIR
echo "In ${HD_EMBEDDINGS_GENERATOR_DIR}"

echo "Deleting chroma/ directory from ${HD_EMBEDDINGS_GENERATOR_DIR}"
rm -rf chroma/

echo "Deleting sqlite/sections.db from ${HD_EMBEDDINGS_GENERATOR_DIR}"
rm sqlite/sections.db

echo "Generating new embeddings and HTML fragments"
.venv/bin/python main.py  # use the directory's venv

cd $HD_HUGO_LOCAL_DIR
echo "In ${HD_HUGO_LOCAL_DIR}, deleting Hugo minimal build"
rm -rf public/

echo "Building production HTML"
hugo build --environment production

echo "Completed local Hugo build and embedding/fragment generation"