Every site builds in an isolated, locked-down container: no network access, a read-only filesystem, 1 GB memory, 2 CPUs and a 10-minute timeout. Builds run as a non-root user, and /tmp is a small (256 MB) RAM disk. Configure your build in Site settings.

Build command

Leave it blank to use the default for your framework:

FrameworkDefault commandDefault publish directory
Hugohugo --minifypublic
Jekylljekyll build_site
Static(none, files served as-is).

Set a custom command to do more. You can chain steps with && or run a shell script committed to your repo:

hugo --minify && sh scripts/redirects.sh
jekyll build && cp _redirects _site/
npm run build
sh build.sh

Use sh, not bash. The build images are Alpine-based and have no bash, so a script must be POSIX sh (start it with #!/bin/sh, avoid [[ ]] and arrays) and you should call it with sh scripts/yourscript.sh.

The build itself has no network access. Dependencies are fetched in a separate network-enabled step before the sandboxed build: Hugo Modules are vendored automatically (if your repo has a go.mod), and npm install runs automatically if there’s a package.json and no node_modules. Commit anything else your build needs.

Image optimisation (libvips)

Every build container includes libvips (vips / vipsthumbnail) and Python 3, so you can resize images, convert AVIF/HEIF to WebP and cap dimensions as part of the build. libvips streams images, so it stays well within the memory limit even for large photos.

Resize to fit within 2000×2000 and convert to WebP (only ever shrinks, never upscales):

vipsthumbnail hero.avif --size 2000x2000 -o hero.webp[Q=80]

For an image-heavy build, point TMPDIR at the workspace so scratch files and Hugo’s cache don’t fill the small /tmp RAM disk:

export TMPDIR="$PWD/.buildtmp" && mkdir -p "$TMPDIR" && sh scripts/prebuild-images.sh && hugo --minify

Keep any pre-processing script idempotent (skip images already converted) so repeat builds stay within the 10-minute timeout.

Publish directory

The folder your generator outputs to. Set it to match your tooling (public for Hugo, _site for Jekyll, dist for many bundlers, . if you’re serving files as-is).

Environment variables

Add per-site environment variables in Site settings → Environment variables. They’re passed securely to the build container.

  • Up to 20 variables per site.
  • Names must match ^[A-Za-z_][A-Za-z0-9_]*$ (letters, digits, underscores; not starting with a digit).
  • Available to your build command and scripts, e.g.:
# with HUGO_ENV=production set in settings
hugo --minify --environment $HUGO_ENV

Common uses: HUGO_ENV / JEKYLL_ENV, a build-time API base URL, or a feature flag your generator reads. (Hugo builds already get HUGO_TIMEOUT=300s so image processing doesn’t time out.) Note: your variables are passed to the build step, not to the automatic Hugo-module vendoring or npm install steps, which run earlier with network access.