stack.yaml Reference

stack.yaml Reference

A stack definition lives at .8v/stack.yaml in your project directory. It defines the services 8Vast runs, how they connect, and what resources they get.

File location

8Vast looks for stack definitions in this order:

  1. .8v/stack/ directory (split file format — one YAML per service)
  2. .8v/stack.yaml
  3. .8v/stack.yml

If none exist, 8v stack up reports an error.

Top-level structure

services:
  service-name:
    # ... service configuration

networks:
  network-name:
    # ... network configuration

The file has two top-level keys: services and networks. Services are required. Networks are optional — 8Vast creates a default network if you don't define any.

Service fields

Every field available on a service definition:

services:
  myservice:
    image: "registry/image:tag"       # OCI image (required unless build is set)
    build: ./app                       # Build from Dockerfile (alternative to image)
    command: "npm start"               # Override the image's default command
    cpus: 2                            # CPU cores (default: 1, minimum: 1)
    memory: 1024                       # Memory in MB (default: 512, minimum: 128)
    replicas: 3                        # Number of instances (default: 1)
    ports:
      - "8080:80"                      # Port forwarding (host:container)
    environment:                       # Environment variables
      KEY: value
    env_file: .env                     # Load variables from a file
    volumes:
      - "./data:/app/data"             # Mount host paths into the service
    networks:
      - frontend                       # Which networks to join
    healthcheck:                       # Health monitoring
      test: "curl -f http://localhost/"
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 5s
    restart: unless-stopped            # Restart policy
    depends_on:
      - other-service                  # Start order and dependency

image

The OCI image to run. Use registry/image:tag format. If no tag is specified, latest is assumed.

image: postgres:15
image: redis:7-alpine
image: ghcr.io/myorg/myapp:v2.1

Every service must have either image or build (or both). If both are set, 8Vast builds the image and tags it with the image value.

build

Build an image from a Dockerfile instead of pulling one. Accepts a string (context path) or an object:

# Short form — context path, uses Dockerfile in that directory
build: ./backend

# Long form — specify context and Dockerfile separately
build:
  context: ./backend
  dockerfile: Dockerfile.prod

command

Override the image's default command:

command: "python manage.py runserver 0.0.0.0:8000"

cpus and memory

Resource allocation for the service.

FieldDefaultMinimum
cpus11
memory512 (MB)128 (MB)
cpus: 4
memory: 2048

You can also set container-level resource limits separately from the allocation:

container_cpus: 0.5      # Fractional CPU limit inside the container
container_memory: 256     # Memory limit in MB inside the container

replicas

Run multiple instances of the same service:

replicas: 3

Default is 1.

ports

Forward ports from your machine to the service. Format: "host:container".

ports:
  - "8080:80"       # localhost:8080 -> service port 80
  - "5432:5432"     # same port on both sides
  - "443:443"

Each host port can only be used by one service. 8Vast rejects the configuration if two services try to use the same host port.

environment

Set environment variables. Two formats are supported:

# Map format
environment:
  DATABASE_URL: postgres://localhost:5432/mydb
  REDIS_URL: redis://localhost:6379
  DEBUG: "true"

# List format
environment:
  - DATABASE_URL=postgres://localhost:5432/mydb
  - REDIS_URL=redis://localhost:6379
  - DEBUG=true

Both produce the same result. Use whichever you prefer.

env_file

Load environment variables from a file. The file uses KEY=value format, one per line. Lines starting with # are comments. Empty lines are ignored.

# Single file
env_file: .env

# Multiple files
env_file:
  - .env
  - .env.local

Variables from env_file are loaded first. Inline environment values override them if the same key appears in both.

Example .env file:

# Database
DB_HOST=localhost
DB_PORT=5432

# App
SECRET_KEY="a-long-random-string"

Quoted values (single or double quotes) have the quotes stripped automatically.

volumes

Mount paths from your machine into the service. Format: "host:container" or "host:container:ro" for read-only.

volumes:
  - "./data:/var/lib/postgresql/data"     # Read-write
  - "./nginx.conf:/etc/nginx/nginx.conf:ro"  # Read-only

Volumes persist data across service restarts. If you stop and start a service, the data in mounted volumes is still there.

networks

Assign the service to one or more networks. Services on the same network can reach each other by name.

networks:
  - frontend
  - backend

If you reference a network here, it must be defined in the top-level networks section.

healthcheck

Define how 8Vast checks whether the service is healthy. A service is considered "healthy" only after its health check passes.

healthcheck:
  test: "pg_isready -U postgres"
  interval: 10s
  timeout: 5s
  retries: 3
  start_period: 5s
FieldDefaultDescription
test(required)Command to run. Exit code 0 = healthy.
interval10sTime between checks.
timeout5sMaximum time for a single check.
retries3Consecutive failures before marking unhealthy.
start_period5sGrace period after startup before checks count.

The test field accepts a string (run as shell command) or a list:

# String — runs in a shell
test: "curl -f http://localhost:8080/health || exit 1"

# List with CMD-SHELL prefix
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]

Health checks matter for dependencies. When service B has depends_on: [A], B waits for A to be healthy — not just started.

restart

What to do when a service exits.

PolicyBehavior
noDon't restart.
alwaysRestart regardless of exit code.
on-failureRestart only if the exit code is non-zero.
unless-stoppedRestart unless explicitly stopped. (default)
restart: on-failure

depends_on

Declare that this service needs other services to be running (and healthy) before it starts.

depends_on:
  - database
  - redis

8Vast resolves the full dependency graph and starts services in the correct order. If api depends on database, and web depends on api, then the start order is: database, api, web.

Circular dependencies are rejected. If A depends on B and B depends on A, 8v stack validate catches it.

Networks

Define networks for service isolation and communication:

networks:
  frontend:
    driver: bridge
    policy: deny
  backend:
    driver: bridge
    subnet: 10.0.1.0/24
FieldDefaultDescription
driverbridgeNetwork driver.
policydenyDefault traffic policy: allow or deny.
subnet(auto)CIDR subnet. Auto-assigned if not specified.

Services on the same network can communicate using service names as hostnames. Services on different networks are isolated from each other.

Validation rules

8Vast validates your stack definition before starting anything. It checks for:

  • Missing image or build — every service needs one or the other.
  • Port conflicts — two services can't use the same host port.
  • Resource minimums — at least 1 CPU and 128 MB memory per service.
  • Invalid restart policy — must be one of the four valid values.
  • Undefined references — networks and dependencies must point to things that exist.
  • Circular dependencies — A depends on B depends on A is rejected.

Run 8v stack validate to check without starting anything.

Defaults summary

FieldDefault value
cpus1
memory512 MB
replicas1
restartunless-stopped
healthcheck.interval10s
healthcheck.timeout5s
healthcheck.retries3
healthcheck.start_period5s
networks[].driverbridge
networks[].policydeny