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:
| Framework | Default command | Default publish directory |
|---|---|---|
| Hugo | hugo --minify | public |
| Jekyll | jekyll 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.