Module 2 · Lesson 5

Lifecycle Commands

Build, release, start, seed — the full app lifecycle.

What you'll learn
  • The six command types: build, release, start, seed, test, bootstrap
  • When each command runs in the deployment lifecycle
  • Command capture for post-start output
  • The build block for Dockerfile-based builds

The deployment lifecycle

Every deployment follows the same arc: compile the code, prepare the environment, then run the app. Launchfile gives you a hook for each stage via the commands block.

Here's the order, and when each command fires:

  1. build — Compile source, install dependencies, generate assets. Runs at build time.
  2. release — Runs once per deployment, before start. Migrations, asset uploads, cache warming. If it fails, the deploy stops.
  3. start — The long-running process. This is your app.
  4. seed — Populate the database with sample or default data. Typically run on demand, not on every deploy.
  5. test — Run the test suite. Used by CI and by providers that validate before promoting a deploy.
  6. bootstrap — First-time setup. Create the admin user, generate invite links, initialize config. Runs on user request, not automatically.
release vs. bootstrap

Think of release as "every deploy" (migrations) and bootstrap as "first deploy ever" (admin setup). Both run against a live app, but release gates the deploy while bootstrap is fire-and-forget.

Build it up

1
The minimum: a start command. The provider runs this to launch your app.
commands:
  start: "node server.js"
2
Add build to compile and release to run migrations before every deploy.
commands:
  build: "npm install && npm run build"
  release: "npx prisma migrate deploy"
  start: "node dist/server.js"
3
Add seed for sample data and test for the test suite.
commands:
  build: "npm install && npm run build"
  release: "npx prisma migrate deploy"
  start: "node dist/server.js"
  seed: "node scripts/seed.js"
  test: "npm test"
4
The capture pattern extracts values from stdout via regex. Useful for apps that print a generated token or URL on first start.
commands:
  start:
    run: "my-app serve"
    capture:
      ADMIN_TOKEN: "Admin token: (.+)"

The build block

There's a subtle but important distinction: commands.build runs shell commands (like npm run build), while a top-level build: block configures a Dockerfile-based container build. They serve different purposes.

commands.build (shell)
commands:
  build: "npm install && npm run build"
  start: "node dist/server.js"
build: (Dockerfile)
build:
  dockerfile: ./Dockerfile

commands:
  start: "node server.js"
Don't confuse the two

commands.build runs inside an already-built container (or on the host). The top-level build: block tells the provider how to build the container image itself from a Dockerfile. If you're using a prebuilt image (like image: node:20), you only need commands.build. If you have a Dockerfile, use the top-level build: block.

In the wild

This spec example shows a real-world pattern: a post-start bootstrap command that creates an admin user and captures the one-time invite link from stdout.

my-app/Launchfile View on GitHub
version: launch/v1
name: my-app

build:
  dockerfile: ./Dockerfile

provides:
  - protocol: http
    port: 9999
    exposed: true

env:
  APP_SECRET:
    generator: secret
    sensitive: true
  PUBLIC_URL:
    default: $app.url
    description: "Public URL the app is reachable on (auth callbacks, email links)"

health: /health
restart: always

commands:
  start: "node server.js"

  # Post-start setup: create the first admin and capture the one-time invite link.
  # Run by the user via `launchfile bootstrap my-app` (or the provider's equivalent)
  # after the app is up. Re-runnable; failures are reported, not deploy-failing.
  bootstrap:
    command: "my-app-cli create-invite --name admin --url $app.url"
    capture:
      invite_link:
        pattern: "https?://\\S+"
        description: "One-time invite link — open in a browser to register your account"
        sensitive: true
build:
Top-level build block — this app uses a Dockerfile, not a prebuilt image.
commands:
The commands block defines start and bootstrap. No release or build command needed since the Dockerfile handles compilation.
bootstrap:
Runs on user request after the app is up. Creates an admin invite and captures the URL from stdout.
capture:
Extracts the invite link via regex. The provider stores it and shows it to the user.

Check your understanding

When does the release command run?
Key takeaways
  • The deployment lifecycle is: build, release, start. Seed, test, and bootstrap are on-demand.
  • release runs once per deploy (migrations). bootstrap runs once ever (initial setup).
  • Commands can use the capture pattern to extract values from stdout via regex.
  • Top-level build: configures Docker image builds. commands.build runs shell commands inside a container.
esc
Type to search the docs