Harthelm Docs
Guides

Run a container image

Run your own OCI image as a container service.

Last updated 2026-10-19

A container service runs an image you built elsewhere: a search engine, a queue, a service in a language your workspace does not have. Harthelm runs the image's entrypoint and command; there are no steps.

Add the service

harthelm.yml
services:
  search:
    type: container
    image: registry.example.com/team/search@sha256:4f1c2b…
    env:
      HTTP_PORT: 8080
    ports:
      - port: 8080
        routes:
          - path: /search
            strip: true
    health:
      port: 8080
      path: /healthz

Sync. The review resolves the image and shows the service under "To add". A container service starts at the Sync and keeps running: it does not wait for Run, and Stop and Start on its row control it.

Ports, routes, health checks, plan, replicas, env, needs and sleep work as for any service; see Configure services.

Pin the image

Sync resolves the image to a digest and the pods run exactly that digest until the next Sync. Name the digest yourself (@sha256:…) so every Sync runs the same image; an image by tag gets a warning in the review, and a Sync after the tag moved rolls the pods to the new image.

Change the command

command replaces the image's ENTRYPOINT and args its CMD:

harthelm.yml
  worker:
    type: container
    image: registry.example.com/team/app@sha256:4f1c2b…
    command: ["/app/bin/worker"]
    args: ["--queue", "default"]

An image with neither ENTRYPOINT nor CMD needs command; otherwise the Sync is blocked.

The user it runs as

A container service runs as the workspace's user, a random non-root UID with group 0, whatever USER the image names. The review warns when the image expects another user. Build images that work under any UID: files the process writes belong to group 0 and are group-writable.

runAsUser is only for teams a cluster admin allowed (team Settings → Container services). Without that permission a file that sets it is refused at Sync.

Private images

An image from a private registry needs the team's credentials for it; see Use private registries. Your installation may also allow only some registries; a refused or missing image blocks the Sync with the reason.

Mount files from your code

A container sees only what you mount; it does not get /data/app. Put files of your code into it with mounts:

harthelm.yml
    mounts:
      - from: config/search.yaml
        to: /etc/search/config.yaml

When it does not start

The review or the Run panel saysCause
image-unavailableThe image or tag does not exist, the registry refused the pull, or the image has no entrypoint and no command
run-as-not-allowedrunAsUser is set, but the team may not choose the user
FailedThe process exited 5 times within 2 minutes; its Logs say why

Next steps

On this page