Skip to content

Apps and Services

EasyRunner uses app for the deployable thing you operate. The Compose file format uses service for each container/process inside that app.

Compose means the file format

EasyRunner reads Compose-format YAML, then converts it into Podman/systemd configuration. These docs use Compose as shorthand for the Docker Compose file format, not the Docker Compose CLI tool.

The Model

flowchart TD
  app[EasyRunner app stack]
  meta[App metadata]
  secrets[App secrets]
  services[Service entries]
  web[web service]
  api[internal API]
  worker[worker]
  redis[redis]

  app --> meta
  app --> secrets
  app --> services
  services --> web
  services --> api
  services --> worker
  services --> redis

An EasyRunner app can be one public web service, or it can be a small stack of services that work together.

One-Service App

app: docs-site
└── service: web

This is the common first deployment. The service listens on an internal port, and Caddy routes public HTTPS traffic to it.

Multi-Service App

app: customer-portal
├── service: web       public
├── service: api       internal
├── service: worker    internal
└── service: redis     internal

Only the service you mark as public should receive external traffic. Internal services remain on the app network.

App is the lifecycle unit. You add, deploy, inspect, start, stop, restart, and remove it with er app ....

Service is a process/container inside the app. Services are declared under services: in the Compose-format file.

Public service means Caddy can route HTTPS traffic to it. Internal services remain on the app network.

Compose-Format Labels

EasyRunner reads labels on service entries to understand how to route and run them. The canonical labels use the service.* prefix:

labels:
  xyz.easyrunner.service.type: web # (1)!
  xyz.easyrunner.service.domain: app.example.com # (2)!
  xyz.easyrunner.service.framework: standardbackend
  xyz.easyrunner.service.port: "3000" # (3)!
  1. Service role: web, internal, or worker. web means this service can receive public traffic through Caddy.
  2. The public domain Caddy routes to this web service. Each web service has its own; an app can route several domains.
  3. Internal container port Caddy should proxy to.

Renamed from app* labels

The older appNodeType, appFramework, and appContainerInternalPort labels still work for backward compatibility, but the service.* names are canonical. Prefer them for new files.

See Compose-Format Files and Labels for the reference.