> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akua.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub build workflows

> Reusable GitHub Actions workflows that build container images and notify Akua

<Frame>
  <img className="block dark:hidden" src="https://mintcdn.com/akua-1dce587a/3H5lVc027NQakOso/images/heros/github-actions-light.svg?fit=max&auto=format&n=3H5lVc027NQakOso&q=85&s=9cc3ef9035f9a1eaa9e3b8a3fd16fb60" alt="A GitHub Actions workflow checking out code, building a container image, pushing to a registry, and notifying Akua that a new image is ready" width="1536" height="864" data-path="images/heros/github-actions-light.svg" />

  <img className="hidden dark:block" src="https://mintcdn.com/akua-1dce587a/3H5lVc027NQakOso/images/heros/github-actions-dark.svg?fit=max&auto=format&n=3H5lVc027NQakOso&q=85&s=0362d50690be409f331e13cd4b1f9462" alt="A GitHub Actions workflow checking out code, building a container image, pushing to a registry, and notifying Akua that a new image is ready" width="1536" height="864" data-path="images/heros/github-actions-dark.svg" />
</Frame>

<Card title="View repository" icon="github" href="https://github.com/akua-dev/actions">
  Browse the reusable GitHub Actions workflows repository.
</Card>

Akua provides reusable GitHub Actions workflows that build container images from your source code using <Tooltip headline="Railpack" tip="Railpack is a modern build system that transforms application source code into container images without requiring a Dockerfile. It uses BuildKit to run build steps in parallel for faster builds, analyzes your code to create optimized build plans, and uses granular caching to speed up subsequent builds.">Railpack</Tooltip> and notify Akua when new images are ready for Package generation.

<Note>
  Already have a build pipeline? You can use the `build-railpack` action on its own to run just the Railpack build step inside your existing workflow. See [Using individual actions](#using-individual-actions) for details.
</Note>

## What it does

The Akua GitHub Actions workflows automate the image build path:

1. **Checkout code:** Retrieves your repository code.
2. **Language detection:** Railpack automatically detects your language and framework.
3. **Build configuration:** Uses Railpack defaults unless you override build or runtime settings.
4. **Image building:** Builds a production-ready Docker image using Railpack.
5. **Registry push:** Pushes the image to GitHub Container Registry (GHCR).
6. **Akua notification:** Notifies Akua that the new image can be used by the Package.

This means you can push code to GitHub and have container images ready for Akua Package generation without writing Dockerfiles or managing build pipelines.

## Quick start

Add the workflow to your repository with the required permissions:

```yaml highlight={8,10-12} theme={null}
name: Akua Build Image
on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  cnap:
    uses: akua-dev/actions/.github/workflows/cnap.yml@main
    permissions:
      contents: read
      packages: write
      id-token: write
    secrets: inherit
```

This workflow:

* Detects your application's language and framework when Railpack supports it.
* Builds a container image using Railpack.
* Pushes to `ghcr.io/your-username/your-repo:sha-<commit-sha>`.
* Notifies Akua about the new build.

## Configuration options

You can customize the workflow behavior with optional inputs:

<ParamField path="build-context" type="string" default="./">
  Directory containing your application code. Use this for monorepos or projects with multiple applications.
</ParamField>

<ParamField path="build-command" type="string">
  Override Railpack's automatically detected build command. If not specified, Railpack analyzes your code to determine the build command.
</ParamField>

<ParamField path="start-command" type="string">
  Override Railpack's automatically detected start command. If not specified, Railpack analyzes your code to determine the start command.
</ParamField>

<ParamField path="build-apt-packages" type="string">
  Space-separated list of additional apt packages needed during the build phase (for example, `python3-dev libpq-dev`).
</ParamField>

<ParamField path="runtime-apt-packages" type="string">
  Space-separated list of additional apt packages needed at runtime (for example, `postgresql-client curl`).
</ParamField>

### Custom build context

For monorepos or projects with multiple applications:

```yaml theme={null}
jobs:
  deploy-api:
    uses: akua-dev/actions/.github/workflows/cnap.yml@main
    permissions:
      contents: read
      packages: write
      id-token: write
    secrets: inherit
    with:
      build-context: './apps/api'

  deploy-web:
    uses: akua-dev/actions/.github/workflows/cnap.yml@main
    permissions:
      contents: read
      packages: write
      id-token: write
    secrets: inherit
    with:
      build-context: './apps/web'
```

### Custom dependencies

Add system packages for build or runtime:

```yaml theme={null}
jobs:
  cnap:
    uses: akua-dev/actions/.github/workflows/cnap.yml@main
    permissions:
      contents: read
      packages: write
      id-token: write
    secrets: inherit
    with:
      build-apt-packages: 'python3-dev libpq-dev'
      runtime-apt-packages: 'postgresql-client'
```

## Supported languages

Railpack supports 10+ languages and frameworks with automatic detection:

* **Node.js:** Express, Next.js, SvelteKit, Remix, Nuxt
* **Python:** Django, FastAPI, Flask
* **Go:** Gin, Echo, Chi
* **PHP:** Laravel, Symfony
* **Java:** Spring Boot, Quarkus
* **Ruby:** Rails, Sinatra
* **Rust:** Actix, Rocket, Axum
* **Deno:** Web frameworks
* **Elixir:** Phoenix
* **Static files:** HTML, CSS, JavaScript
* **Shell scripts:** Bash applications

See the [Railpack documentation](https://railpack.com) for complete language support and configuration options.

## How it works with Akua

When you connect a GitHub repository to Akua and the workflow runs:

1. **Workflow builds image:** The GitHub Actions workflow builds your application using Railpack.
2. **Image pushed to GHCR:** The built image is pushed to GitHub Container Registry.
3. **Akua notified:** The workflow automatically notifies Akua about the new build.
4. **Build appears in Akua:** The build shows up in your source's build history.
5. **Ready to package:** You can select the new build when creating a Package version.

<Note>
  The workflow uses OIDC authentication to securely notify Akua without requiring API keys or secrets. The `id-token: write` permission enables this secure authentication method.
</Note>

## Integration with Akua products

When you create a product in Akua using a GitHub repository source:

1. **Repository connected:** Akua connects to your GitHub repository via GitHub App.
2. **Builds detected:** Akua automatically detects builds from the workflow.
3. **Images available:** Built images appear in the build selection interface.
4. **Build updates:** New builds appear when the workflow runs. Create a new Package version or repository change request when a build should reach an installation.

You do not need to manually configure the workflow in most cases. Akua handles the integration automatically when you connect a GitHub repository.

## Using individual actions

The reusable workflow is composed of individual reusable actions that you can use independently in your existing pipelines. This is useful when you already have a build process and want to reuse just the Railpack build step.

### Available actions

The repository provides these reusable actions:

| Action | Description | Use case |
| - | - | - |
| `build-railpack` | Builds a Docker image using Railpack | Use when you want Railpack builds but need custom workflow steps |
| `setup-buildkit` | Starts a BuildKit container | Use when you need BuildKit for custom builds |
| `stop-buildkit` | Stops the BuildKit container | Use to clean up BuildKit after builds |
| `generate-railpack-config` | Generates Railpack configuration file | Use when you need custom Railpack config |

### Using the build-railpack action

If you want to use Railpack for building but need more control over your workflow:

```yaml highlight={10-13,19-22} theme={null}
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Install Railpack
        run: curl -sSL https://railpack.com/install.sh | bash

      - name: Setup BuildKit
        uses: akua-dev/actions/.github/actions/setup-buildkit@main

      - name: Build with Railpack
        uses: akua-dev/actions/.github/actions/build-railpack@main
        with:
          image-name: ghcr.io/${{ github.repository }}:${{ github.sha }}
          build-context: './src'

      - name: Push image
        run: docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
```

#### build-railpack action parameters

<ParamField path="image-name" type="string" required>
  Full Docker image name including registry and tag (for example, `ghcr.io/owner/repo:sha-abc123`).
</ParamField>

<ParamField path="build-context" type="string" default="./">
  Directory containing application code. Use this for monorepos or projects with multiple applications.
</ParamField>

<ParamField path="build-command" type="string">
  Override Railpack's automatically detected build command. If not specified, Railpack analyzes your code to determine the build command.
</ParamField>

<ParamField path="start-command" type="string">
  Override Railpack's automatically detected start command. If not specified, Railpack analyzes your code to determine the start command.
</ParamField>

## Advanced usage

### Custom build commands

Override Railpack's automatic detection:

```yaml theme={null}
with:
  build-command: 'npm run build:production'
  start-command: 'node server.js'
```

### Multiple environments

Deploy different branches to different environments:

```yaml theme={null}
on:
  push:
    branches: [main, staging]

jobs:
  cnap:
    uses: akua-dev/actions/.github/workflows/cnap.yml@main
    permissions:
      contents: read
      packages: write
      id-token: write
    secrets: inherit
    with:
      build-context: ${{ github.ref == 'refs/heads/main' && './apps/prod' || './apps/staging' }}
```

## Related topics

<CardGroup cols={2}>
  <Card title="GitHub integration" icon="github" href="/platform/github-integration">
    Connect GitHub repositories to Akua.
  </Card>

  <Card title="App sources" icon="code" href="/app-sources">
    GitHub repository sources.
  </Card>

  <Card title="Container image sources" icon="box" href="/tools/generic-chart">
    How GitHub builds and Docker images become Package versions.
  </Card>

  <Card title="Create a product" icon="box" href="/products">
    Create products from GitHub repositories.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.