Static sites with a build step
Ferry runs your build command, then nginx serves the publish directory.
Toolchain. Ferry chooses the build image from the files of the project.
An example
ferry up web --type static --follow # runs "npm run build", serves dist/The build step runs when you set a build command, or when package.json has a build script.
The build image
The toolchain comes from the files of the project.
| Project | Build image |
|---|---|
package.json | Node with the package manager of the project, as for Node.js |
requirements.txt, pyproject.toml, Pipfile (MkDocs, Pelican…) | Python, as for Python |
Gemfile (Jekyll…) | Ruby, as for Ruby |
hugo.toml / hugo.yaml / hugo.json, or hugo in the build command | Alpine with Hugo (and Go when there is a go.mod) |
go.mod | Go |
| none of these | node:22-alpine |
The publish directory
After the build, Ferry publishes the publish directory: --publish-dir. If you did not set it, Ferry publishes the first of dist, build, out, public, _site and site that exists. If none exists, the build fails.
ferry create docs --type static --repo https://github.com/you/docs --build-cmd "mkdocs build" # publishes site/
ferry create blog --type static --repo https://github.com/you/blog --build-cmd "hugo --minify" # publishes public/A build with no package.json at the root
The root can have no package.json, for example for a build in a subdirectory: cd docs && npm ci && npm run build. Then Ferry sets NODE_ENV=production before your build command, and npm ci skips the devDependencies. The build tools are usually there. Use npm ci --include=dev. The guide Host these docs on Ferry does this.