Skip to content

Services

Services are the core of your lokl configuration. Each service represents a process or container that makes up your development environment.

For local processes:

services:
frontend:
command: pnpm dev
path: apps/frontend
port: 5173
FieldTypeDescription
commandstringShell command to run
pathstringWorking directory (relative to config)
portintPort the service listens on
envmapEnvironment variables
env_filelistPaths to .env files to load
depends_onlistServices to start first
autostartboolStart automatically (default: true)
restartstringRestart policy: no, always, on-failure

For Docker containers:

services:
db:
image: postgres:16
ports:
- "5432:5432"
port: 5432
subdomain: db
env:
POSTGRES_PASSWORD: secret
volumes:
- ./data:/var/lib/postgresql/data
FieldTypeDescription
imagestringDocker image
portslistPort mappings (host:container)
portintHost port for proxy routing and health checks
envmapEnvironment variables
env_filelistPaths to .env files to load
volumeslistVolume mounts (host:container)
subdomainstringSubdomain for proxy routing
depends_onlistServices to start first
healthobjectHealth check configuration (see below)
autostartboolStart automatically (default: true)
restartstringRestart policy: no, always, on-failure

Control startup order with depends_on:

services:
api:
command: pnpm dev
depends_on:
- db
- redis
db:
image: postgres:16
redis:
image: redis:7

Monitor HTTP services:

services:
api:
command: pnpm dev
port: 3000
health:
path: /health
interval: 10s
timeout: 5s
retries: 3

For data services that have no HTTP endpoint (databases, caches):

services:
db:
image: postgres:16
health:
command: "pg_isready -U myapp" # string → sh -c wrap
interval: 2s
timeout: 1s
retries: 10
cache:
image: redis:7
health:
command: ["redis-cli", "ping"] # array → exec directly (no shell)
interval: 1s
retries: 5

path and command are mutually exclusive — use one or the other.

Containers in the same lokl project share a bridge network (lokl-{name}). They can reach each other by service name as hostname — no need to expose ports between containers:

services:
api:
image: myapp:latest
env:
DB_HOST: db # reaches the "db" container directly
REDIS_HOST: cache # reaches the "cache" container directly
depends_on:
- db
- cache
db:
image: postgres:16
health:
command: "pg_isready -U myapp"
retries: 10
cache:
image: redis:7
health:
command: ["redis-cli", "ping"]
retries: 5

The network is created on lokl up and removed on lokl down.

Load variables from .env files instead of hardcoding secrets:

# Global — available to all services
env_file:
- .env
services:
api:
command: pnpm dev
env_file:
- .env.local

Standard dotenv format: KEY=VALUE, # comments, blank lines, optional quotes. Paths are relative to lokl.yaml.

Inline env values take priority over env_file values.

Reference host environment variables with ${VAR} or $VAR:

services:
api:
command: pnpm dev
env:
DATABASE_URL: postgres://${DB_USER}:${DB_PASS}@localhost:5432/mydb

Variables are resolved against the host’s environment at config load time. Missing variables expand to an empty string.