Skip to Content
Agent computeCustom Dockerfile runtime
Raw

Custom Dockerfile runtime

Every other Aetherfy runtime — python3.11, node22, bun and the rest — has Aetherfy generate the container for you. runtime: dockerfile is the opposite arrangement: you supply the entire Dockerfile and Aetherfy builds it as-is.

The trade is total control for total responsibility. Use it when your program needs a toolchain Aetherfy does not ship — Go, Rust, Java, a system library, a compiled binary.

What changes when an Aetherfy agent uses the dockerfile runtime

Standard runtimeruntime: dockerfile
Who writes the DockerfileAetherfy, from a runtime templateYou
Platform runner injectedYesNo — but a type: job agent still gets the task supervisor
GET /health endpointProvided for youYou must implement it
Signal handling on shutdownHandled for youYours for a service — see below the table
entrypoint: in aetherfy.yamlSelects the file to runIgnored — your CMD/ENTRYPOINT decides
Lockfile requirementsEnforced for Node and BunSkipped — you pin dependencies yourself

Shutdown in a custom service container is yours. There is no supervisor in front of a service built from your own Dockerfile, so when Aetherfy stops the machine your container’s own main process receives SIGTERM directly, and the machine is sent SIGKILL 120 seconds later. Handling that signal — and stopping any processes your code started — is up to you. A type: job container is different: the task supervisor is in front of it, so a stop works as it does for any task — see /agents/task-contract.

The consequential row is the health endpoint. Aetherfy health-checks every service agent at GET /health on port 8080. A standard runtime gets that for free from the injected runner; with a custom Dockerfile nothing is injected, so an agent that does not answer /health will never be considered healthy.

A task in a custom container works like any task. A type: job agent on Aetherfy is driven by a supervisor that receives each run, hands your code its payload and reports what it returned. That supervisor is one small static binary, and Aetherfy places it in front of your container’s own command: your Dockerfile is built exactly as you wrote it, and the ENTRYPOINT/CMD your image declares becomes the command Aetherfy runs once per run request. Your image is not modified and your command is not replaced. Everything on The task contract applies — the payload file, the result file, exit codes, logs and the one-run-at-a-time rule.

Your image must declare an ENTRYPOINT or a CMD, inherited from your base image or written in your Dockerfile. An image that declares neither has no command to run, and the deploy is refused with a message saying so.

What an Aetherfy dockerfile archive must contain

A Dockerfile at the root of the uploaded archive — the same directory as aetherfy.yaml, not in a subfolder.

aetherfy.yaml # runtime: dockerfile Dockerfile # required, at the root src/ main.go # or any language you like

A complete aetherfy.yaml:

name: my-go-agent runtime: dockerfile type: service memory_mb: 512 regions: - us-east-1

A complete Dockerfile — a Go multi-stage build that satisfies everything Aetherfy checks for:

FROM golang:1.22-alpine AS builder WORKDIR /app COPY . . RUN go build -o server . FROM alpine:3.19 WORKDIR /app COPY --from=builder /app/server . EXPOSE 8080 CMD ["./server"]

Your program must listen on port 8080 and serve GET /health with HTTP 200.

What Aetherfy validates in a custom Dockerfile

Validation runs in two tiers. These block the build and put the deployment into failed:

ConditionResult
No Dockerfile at the archive rootBuild fails: “runtime ‘dockerfile’ is set but no Dockerfile was found in the archive. Add a Dockerfile to your project root.”
No CMD and no ENTRYPOINT instructionBuild fails — nothing would start

These are logged as warnings and do not block the build:

ConditionWhy it is flagged
No EXPOSE instructionThe port is likely unreachable
No /health path detected in the imageHealth checks will not pass
chmod 777 or world-writable filesOverly permissive permissions
Runs as root with no USER instructionContainer runs privileged

Aetherfy’s validation is deliberately non-exhaustive — it catches the common mistakes rather than linting arbitrary Dockerfiles. A build that passes validation is not thereby certified correct.

Which Aetherfy plans allow the dockerfile runtime

PlanCustom Dockerfile
FreeNot available
StarterAvailable
PerformanceAvailable
EnterpriseAvailable

Creating an agent with runtime: dockerfile on Free is rejected with HTTP 400 and a message naming the restriction. The gate also applies in reverse: an account with a dockerfile agent cannot downgrade to Free until that agent moves to a standard runtime, and the downgrade check names the offending agent.

Because a runtime is immutable once an agent exists, switching an existing agent to or from dockerfile is not possible — a changed runtime is rejected with RUNTIME_IMMUTABLE. Delete the agent and recreate it, or create a new one alongside. See the aetherfy.yaml reference.

Aetherfy environment variables in a custom container

A custom Dockerfile changes nothing about the environment your agent receives. Aetherfy injects the same variables it injects for a standard runtime — AETHERFY_AGENT_ID, AETHERFY_AGENT_NAME, AETHERFY_REGION, AETHERFY_MEMORY_MB, AETHERFY_VCPUS, AETHERFY_API_KEY, AETHERFY_API_URL, AETHERFY_VECTORS_URL, AETHERFY_SPAWN_URL, AETHERFY_DEPLOYMENT_ID, AETHERFY_SPAWN_ID on ephemeral runs, and AETHERFY_WORKSPACE when the agent declares a workspace — plus every secret you have set.

Logging is unchanged too: whatever your container writes to stdout and stderr becomes the agent’s logs. See Runs and logs.

Installing the Aetherfy SDK in a custom container

The standard runtimes preinstall it; a custom container does not. Aetherfy writes the dependency steps for a standard image and can put the SDK in one. It does not write yours, so if your code imports the agent helper — payload, machine, fan_out, spawn, write_result, result, wait — install it in your own Dockerfile, like any other dependency:

RUN pip install aetherfy-vectors
RUN npm install aetherfy-vectors

Nothing on the task contract requires the SDK. Every call it makes is an environment variable, a file, or a documented REST endpoint, and a container that reads those directly needs no package at all.

Last updated on