Recently, I decided to migrate this blog to a self-hosted infrastructure using Coolify. The stack I chose is Hugo as the Static Site Generator (SSG) combined with the modern Blowfish theme.
At first, I thought the process would be as easy as “plug-and-play” using Coolify’s built-in build pack (Nixpacks). However, reality proved otherwise. I encountered two technical issues that were quite a headache and caused the deployment to fail completely.
This post documents those issues and the final solution using a manual Dockerfile, which proved to be stable.
The Problems Encountered#
1. Hugo Version Error (Function “try” not defined)#
When using Coolify’s default settings, the system pulls a version of Hugo that is quite old (e.g., v0.118 or v0.111). However, the latest version of the Blowfish theme requires features only available in modern Hugo versions (v0.123+).
The error log appearing in Coolify looks like this:
Error: ... template: shortcodes/codeberg.html:5: function "try" not defined
WARN Module "blowfish" is not compatible with this Hugo version
2. Broken Layout (CSS Integrity Mismatch)#
After successfully resolving the version issue, the site was finally accessible. However, the layout was completely broken, displaying only black and white text with no styling (CSS).
When I checked the browser Console (Inspect Element), a series of red errors appeared like this:
Failed to find a valid digest in the 'integrity' attribute for resource ...
The resource has been blocked.
This problem occurred because the workflow I used was flawed:
- I built the site (
hugo) on my laptop using Windows. - I uploaded the build result (
publicfolder) to Git. - The server (Linux) served those files.
The difference in line endings between Windows (CRLF) and Linux (LF) caused the security hash calculation (Fingerprint/Integrity) to mismatch. Consequently, the browser assumed the CSS file had been modified or “tampered with,” blocking it for security reasons.
Solution: Switching to a Custom Dockerfile#
The best solution to this problem is not to rely on Coolify’s built-in automated images and not to upload the public folder manually. We must build our own environment using Docker so we have full control over the Hugo version and ensure file integrity.
Here are the steps to fix it:
Step 1: Clean the Git Repository#
Let the server do the building, not the laptop. Remove the public folder from the Git repository to avoid hash conflicts in the future.
Run these commands in your laptop terminal:
# Remove the public folder from git tracking (files on laptop remain safe)
git rm -r --cached public
# Add to .gitignore to prevent future uploads
echo "public" >> .gitignore
# Commit changes
git commit -m "chore: remove public folder specific to local build"
git push origin main
Step 2: Create a Manual Dockerfile#
Instead of relying on community-made images that might be rarely updated (like klakegg/hugo), the best solution is to build the environment ourselves. We will use a Multi-stage Build with a Debian Slim base image to guarantee we can install the official Hugo Extended version directly from the source.
Create a new file named Dockerfile (without any extension) in your project’s root directory, then fill it with the following code:
# --- Stage 1: Build Website ---
# Use Debian Slim: Lightweight, stable, and compatible with Hugo Extended libraries
FROM debian:bookworm-slim AS builder
# Define the Hugo version we want.
# We can change this number anytime if there is a new update from Hugo.
ARG HUGO_VERSION="0.152.2"
# 1. Install basic tools needed for download and extraction
RUN apt-get update && apt-get install -y \
curl \
git \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# 2. Download Official Hugo Extended Installer (.deb) from GitHub
# Using the Extended version is MANDATORY for the Blowfish theme (image processing/WebP)
RUN curl -L "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb" -o hugo.deb \
&& dpkg -i hugo.deb \
&& rm hugo.deb
# 3. Verify installation (Optional, for logging purposes)
RUN hugo version
# 4. Setup working directory
WORKDIR /src
COPY . .
# 5. Build the Hugo site
# --minify: Compresses HTML/CSS/JS for faster loading
# --gc: Garbage Collector to clean up unused cache
RUN hugo --minify --gc
# --- Stage 2: Serve with Nginx ---
# Move build results to a very lightweight Nginx server (Alpine)
FROM nginx:alpine
# Copy only the 'public' folder (build result) from Stage 1 to Nginx HTML folder
COPY --from=builder /src/public /usr/share/nginx/html
# Expose port 80 to be accessible by Coolify
EXPOSE 80
# Run Nginx
CMD ["nginx", "-g", "daemon off;"]
Step 3: Coolify Configuration#
After the Dockerfile is pushed to your GitHub/GitLab repository, configure the following in the Coolify dashboard:
- Open your Hugo project.
- Go to Configuration > General.
- Change Build Pack to Dockerfile.
- Ensure Docker File Location is set to
/Dockerfile. - Ensure that in the Network section, Ports Exposes contains port
80. - Click Save and then Deploy.
Final Result#
With this manual Dockerfile method, all problems are resolved:
- Controlled Version: We get Hugo v0.152.2 (or the latest) specifically, ensuring Blowfish features run smoothly.
- Secure CSS Integrity: Since the build process happens inside a Linux container on the server (not on Windows), the CSS hash matches perfectly, and integrity errors disappear.
- Lightweight: The final container result is very small because it only contains Nginx and static HTML files.
If Hugo releases a new version in the future (e.g., v0.160.0), I simply need to edit one line in the Dockerfile without changing server configurations:
ARG HUGO_VERSION="0.160.0"
I hope this guide helps anyone struggling to deploy Hugo on their own VPS!


