Configuration and Customization
This page describes how to configure Jekyll Docker using environment variables, local package manifests, and host-mounted caching directories.
Environment Variables
Configure Jekyll Docker's internal wrappers by passing these environment variables when starting your container:
User and File Access Mappings
JEKYLL_UID(Default:1000)- Why it matters: By default, containers execute as the root user. If your host developer account has a different User ID (e.g.,
1001), files generated by Jekyll inside the container (like the_siteoutput folder) will be owned by root, preventing you from editing or deleting them on your host. - Resolution: Set
-e JEKYLL_UID=$(id -u)to align the container with your host user account. JEKYLL_GID(Default:1000)- Resolution: Set
-e JEKYLL_GID=$(id -g)to map group permissions securely. JEKYLL_ROOTLESS(Default:"")- Resolution: When running rootless container runtimes like Podman, set
-e JEKYLL_ROOTLESS=1to run the execution loop directly as root inside the namespace, which securely maps back to your host user account.
Execution Toggles
FORCE_POLLING(Default:false)- Why it matters: Jekyll uses file system events to watch for changes. On virtualized systems (such as WSL1/WSL2, VirtualBox Shared Folders, or NFS mounts), these events are often blocked.
- Resolution: Set
-e FORCE_POLLING=trueto force Jekyll to poll the file system for changes manually. VERBOSE(Default:false)- Resolution: Set
-e VERBOSE=trueto print detailed compilation diagnostics and track gem resolution issues. DRAFTS(Default:false)- Resolution: Set
-e DRAFTS=trueto include files located in your_draftsdirectory during compilation.
Installing Custom Alpine Packages (.apk Support)
If your build process depends on system utilities that are not pre-installed in the base image (such as custom rendering engines, font libraries, or native image preprocessors), you can install them dynamically at boot.
Step-by-Step Package Installation
- In your project's root folder (next to your
_config.yml), create a text file named.apk. - Add the exact Alpine package names, one per line:
imagemagick
graphviz
inkscape
- Start your container with an active internet connection. The internal
bundlescript will intercept this file, parse its contents, and runapk add --no-cacheto install the packages before running Jekyll.
!!! warning "Network Requirement" Dynamic package installation requires an active internet connection at startup. If the container is offline, package installation is skipped, which may cause build failures if your plugins depend on those utilities.
Gem Cache Optimization
When a project includes a custom Gemfile, Jekyll Docker runs bundle install at startup to ensure all dependencies are resolved. To prevent the container from re-downloading these packages on every run, configure a persistent host directory to cache your compiled gems.
Configure Your Volumes
Map a local path on your host machine to the container's /usr/local/bundle directory:
docker run --rm \
--volume="$PWD:/srv/jekyll:Z" \
--volume="$PWD/vendor/bundle:/usr/local/bundle:Z" \
-it jekyll/jekyll:latest \
jekyll build
Prevent Infinite Build Loops
If you mount your gem cache folder inside your project directory (such as vendor/bundle), you must explicitly instruct Jekyll to ignore it. Otherwise, Jekyll will treat newly compiled gems as source modifications, triggering an infinite rebuild loop.
Update your _config.yml configuration file to exclude your cache directory:
exclude:
- vendor/
- Gemfile.lock
- .bundle/
- .apk