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

# Service types

> Every Brimble project has a service type.

Every Brimble project has a service type. The type determines build behavior, runtime model, and what's exposed.

| Service type    | Build source                                                     | Runtime                       | Public URL                                      | Health check                  | Use for                                                                       |
| --------------- | ---------------------------------------------------------------- | ----------------------------- | ----------------------------------------------- | ----------------------------- | ----------------------------------------------------------------------------- |
| **Web service** | Git repo (Railpack / `Dockerfile`) **or** pre-built Docker image | Container, listens on `$PORT` | Yes                                             | HTTP GET on `healthCheckPath` | Express, Django, Rails, FastAPI, Spring Boot, Phoenix, any HTTP server        |
| **Static site** | Git repo (frontend builder)                                      | None, assets served from edge | Yes                                             | None                          | Next.js (export), Vite, Astro, Hugo, plain HTML/JS                            |
| **Worker**      | Git repo (Railpack / `Dockerfile`) **or** pre-built Docker image | Container, no port            | No                                              | Process liveness              | Queue consumers, schedulers, background jobs                                  |
| **Database**    | Managed image                                                    | Engine-specific               | No (private endpoint) and Yes (public endpoint) | Engine readiness probe        | Postgres, MySQL, MariaDB, MongoDB, Redis, Valkey, RabbitMQ, Neo4j, ClickHouse |
| **MCP server**  | Git repo (Railpack / `Dockerfile`) **or** pre-built Docker image | Container, listens on `$PORT` | Yes                                             | HTTP GET on `healthCheckPath` | Remote MCP servers for AI clients                                             |

## Web service

A long-running container that handles HTTP traffic.

**Source options:**

* **Git repository**, Brimble builds from source using Railpack (auto-detected) or a `Dockerfile` if one is at the project root.
* **Docker image**, pull a pre-built image from Docker Hub, GHCR, or any container registry. See [Deploy from a Docker image](/projects/deploy-from-docker-image).

**Required:**

* The container's start command must listen on `process.env.PORT`.
* Listening on `0.0.0.0` (not `localhost` or `127.0.0.1`).

**Auto-detected for Git source:** Node (Express, Fastify, Next.js standalone, NestJS), Python (FastAPI, Django, Flask), Ruby (Rails, Sinatra), Go, Java (Spring Boot), Rust, Elixir (Phoenix), PHP (Laravel).

**Configurable:**

* Install command, build command, start command.
* Health check path (default `/`).
* Pre-start command (runs once per build, before push).
* Watch paths (monorepo support).
* Build cache toggle.
* Persistent disk (mount path + size from 1, 5, 10, 25, 50, 100 GB).
* Site password / basic auth.
* Auto-deploy on push (Git source).

## Static site

A pure asset deploy: Brimble's frontend builder runs your build, captures the output directory, and ships the files. **No container is created and no runtime cost is billed.**

**Required:**

* A `build` command that produces the output directory.
* An output directory configured in **Settings → Build** (e.g. `dist`, `out`, `build`, `public`).

**Auto-detected for:** Next.js (`next export`), Vite, Astro, Hugo, Jekyll, Eleventy, Gatsby, Docusaurus, MkDocs, SvelteKit static, Remix static, plain HTML repos.

<Warning>
  **Frameworks with both SSR and static modes must be explicitly configured for static output.** A vanilla Next.js or Nuxt repo defaults to SSR, the build emits server-runtime artifacts that need a Node process. A static-site deploy doesn't have a runtime, so the build runs, the upload succeeds, and the deployed site loads blank.

  **Next.js.** Set `output: "export"` in `next.config.js` (or `.mjs`/`.ts`):

  ```js theme={null}
  // next.config.js
  module.exports = {
    output: "export",
  };
  ```

  Next.js emits a real `out/` directory of HTML/CSS/JS at build time.

  **Nuxt 3.** Run `nuxi generate` instead of `nuxi build` (or set `nitro.preset: "static"` in `nuxt.config.ts`):

  ```ts theme={null}
  // nuxt.config.ts
  export default defineNuxtConfig({
    nitro: {
      preset: "static",
    },
  });
  ```

  Nuxt emits a prerendered `.output/public/` directory; set that as the **output directory** in **Configuration**.

  **Either way, you lose** server-side rendering, API routes, middleware, on-demand revalidation, and image optimization, anything that needs a server at runtime. If your app uses any of those, deploy as a [Web service](#web-service) instead (paid plans only).

  Same caveat applies to **SvelteKit** (use `@sveltejs/adapter-static`) and **Remix** (use the static adapter). **Astro, Hugo, Eleventy, Jekyll, and Gatsby** default to static, so they Just Work.
</Warning>

### How a static-site request is served

A deploy goes through the standard build phases (clone, detect, install, build) and then takes a different path at orchestrate:

1. The frontend builder uploads the built assets to Brimble's **globally distributed object storage** for static artifacts. Each project gets its own prefix; the latest active deployment is what users see.
2. The deployment goes live the moment the upload finishes. There's no health check, no container start, no Nomad scheduling.
3. Brimble's gateway serves requests directly from the storage layer. The static path short-circuits the container-routing logic, requests don't fan out to a backend, they fan out to objects.
4. Cloudflare sits in front of every public request, so most asset hits are answered from the closest Cloudflare data center to the user without ever reaching Brimble.
5. When a deploy goes live, Cloudflare's cache for the project's hostnames is purged automatically so the new version is visible immediately.

This is why static sites are faster and cheaper than web services on Brimble: no idle compute, no cold starts, and most requests are served from cache at the edge.

### Cache headers

The gateway sets `Cache-Control` per response so Cloudflare and browsers cache the right things for the right durations:

* **HTML documents:** `no-store, no-cache, must-revalidate, max-age=0` (always fresh after a deploy).
* **Hashed asset paths** (`/assets/*`, `/_assets/*`, `/static/*`) and immutable extensions (`.js`, `.css`, fonts, images): `public, max-age=31536000, immutable` (cached for a year, invalidated automatically by content-hashed filenames).
* **Other static files:** `public, max-age=3600, must-revalidate`.

See [Edge caching](/projects/builds#edge-caching) in the builds doc for the full table and the reasoning.

### What you don't need

* **A start command.** The artifact is files, not a process.
* **A `PORT`.** No HTTP server is spawned.
* **A health check path.** Probes don't apply.
* **Resource sizing.** CPU and memory aren't billed for static sites; storage and bandwidth are.

### SPA fallback

If your build is a single-page app (Vite, CRA, Remix static, etc.) and a request path doesn't match a file in your output directory, the gateway falls back to `index.html` so client-side routing works. You don't need to configure rewrites; this is the default.

## Worker

A background container with no inbound HTTP. Identical build pipeline to a web service; the difference is no port is exposed and no HTTP probe runs.

**Required:**

* A `start` command that runs forever. If your start command exits, Brimble restarts it.

**Common patterns:**

* BullMQ / Sidekiq / Celery / RQ workers.
* Long-polling consumers.
* In-process schedulers (`node-cron`, `APScheduler`).

## Database

A managed instance of a database engine. You don't push code; you pick an engine and version.

**Engines and typical use:**

| Engine     | Type           | Use for                                         |
| ---------- | -------------- | ----------------------------------------------- |
| PostgreSQL | Relational     | Default choice for relational data              |
| MySQL      | Relational     | MySQL-specific stacks (Rails legacy, WordPress) |
| MariaDB    | Relational     | Drop-in MySQL replacement                       |
| MongoDB    | Document       | Flexible-schema document workloads              |
| Redis      | Key/value      | Cache, sessions, queues                         |
| Valkey     | Key/value      | Drop-in Redis replacement                       |
| RabbitMQ   | Message broker | AMQP queues, pub/sub                            |
| Neo4j      | Graph          | Relationship-heavy data                         |
| ClickHouse | Columnar       | Analytics, OLAP, log aggregation                |

**Versions** available per engine are listed in the dashboard during provisioning. Brimble carries multiple major versions per engine.

**Sizing:** CPU, memory, and storage in GB. Storage can grow but not shrink.

**Backups:** Optional, scheduled.

## MCP server

A web service tuned for Model Context Protocol traffic. Build and runtime model are identical to a web service. The dashboard offers MCP-specific helpers (auth presets, common transport patterns).

**Required:**

* HTTP transport (Streamable HTTP, SSE, or WebSocket). MCP servers using stdio transport only don't work for remote deployment.
* Listening on `process.env.PORT`.

## Choosing the right type

If your repo has a build script that emits a folder of static assets and nothing needs to keep running, pick **static site**. It's faster and cheaper than a web service.

If your code needs to handle HTTP traffic, pick **web service**.

If your code runs forever but doesn't serve traffic, pick **worker**.

If you need a data store, pick **database**.

If you're shipping an MCP server for AI tools, pick **MCP server**.

When in doubt, **web service** is the safe default, anything that listens on `$PORT` will work.

## Switching service types

A project's service type is set at creation and isn't changed in place. To switch (e.g. from web service to static site), create a new project with the right type, copy env vars over, attach domains, then delete the old project.
