> ## 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.

# Deploy from a Docker image

> Deploy a project from a pre-built Docker image instead of building from source.

Deploy a project from a pre-built Docker image instead of building from source. Useful when:

* Your image is already built by a separate CI pipeline.
* You're deploying a third-party image (databases, tools, MCP servers published as images).
* You want a simple no-build path: pull and run.

## Prerequisites

* A Docker image hosted on a [supported registry](#supported-registries).
* A Brimble account.

## Supported registries

Brimble can pull from the following registries. Public images pull anonymously; private images use the credentials you provide on the project (one **username** + **token / password** form, regardless of registry).

| Registry                                 | Hostname format                                                                                    | What to put in the credentials form (private images)                                  |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| **Docker Hub**                           | `nginx:latest`, `myorg/image:tag` (no prefix needed)                                               | Docker Hub username + a Personal Access Token.                                        |
| **GitHub Container Registry (GHCR)**     | `ghcr.io/org/image:tag`                                                                            | GitHub username + a PAT with the `read:packages` scope.                               |
| **Google Container Registry (GCR)**      | `gcr.io/project/image:tag`, or regional (`us.gcr.io`, `eu.gcr.io`, `asia.gcr.io`)                  | `_json_key` as username + the contents of a service-account JSON key as the password. |
| **Red Hat Quay**                         | `quay.io/org/image:tag`                                                                            | Quay username (or a robot account name) + the matching token.                         |
| **AWS Elastic Container Registry (ECR)** | `<account>.dkr.ecr.<region>.amazonaws.com/image:tag` (private) or `public.ecr.aws/...` (anonymous) | An IAM-issued ECR auth token as the password (`AWS` is the conventional username).    |
| **DigitalOcean Container Registry**      | `registry.digitalocean.com/<registry>/image:tag`                                                   | A DigitalOcean API token used as both username and password.                          |

Brimble identifies the registry from the image hostname; you don't pick a registry type from a dropdown. Just paste the image URI and, if it's private, expand **Private registry credentials** and fill in username and token.

Custom / self-hosted registries that speak the Docker Registry HTTP API v2 will generally work too, but they're not first-class. If yours behaves oddly, open a support ticket.

## Create the project

1. In the dashboard, click **New project**.
2. Pick **Docker image** as the source.
3. Enter the image reference. Examples:
   * `nginx:latest`
   * `ghcr.io/org/app:v1.2.3`
   * `myteam/my-image:abc123` (Docker Hub)
   * `registry.example.com/team/image:tag` (custom registry)
4. If the image is private, expand **Registry credentials** and enter:
   * **Username**, the registry username.
   * **Password / token**, a password or access token. For GHCR, this is a personal access token with `read:packages`. For Docker Hub, a personal access token works better than your password.

<Frame caption="The Docker source step, image reference and registry credentials.">
  <img src="https://mintcdn.com/brimble-86/VDnKCHWcGHKvY1rj/images/projects/deploy-docker-first-page.jpg?fit=max&auto=format&n=VDnKCHWcGHKvY1rj&q=85&s=137d23e3fdfb0d29c53c8d66e9b39ac5" alt="New-project flow with Docker image selected and registry credentials expanded" width="5088" height="3366" data-path="images/projects/deploy-docker-first-page.jpg" />
</Frame>

<Frame caption="The Docker source step, runtime configuration.">
  <img src="https://mintcdn.com/brimble-86/VDnKCHWcGHKvY1rj/images/projects/deploy-docker-second-page.jpg?fit=max&auto=format&n=VDnKCHWcGHKvY1rj&q=85&s=3049931ed7b9e62ca5862ffad537002f" alt="Second page of the Docker deploy flow showing service type, region, and compute size" width="5088" height="3366" data-path="images/projects/deploy-docker-second-page.jpg" />
</Frame>

5. Configure the runtime:
   * **Service type**, usually **Web service**. Pick **Worker** if the image isn't an HTTP server.
   * **Region**, datacenter to deploy in.
   * **Compute size**, CPU and memory.
6. Set environment variables your image needs.
7. Click **Deploy**.

Brimble pulls the image, starts a container with your environment variables, and (for web services) routes traffic to it once it passes the health check.

## What Brimble passes to the container

When the container starts, Brimble injects:

* All environment variables you configured for the active environment.
* `PORT`, the port Brimble assigns. Your image must read this and listen on it for web services. (Workers don't need to listen.)
* `BRIMBLE_*` system variables (`BRIMBLE_REGION`, `BRIMBLE_COMMIT_SHA` is empty since there's no commit, `BRIMBLE_PROJECT`, etc.).

The container's command is whatever the image defines (`CMD` or `ENTRYPOINT`). To override, set a custom start command under **Settings → Build**.

## Image requirements

Your image should:

* **Listen on `0.0.0.0:$PORT`** for web services. Don't listen on `127.0.0.1`, Brimble's edge can't reach localhost-only services.
* **Run a foreground process.** A container that exits is treated as crashed and restarted (or marked failed after repeated restarts).
* **Have a `CMD` or `ENTRYPOINT`** that doesn't depend on a TTY. Brimble runs containers non-interactively.

Common adjustment for off-the-shelf images: pass `PORT` through to the existing config. Many images take a port via env var (`-e PORT=8080`); some take it via flag (`--port=$PORT`).

## Pulling private images

For private images, the credentials you entered are stored encrypted and used only when pulling. Rotate them by editing the project's **Build → Registry credentials**.

If a credential expires, the next pull will fail with a deployment error. Update the credential and click **Redeploy**.

## Updating the image

There's no auto-deploy hook for image registries, pushing a new tag doesn't redeploy automatically.

To update:

* **For mutable tags (e.g. `:latest`).** Click **Redeploy**. Brimble re-pulls the tag and starts the new image.
* **For immutable tags (e.g. `:v1.2.4`).** Open **Settings → Build**, change the image reference to the new tag, and save. The next deploy uses the new tag.

For automation, integrate with your CI: have CI call out to Brimble's API to trigger a redeploy after a successful push.

## Troubleshooting

**Pull fails: "no such image" or "manifest unknown."** Triple-check the image reference (registry, namespace, name, tag). Tags are case-sensitive. For private images, confirm the credentials work locally with `docker login` + `docker pull`.

**Pull fails: "unauthorized."** Credentials are wrong or expired. For GHCR, the token needs `read:packages` scope. For Docker Hub, free accounts have rate limits, use an authenticated pull.

**Container starts but immediately exits.** The image's `CMD` ran to completion. Override with a long-running command under **Settings → Build → Start command**, or fix the image's entrypoint.

**Health check fails (502).** The image isn't listening on `$PORT`, or it's listening on `127.0.0.1` instead of `0.0.0.0`. Pass the port through whatever mechanism the image expects, and make sure the bind address is `0.0.0.0`.

**Image is huge and pulls slowly.** Only the first pull per region is uncached; subsequent deploys reuse layers. If the cold pull is unacceptable, switch to a multi-stage build that ships a thinner runtime image.

## Next steps

* [Service types](/projects/service-types), picking the right type for your image.
* [Manage environment variables](/environments/environment-variables), wiring config into your container.
* [Builds](/projects/builds), the alternative path: building from source.
