Skip to content
Open
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1a3bcf0
feat: added app lifecycle page
Kemi-Elizabeth Nov 7, 2025
706227a
Optimize images
actions-user Nov 7, 2025
ddf83ba
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 13, 2025
c06fcad
Update sites/upsun/src/learn/overview/app-life-cycle.md
Kemi-Elizabeth Nov 13, 2025
374d6c1
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 19, 2025
0fa894d
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 20, 2025
154d12f
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 20, 2025
a9e5ff9
Apply suggestion from @Kemi-Elizabeth
Kemi-Elizabeth Nov 20, 2025
1216c2c
feat: added note and adjusted table
Kemi-Elizabeth Nov 20, 2025
8cb82e1
Merge branch '5185-new-page-to-be-added-about-hooks' of https://githu…
Kemi-Elizabeth Nov 20, 2025
71ebbf1
feat: adjusted vale allowances
Kemi-Elizabeth Nov 20, 2025
24e3060
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 21, 2025
057cefd
Merge branch 'main' into 5185-new-page-to-be-added-about-hooks
Kemi-Elizabeth Nov 26, 2025
1feed1d
feat: adjusted to include deploy hooks
Kemi-Elizabeth Nov 26, 2025
7ca70cb
Merge branch '5185-new-page-to-be-added-about-hooks' of https://githu…
Kemi-Elizabeth Nov 26, 2025
c4a3652
Optimize images
actions-user Nov 26, 2025
79f3c8d
Removed sentence start
Kemi-Elizabeth Nov 26, 2025
1b854c1
Merge branch '5185-new-page-to-be-added-about-hooks' of https://githu…
Kemi-Elizabeth Nov 26, 2025
a5cdfec
feat: removed diagram
Kemi-Elizabeth Nov 26, 2025
cbddf82
feat: added new diagrams
Kemi-Elizabeth Nov 27, 2025
ebbc9d3
feat: removed image
Kemi-Elizabeth Nov 27, 2025
d3f654d
Apply suggestion from @Kemi-Elizabeth
Kemi-Elizabeth Nov 28, 2025
e36400f
feat: removed note about blocking
Kemi-Elizabeth Dec 1, 2025
2b67d48
feat: corrected typo and removed section
Kemi-Elizabeth Dec 1, 2025
989e9b8
feat: adjusted table description
Kemi-Elizabeth Dec 1, 2025
ea6040b
feat: added links
Kemi-Elizabeth Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions sites/upsun/src/learn/overview/app-life-cycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
---
title: The application lifecycle
weight: 3
description: "Understand the {{% vendor/name %}} application lifecycle and learn how to use web commands and hooks to control app behavior"
---
<!-- vale off -->

Hooks and web commands let you automate and control different stages of your [application’s lifecycle](#lifecycle-overview).

- **Web commands** (`pre_start`, `start`, `post_start`) run **on every instance**, every time that instance starts. They ensure each container is correctly initialised before it receives traffic, including during [horizontal](/manage-resources/adjust-resources.html#horizontal-scaling) autoscaling.

- **Hooks** (`build`, `deploy`, `post_deploy`) run **once per deployment**, on a single instance. They are used for environment-wide tasks such as preparing the image, running database migrations, or triggering background jobs.

Together, hooks and web commands give you fine-grained control of the application lifecycle, ensuring smooth start-up, reliable [autoscaling](/manage-resources/autoscaling.html), and safe deployments.

## Lifecycle overview

The {{% vendor/name %}} deployment lifecycle has two parallel tracks:

- Deployment process (runs once per deployment)
This is where your environment is built, deployed, updated, and released.
- Instance startup process (runs on every container instance)
Each new application instance goes through its own startup steps before it can receive traffic.

Understanding how these two tracks interact helps you choose the right hook for each task.

### Deployment Lifecycle (Environment-level)

These steps run once per deployment, no matter how many instances you have:

- `build` → Create the application image
- `deploy` → Run blocking environment-wide tasks before going live
- `post-deploy` → Run safe, non-blocking background tasks after the deployment is live

[![The steps in the deployment flow](https://mermaid.ink/img/pako:eNplkt2O0zAQhV9l5L0BKa3c_NEECalN1DskhPYKglhjTxqrjh05zpal6i0PwCPyJDhpWoq48xyd74w94xPhRiDJSa3MkTfMOngsKw3wSD9XpMROmZcWtYMP1nDse1iAHXQPRnOEDi2Im6UiXyp9QWGxeAcbH1BYZA5B4xFY1ynJmZNGAzfaManR9hMEsJmIrSc-DhqeLqFP0BhzgFet3NuJ6wNA_QyO9Yf-9UxuJ7Lw5EaIu2BwBqwZnL_i75-_wFlW15LPUDFB5bVdZ3r39d-e3xg_7D2vxX27keWK-TFs4Fkahe7tX2kLSrZ4JxT_e8qr5yaVWM82qKVS-UNK43S3C7hRxubHRrq7yNE8BszWku4iGs7WB0qpd5KA7K0UJHd2wIC0aFs2luQ0plTENdhiRXJ_FFizQfm9VfrssY7pT8a0V9I_ft-QvGaq99XQCb_IUjK_ivamWtQCbeHH5EierqYMkp_Id5KH8XqZrsJkHa2TlIZRFJAXkkfxck2TMKSrLI3DMKLxOSA_pq50-SYNkyxOs2ydZOkq83EopDP2_eWHTh_1_AfE39-r?type=png)](https://mermaid.live/edit#pako:eNplkt2O0zAQhV9l5L0BKa3c_NEECalN1DskhPYKglhjTxqrjh05zpal6i0PwCPyJDhpWoq48xyd74w94xPhRiDJSa3MkTfMOngsKw3wSD9XpMROmZcWtYMP1nDse1iAHXQPRnOEDi2Im6UiXyp9QWGxeAcbH1BYZA5B4xFY1ynJmZNGAzfaManR9hMEsJmIrSc-DhqeLqFP0BhzgFet3NuJ6wNA_QyO9Yf-9UxuJ7Lw5EaIu2BwBqwZnL_i75-_wFlW15LPUDFB5bVdZ3r39d-e3xg_7D2vxX27keWK-TFs4Fkahe7tX2kLSrZ4JxT_e8qr5yaVWM82qKVS-UNK43S3C7hRxubHRrq7yNE8BszWku4iGs7WB0qpd5KA7K0UJHd2wIC0aFs2luQ0plTENdhiRXJ_FFizQfm9VfrssY7pT8a0V9I_ft-QvGaq99XQCb_IUjK_ivamWtQCbeHH5EierqYMkp_Id5KH8XqZrsJkHa2TlIZRFJAXkkfxck2TMKSrLI3DMKLxOSA_pq50-SYNkyxOs2ydZOkq83EopDP2_eWHTh_1_AfE39-r)

This lifecycle details the kind of work that affects the entire environment, such as migrations, asset compilation, cache resets, and index updates.

### Instance Startup Lifecycle (per-instance)

Every application container goes through the following before it can handle traffic:

- `pre_start` → Quick per-instance setup
- `start` → Launch the application (traffic is blocked until this completes)
- `post_start` → Warm-up tasks before instance is added to router

[![The steps in the start-up flow](https://mermaid.ink/img/pako:eNplkk2L2zAQQP_KMHtpwQ6Kv2q7UNjEBHroqXtqXYrWHseismQkedNtyH-v7HXSQG-a0XszGkZnbHRLWGIn9anpuXHwVNUK4Il9r_Gzso6rhuCr8zfTCCGYSVkYyYBY72r8Uas3A8LwEzx6bzT0084KvLPkvQCUVuGz1M0voY7vFwXgceF3nl9ZySfV9AEsoIVJOSHnhupO2i3Sfm6irbt2OXEzhP59z9RpQ2CIt69XY78Y1f04lswLWXCGd51obhM0klvrn_UitCT38V9qB1IMdJfY_89UV-aWqqhbMeiElOVDxpLscAgaLbUpT71wdyVneC6wohU7xCxa0QfGmCcxwKMRLZbOTBTgQGbgc4jnuUqNrqfBr6P0x5Y6PklXY60uXhu5-qb1cDWNno49lh2X1kfT2HJHleBHw4db1pBqyey1XwKWUbrUwPKMv32U5JtsG6V5nKcZi-I4wFcs42STszSK2LbIkiiKWXIJ8M_SlW0-ZFFaJFlR5GmRbYttgNQKp82Xt8-3_MHLX2fu0Mg?type=png)](https://mermaid.live/edit#pako:eNplkk2L2zAQQP_KMHtpwQ6Kv2q7UNjEBHroqXtqXYrWHseismQkedNtyH-v7HXSQG-a0XszGkZnbHRLWGIn9anpuXHwVNUK4Il9r_Gzso6rhuCr8zfTCCGYSVkYyYBY72r8Uas3A8LwEzx6bzT0084KvLPkvQCUVuGz1M0voY7vFwXgceF3nl9ZySfV9AEsoIVJOSHnhupO2i3Sfm6irbt2OXEzhP59z9RpQ2CIt69XY78Y1f04lswLWXCGd51obhM0klvrn_UitCT38V9qB1IMdJfY_89UV-aWqqhbMeiElOVDxpLscAgaLbUpT71wdyVneC6wohU7xCxa0QfGmCcxwKMRLZbOTBTgQGbgc4jnuUqNrqfBr6P0x5Y6PklXY60uXhu5-qb1cDWNno49lh2X1kfT2HJHleBHw4db1pBqyey1XwKWUbrUwPKMv32U5JtsG6V5nKcZi-I4wFcs42STszSK2LbIkiiKWXIJ8M_SlW0-ZFFaJFlR5GmRbYttgNQKp82Xt8-3_MHLX2fu0Mg)

This is the work that every instance must do to be ready for traffic, like preparing local caches, installing runtime files, or loading ML models.

## Web commands

Each web application on {{% vendor/name %}} can define web commands inside its `.upsun/config.yaml` file:

```yaml
applications:
myapp:
type: 'python:3.13'
web:
commands:
pre_start: "./scripts/setup.sh"
start: "uwsgi --ini conf/server.ini"
post_start: "./scripts/warm-up.sh"
```

| Name | Type | Required | Blocks Traffic | Description |
| -------------- | ------ | -------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **pre_start** | string | No | No | Runs before `start`. Ideal for short per-instance setup tasks, such as preparing local caches or setting file permissions. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry you forgot to remove the "Blocks Traffic" column on this table

| **start** | string | Yes | Yes (until running) | The main command that launches your app. Traffic is blocked until this command successfully runs. If it exits, {{% vendor/name %}} restarts the instance. |
| **post_start** | string | No | Yes (until completed) | Runs after the app starts but before the instance is added to the router. Use for warm-up tasks that must complete before serving traffic. |

For more information about web commands, visit the [Single-runtime Image page](/create-apps/app-reference/single-runtime-image.html#web-commands).

{{< note theme="info" title="Blocking vs. non-blocking commands" >}}

A command is blocking if an instance cannot receive traffic until it completes successfully.

- `start` blocks traffic until the application is running.
- `post_start` blocks traffic until all warm-up tasks complete.
- `pre_start` is non-blocking.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pre_start is also blocking, I'd remove the whole distinction of non-blocking/blocking, they all block the deployment.


These rules apply only to instance startup, not to deployments.

{{< /note >}}

## Web comannd use cases
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"comannd" should be "command"


| Command | When to use | Example task |
| -------------- | ---------------------------------------- | ------------------------------------------- |
| **pre_start** | Per-instance setup before app launch | Preparing local caches, setting permissions |
| **post_start** | Warm-up before instance receives traffic | Cache priming, loading dependencies |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typical example is rather "waiting for the application to be fully started"


## Deploy and `post_deploy` hooks

While [web commands](#web-commands) run on every instance during startup, deployment-level hooks run only once per deployment, on a single container. They do not run during [horizontal](/manage-resources/adjust-resources.html#horizontal-scaling) autoscaling or instance restarts.

Use `build`, `deploy`, and `post_deploy` for image preparation, environment-wide tasks, or background jobs that should run per-deployment.

Define hooks in `.upsun/config.yaml`:

```yaml
applications:
myapp:
type: "python:3.13"
hooks:
build: "pip install -r requirements.txt"
deploy: "./scripts/migrate.sh"
post_deploy: "./scripts/warm-cache.sh"
```

| Hook | When it runs | Blocks traffic | Purpose |
|---------------|---------------------------------------------------|----------------|--------------------------------------------------------------|
| **build** | During the image build (before deployment) | N/A | Install dependencies, compile assets, prepare the runtime image |
| **deploy** | After new containers start but before they serve traffic | Yes | Environment-wide tasks that must complete before the new version goes live |
| **post_deploy** | After deployment is live and serving traffic | No | Non-blocking background work safe to run after the deployment completes |

### `deploy`

`deploy` runs once per deployment, **never** per instance. Because it blocks traffic until it completes, use it only for tasks that must finish before the application is switched over.

{{< note theme="note" title="Keep deploy short" >}}

Long-running deploy tasks slow down releases and may cause timeouts.

{{< /note >}}

### `post_deploy`

`post_deploy` runs after the deployment is successful and traffic has already switched to the new version. Use it for background tasks that don’t need to block deployment.

{{< note theme="info" title="Runs on every redeploy" >}}

`post_deploy` runs on every redeploy (even without code changes). It’s ideal for tasks triggered by:

- configuration changes
- new or updated environment variables
- dependency or service updates

{{< /note >}}

## Deploy and `post_deploy` use cases

| Hook | When to use | Example task |
|-----------------|------------------------------------------------------|--------------------------------------------------|
| **deploy** | Environment-wide tasks that must run before traffic | Database migrations, index updates |
| **post_deploy** | Background tasks safe while serving traffic | CDN cache clearing, cache warming, notifications |

### Autoscaling example

When autoscaling [adds new instances](/manage-resources/autoscaling.html#thresholds), only web commands run, not `deploy` or `post_deploy`. Each new instance must run `start` and `post_start` before receiving traffic.

Good uses for post_start during scaling include:

- Cache priming or session loading
- Lightweight readiness checks
- Loading configuration or dependencies into memory

This ensures new instances are ready before the router adds them.

{{< note theme="tip" title="Autoscaling" >}}

For more information about Autoscaling, visit the [Autoscaling docs page](/manage-resources/autoscaling.html).

{{< /note >}}

### Zero-downtime example

If your [application takes longer to become responsive](/learn/overview/build-deploy.html#application-is-slow-to-start), traffic might be switched back to your original application before it’s fully ready. This can cause temporary errors immediately after deployment.

`post_start` can help co-ordinate so the app receives traffic only when it’s fully ready. An example of a `post_start` command waiting for your application would be:

```
web:
commands:
post_start: |
date
curl -sS --retry 20 --retry-delay 1 --retry-connrefused localhost -o /dev/null
```
{{< note theme="info" title="Zero Downtime Deployment" >}}

For more information about Zero Downtime Deployment, visit the [build deploy documentation page](/learn/overview/build-deploy.html#zero-downtime-deployments).

{{< /note >}}

## Related content

- [Build and Deploy overview](/learn/overview/build-deploy.html)
- [Autoscaling](/manage-resources/autoscaling.html)
- [Single-runtime Image reference](/create-apps/app-reference/single-runtime-image.html#web-commands)
- [Zero-downtime deployments](/learn/overview/build-deploy.html#zero-downtime-deployments)


<!-- vale on -->
Loading