Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deploying Static Sites

Choose Static Files (--framework static) to serve HTML, CSS, JavaScript, and other public assets with nginx. This supports prebuilt files and frontend projects that compile to files. Server-side rendering needs a server framework such as Node.js instead.

For a first deployment with a downloadable site and a public bucket asset, follow the static tutorial. This guide covers configuring your own frontend.

Prebuilt files

Commit your site under public/, including public/index.html, and create a web app:

paas apps create site --framework static --health-check-path /

Push it using the app’s Git remote. nginx listens on the platform’s injected PORT. The home page is the health endpoint; the API, CLI, and dashboard default new Static Files web apps to / when no explicit path is provided. Existing app settings are preserved.

Build a frontend project

Define a package script in package.json, for example a Vite project’s build script. Commit the package manager’s lockfile. The npm and Yarn build workflows are verified; pnpm is not part of this Static Files build path.

At the app root, add project.toml:

[_]
schema-version = "0.2"

[[io.buildpacks.build.env]]
name = "BP_NODE_RUN_SCRIPTS"
value = "build"

[[io.buildpacks.build.env]]
name = "BP_WEB_SERVER_ROOT"
value = "dist"

The builder installs dependencies and runs the named package script, then serves dist/ with nginx. BP_NODE_RUN_SCRIPTS takes script names, not shell commands; put the command in package.json. Change dist to your tool’s output directory (for example build). These paths are relative to the selected app source directory. Shared apps with the same framework and source directory share this build configuration and output.

Use engines.node to select a build-time Node.js version. Paketo’s version inventory differs from the Node.js application builder; see version selection and the catalog. The deployed builder’s Yarn versions and bundled npm version are part of its frontend toolchain; a package-manager pin outside that inventory can fail a build. For the verified Yarn Classic workflow, commit yarn.lock and use engines.yarn in package.json to request a catalog version. npm comes bundled with the selected Node engine. A successful build is separate from upstream maintenance; check both columns in the catalog when choosing a toolchain.

Single-page applications

For client-side routes, add:

[[io.buildpacks.build.env]]
name = "BP_WEB_SERVER_ENABLE_PUSH_STATE"
value = "true"

This serves index.html for client-side routes. Leave it unset for a conventional site where missing pages should return 404. Only publish files intended to be public; build-time variables compiled into JavaScript are visible to visitors.

Configuration and troubleshooting

project.toml configures the build. d2o-paas.yaml configures the running app, such as health checks and process selection. Dashboard environment variables configure the running container; do not rely on them as build-time settings. The platform supplies BP_WEB_SERVER=nginx; no custom nginx configuration is needed for these examples.

If a build fails, inspect dependency installation and the named script in the build log. If deployment health fails, check that the configured output directory contains index.html and that the health path points to a real file. A /health path is not automatically created. For a custom nginx configuration, ensure it listens on the injected port and serves the intended document root.

See Paketo Web Servers for the upstream build settings, and deployments for health checks and rollback.

Pinning nginx

The catalog lists nginx versions from the deployed builder. To select one, set BP_NGINX_VERSION in project.toml using the same build-env syntax above. The currently deployed nginx buildpack 1.3.0 also needs a buildpack.yml file when a version is explicitly selected:

nginx: {}

This works around its missing-file error during detection; the version in BP_NGINX_VERSION still takes precedence. The default server version needs neither setting. This workaround is covered by the catalog’s smoke tests.