---
title: Container runtime contract
description: The rules a container app's image must follow. Where the platform can adapt an image, it does, and leaves a notice on the version page.
url: https://agentlab.cresclab.com/docs/en/deploy/runtime-contract
language: en
updated: 2026-10-06
---

# Container runtime contract

The rules a container app's image must follow. Where the platform can adapt an image, it does, and leaves a notice on the version page.

## Rules

| Item              | Requirement                       | If not met                                                                                                                 |
| ----------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Start command     | A `CMD` or `ENTRYPOINT`.          | The version is refused.                                                                                                    |
| Port              | Serve HTTP on `$PORT`.            | Chosen from setting → `EXPOSE` → 8080; see [App settings](https://agentlab.cresclab.com/docs/en/deploy/app-settings.md#port). |
| Platform          | `linux/amd64`.                    | A push for another platform is refused.                                                                                    |
| User              | A non-root `USER` is recommended. | Root or no `USER` runs as uid 10001, group 0. A `USER` the image doesn't have is refused.                                  |
| Filesystem        | Read-only apart from `/tmp`.      | Writes elsewhere fail.                                                                                                     |
| Cloud credentials | None are provided.                | Use the app's secrets to reach outside services.                                                                           |

When an image runs as uid 10001, the files it reads must be readable by group 0.

## Notices

What the platform adapted shows as notices on the version page and the image's **Check** tab. AI tools read the same codes from the deploy status.

| Code                  | Meaning                                                                                                               | What to do                                                                                                                             |
| --------------------- | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `imageUserForced`     | The image runs as root, so it runs as uid 10001.                                                                      | Nothing. To clear the notice, set a non-root `USER` in the Dockerfile.                                                                 |
| `imagePortFromExpose` | The app listens on the one port the image exposes.                                                                    | Nothing.                                                                                                                               |
| `imagePortsAmbiguous` | The image exposes several ports and none is 8080, so it runs on 8080, which is probably not where the server listens. | Choose the right port in **Settings › Runtime settings › Port** and restart the service, or `EXPOSE` only that port in the Dockerfile. |

## Images that write files at start-up

Some images write outside `/tmp` when they start. `nginx:alpine`, for example, writes to `/var/cache/nginx` and fails on a read-only filesystem. Use an image that doesn't need to write, or move its writes to `/tmp`:

```dockerfile Dockerfile
FROM nginxinc/nginx-unprivileged:alpine
COPY dist/ /usr/share/nginx/html/
```

> [!TIP] Only serving static files?
> [Deploy a static site](https://agentlab.cresclab.com/docs/en/deploy/static-site.md) instead. You don't need to run nginx yourself.
