Octov0.4.2
Deployment

Docker Images

The published images and how they are built.

Octo builds its images from six Dockerfiles. Five produce the platform images, built together and pushed to your own registry (Artifact Registry in the reference deployment). Two are public images on Docker Hub, for use without a cluster: the standalone editor and the runtime on its own.

ImageDockerfileBuild contextRole
octo-runtimeruntime/Dockerfile./runtimeRuns deployed integrations (one pod set per integration)
octo-platformapps/platform/DockerfileRepo rootEditor UI (Next.js) with the octo runtime binary bundled
octo-orchestratororchestrator/Dockerfile./orchestratorDeploys and manages integrations via the Kubernetes API
octo-logslogs/Dockerfile./logsLog aggregator: NATS internal.logs → Postgres + query API
octo-schemasql/Dockerfile./sqlApplies sql/schema.sql as an install/upgrade Job
juancavallotti/octoapps/standalone/DockerfileRepo rootPublic standalone editor ("try Octo"), no cluster needed
juancavallotti/octo-runtimeruntime/Dockerfile./runtimePublic runtime alone: run integrations from Docker, no cluster

The last two rows share a Dockerfile with the cluster's octo-runtime but not a binary: the public image is the default build, the cluster image is built with -tags k8s. See octo-runtime below.

Where they are built

The same five platform images are built in three places, always from the same Dockerfiles and contexts:

  • Locally for k3dtask cluster:images builds them tagged :dev and loads them into the cluster with k3d image import (no registry). See Local cluster.
  • Locally for a registrytask images:push IMAGE_BASE=… TAG=… builds and pushes all five to IMAGE_BASE/<name>:<TAG>.
  • Cloud Build on version tagscloudbuild.yaml builds all five, tags each with both the git tag and latest, pushes them to Artifact Registry, and also packages and pushes the Helm chart as an OCI artifact. See Releases and upgrades.

Both public images are built by the GitHub Actions release workflow (.github/workflows/release.yml) on every version tag, as multi-arch builds (linux/amd64 and linux/arm64) tagged with the release version and latest, and pushed to public Docker Hub.

The images

octo-runtime

A generic image that runs any integration: it carries only the compiled octo binary, built CGO_ENABLED=0. The final stage is gcr.io/distroless/static-debian12:nonroot — no shell, no package manager, runs as nonroot. The default command is octo run --config /etc/octo/integrations, which loads every .yaml/.yml mounted into that directory.

One Dockerfile, two images, differing only in the GOTAGS build arg — which selects the services provider compiled into the binary:

GOTAGSServices providerPublished to
Cluster octo-runtimek8s (default)Lease-based leader election, orchestrator-backed KV, NATS queuesYour registry, by cloudbuild.yaml
Public juancavallotti/octo-runtimeemptyStandalone: in-process queues, in-memory KV, no external infrastructureDocker Hub, by the release workflow

The cluster image is what the orchestrator deploys: one Deployment per integration, with the integration's YAML mounted into the config directory via a per-deployment ConfigMap. The Helm chart hands the image reference to the orchestrator as RUNTIME_IMAGE.

The public image is for running integrations from Docker with no cluster at all — the same engine and the same standalone services a local octo run uses, so a config that works on your machine works here unchanged:

docker run -p 8080:8080 -v "$PWD:/etc/octo/integrations" juancavallotti/octo-runtime

See Running flows locally for ports, environment, and one-shot invoke.

octo-platform

The platform editor UI (Next.js), used in cluster deployments. Its build context is the repo root so the Dockerfile can reach both runtime/ (to build the bundled octo binary for the editor's Run feature) and the pnpm workspace (apps/platform). Serves on port 3000 behind the chart's Ingress and proxies the orchestrator and logs APIs through its BFF.

octo-orchestrator

The Go orchestrator service. Watches for deploy requests and creates the per-integration ConfigMap, Deployment, Service, and optional Ingress through the Kubernetes API (client-go), and serves the KV store to runtime pods. Listens on 8090, ClusterIP only — it is reached solely through the platform's authenticated BFF.

octo-logs

The Go log-aggregator service. Consumes the NATS internal.logs subject as a competing consumer, persists log events to Postgres, and serves the query API behind the platform's /logs view. Listens on 8091, ClusterIP only. Replicas scale safely thanks to the NATS queue group.

octo-schema

A thin postgres:16-alpine that bundles sql/schema.sql — reused purely for its psql client. The Helm chart (and the k3d manifests) run it as a Job that executes psql -f /schema/schema.sql against the Postgres service on every install and upgrade; the schema is idempotent, so re-runs are safe.

juancavallotti/octo (standalone editor)

The self-contained public "try Octo" image: the standalone editor plus the octo runtime binary, with a local-disk flow store — no orchestrator, auth, or database. Published to Docker Hub on every release as a multi-arch build (linux/amd64 and linux/arm64), tagged with the release version and latest.

docker run -p 3000:3000 -v "$PWD:/work" juancavallotti/octo

Like the public octo-runtime, its bundled binary is the default (untagged) build with the standalone services provider; it adds the editor on top. See Running from Docker for usage.

There are also Dockerfile.dev variants for the platform, orchestrator, and logs images (task cluster:images:dev). These are hot-reload images used only by the local DevSpace dev loop — they are never published.

On this page