# Fast Startup with Pre-builds

> Cordium documentation. Canonical page: <https://octelium.com/docs/cordium/latest/examples/workflows/prebuilds>.

Large repositories can take many minutes to become workable: building the development image, cloning the repository, installing thousands of dependencies and warming the build caches. This example sets up a *Template* for a TypeScript monorepo whose *Workspaces* are ready within seconds thanks to pre-builds, and keeps its pre-build fresh by rebuilding it on every push to the main branch (read more about pre-builds [here](https://octelium.com/docs/cordium/latest/workspaces/templates.md#pre-builds)).

## The Template

The image is built from a Dockerfile inside the repository itself, and the expensive work happens in `ON_CREATE` tasks, which run once in the pre-build. The `POST_START` tasks, which run on every start, only bring the repository up to date with the latest commit and start the development server:

```yaml
spec:
  repository:
    url: https://github.com/acme-corp/web-platform
    authentication:
      http:
        username: x-access-token
        password:
          fromSecret: github-read-token.storefront.cordium
  image:
    repository:
      dockerfile:
        path: .cordium/Dockerfile
        context: .
  runtime:
    envVars:
      - key: TURBO_TELEMETRY_DISABLED
        value: "1"
    tasks:
      - name: install
        type: ON_CREATE
        workingDir: /workspace/repo
        onFailure: ON_FAILURE_ABORT
        run: pnpm install --frozen-lockfile
      - name: warm-build-cache
        type: ON_CREATE
        workingDir: /workspace/repo
        onFailure: ON_FAILURE_ABORT
        run: pnpm turbo run build typecheck
      - name: sync
        type: POST_START
        workingDir: /workspace/repo
        run: |
          git pull --ff-only -q
          pnpm install --frozen-lockfile --prefer-offline
      - name: dev
        type: POST_START
        workingDir: /workspace/repo
        isBackground: true
        run: pnpm turbo run dev --filter=storefront -- --host 0.0.0.0
  limit:
    cpu:
      millicores: 8000
    memory:
      megabytes: 16384
    storage:
      megabytes: 50000
```

The `sync` task makes *Workspaces* restored from an older pre-build catch up with the main branch, which is typically fast since only the changes since the pre-build have to be fetched and installed.

```bash
cordium create template web.storefront.cordium --file web.yaml
cordium build web.storefront.cordium
```

You can follow the pre-build from the *Template*'s **Builds** tab in the web portal (read more [here](https://octelium.com/docs/cordium/latest/use/web-portal.md#spaces)) or via `cordium get template web.storefront.cordium -o yaml`. Once the pre-build is `STATE_READY`, every new *Workspace* of the *Template* is restored from it:

```bash
cordium run --template web.storefront.cordium --port web:5173:default
```

> **Note:**
>
> Pre-builds use the `ClusterConfig`'s build limits rather than the *Template*'s limits. Make sure that they are large enough for your heaviest `ON_CREATE` tasks (read more [here](https://octelium.com/docs/cordium/latest/management/clusterconfig.md#limits)).

## Rebuilding on Every Push

A pre-build is a snapshot of a point in time, and the *Template* keeps using it until the next one becomes ready. The simplest way to keep it fresh is to trigger `cordium build` from your CI whenever the main branch changes. Here is a GitHub Actions workflow that authenticates to the *Cluster* as a `WORKLOAD` *User* via GitHub's OIDC identity tokens, which means that no secret is stored in the repository (read more about this setup [here](https://octelium.com/docs/cordium/latest/examples/automation/github-actions.md)):

```yaml
name: Cordium pre-build
on:
  push:
    branches: [main]
    paths:
      - "pnpm-lock.yaml"
      - ".cordium/**"
      - "packages/**"

permissions:
  id-token: write
  contents: read

jobs:
  prebuild:
    runs-on: ubuntu-latest
    env:
      OCTELIUM_DOMAIN: example.com
      OCTELIUM_AUTH_ASSERTION: github-actions:audience=https://example.com
    steps:
      - name: Install the Cordium CLI
        run: curl -fsSL https://octelium.com/install-cordium.sh | bash
      - name: Trigger the pre-build
        run: cordium build web.storefront.cordium
```

Since triggering pre-builds is reserved to the admins of a *Space*, the `WORKLOAD` *User* must be an `ADMIN` *Member* of the `storefront` *Space* (read more [here](https://octelium.com/docs/cordium/latest/workspaces/spaces.md#members-and-roles)). Triggering a new pre-build cancels the one that is still running, if any, which means that a burst of pushes only results in one completed pre-build for the latest commit.
