Write a builder.yaml
builder.yaml tells App Service Builder how to build and run your app.
Place it at the app's source root, whether you deploy GitHub source or upload a ZIP.
Get help from the Builder skill
You do not need to write the manifest unaided. Install the App Service Builder agent skill, then ask:
Use the App Service Builder skill to create or fix builder.yaml for this app.
Check its framework, build output, startup command, listening port, and health
endpoint. Preserve existing source and explain the proposed changes before editing.
Review the changes and validate the manifest before deploying. For GitHub deployment, commit and push it with your code. For ZIP deployment, include the same file at the archive root.
At a glance
- Place
builder.yamlat the selected app source root. - Use
staticfor browser assets andwebfor an HTTP process. - Builder can infer build defaults from supported project files.
- Custom builds must place generated output under
$DESTINATION_DIR.
Validate your manifest
Install Builder CLI, then check an existing builder.yaml from its repository:
builder manifest validate
Validation uses the manifest parser and build planner without changing files or running repository code.
Use --json for automation.
builder init connects the app; it does not automatically analyze or modify the manifest.
Optional build validation runs repository build scripts in Docker:
builder manifest validate --build
Run build validation only for source you trust. Docker separates the build from Builder infrastructure but is not a security boundary for hostile repository code. Validation does not deploy the app; commit and push the intended configuration before deployment.
Start with browser-ready content
For committed HTML, CSS, and JavaScript in public/:
components:
- name: site
role: static
output: public
path: /
This skips a build toolchain and publishes only the selected directory.
Use output: . only when the component root intentionally contains public content.
Do not publish a source tree containing secrets or files you did not intend to expose.
Build Vite assets
For a Vite project under web/ with its package manifest and build script:
components:
- name: site
role: static
rootDirectory: web
path: /
Vite evidence resolves Node.js, the conventional build, and dist unless overridden.
Commit the package and lock files.
Use platformVersion with platform: nodejs when you need an explicit version request.
Confirm the requested version is available in your preview environment.
Run a web process
For a Node.js app under server/ whose package files install its dependencies and whose server.js listens on 0.0.0.0:8080:
components:
- name: api
role: web
platform: nodejs
rootDirectory: server
path: /
run:
port: 8080
start: node server.js
healthCheckPath: /health
healthCheckStatusCodes: [200]
Implement /health in your app.
Do not bind only to localhost.
The runtime reference lists supported platform identifiers and version requirements.
run.start is an optional override, not a requirement shared by all languages.
The Node.js example supplies it to select server.js; other runtimes can use their default startup.
Use the default PHP runtime
For a PHP 8.5 web component whose packaged document root contains index.php and health.php:
components:
- name: web
role: web
platform: php
platformVersion: "8.5"
run:
healthCheckPath: /health.php
Omit run.start to use the default nginx/PHP-FPM startup.
Do not use a PHP development server as hosted startup.
The port defaults to 8080 and this single component's public mount defaults to /.
The explicit /health.php path must return HTTP 200; it does not default to /health.
Keep builder.yaml at the app source root.
The component source root contains the application and its Composer files (composer.json and composer.lock) when it uses Composer.
Changing rootDirectory selects different build input; it does not configure nginx to serve public/.
The runtime serves the packaged build root.
For a custom build, place the intended document-root files and required runtime dependencies directly under $DESTINATION_DIR.
Do not use the static output field for this web component, and do not package private files into its served root.
Confirm PHP 8.5 runtime availability with your preview contact. The PHP tutorial applies this layout to the published sample. See PHP runtime notes for more detail.
Override the build correctly
For a custom static Node build:
components:
- name: site
role: static
platform: nodejs
rootDirectory: web
build: npm run build && mkdir -p "$DESTINATION_DIR/dist" && cp -R dist/. "$DESTINATION_DIR/dist/"
output: dist
path: /
The command runs in the component source directory.
output: dist is resolved beneath the generated output root, not beneath the source directory, for this build.
A custom compute command must similarly produce a complete runnable output under $DESTINATION_DIR, for example dotnet publish -c Release -o "$DESTINATION_DIR".
Choose paths and health policy
| Setting | Guidance |
|---|---|
Source rootDirectory | Selects the app root containing the manifest |
Component rootDirectory | Selects a directory inside that app root |
path | Public mount; declare every path when there is more than one component |
run.healthCheckPath | Public path within the component mount |
run.healthCheckStatusCodes | Exact accepted codes for an explicit health path |
An explicit health path without a status list requires HTTP 200.
Omitting the path instead checks reachability: completed responses from 100 through 499 count as healthy.
A component mounted at /api must place its explicit health path within /api.
See the YAML reference for precise defaults and validation.
Keep within the output limits: at most one static site and one public HTTP application.
After editing, commit, push, and request deployment. Variables are app settings captured by a version, not YAML component fields.