Complete infrastructure platform CLI: - Container runtime (systemd-nspawn) - VoltVisor VMs (Neutron Stardust / QEMU) - Stellarium CAS (content-addressed storage) - ORAS Registry - GitOps integration - Landlock LSM security - Compose orchestration - Mesh networking Copyright (c) Armored Gates LLC. All rights reserved. Licensed under AGPSL v5.0
15 KiB
15 KiB
Voltfile / Constellation Format
A Constellation is the definition of how containers, VMs, services, and resources form a coherent system. volt compose manages Constellations as declarative multi-service stacks — define containers, VMs, services, tasks, networks, and volumes in a single YAML file and deploy them together.
File Discovery
volt compose looks for Constellation definitions in this order:
-f <path>flag (explicit)volt-compose.yamlin current directoryvolt-compose.ymlin current directoryVoltfilein current directory (YAML format)
Quick Example
version: "1"
name: web-stack
containers:
web:
image: armoredgate/nginx:1.25
ports:
- "80:80"
networks:
- frontend
depends_on:
api:
condition: service_started
api:
image: armoredgate/node:20
ports:
- "8080:8080"
environment:
DATABASE_URL: "postgresql://app:secret@db:5432/myapp"
networks:
- frontend
- backend
vms:
db:
image: armoredgate/ubuntu-24.04
cpu: 2
memory: 4G
networks:
- backend
networks:
frontend:
subnet: 10.20.0.0/24
backend:
subnet: 10.30.0.0/24
internal: true
Deploy:
volt compose up -d # Create and start in background
volt compose ps # Check status
volt compose logs -f # Follow all logs
volt compose down # Tear down
Top-Level Keys
| Key | Type | Required | Description |
|---|---|---|---|
version |
string | Yes | File format version. Currently "1". |
name |
string | No | Stack name. Used as prefix for workload names. |
description |
string | No | Human-readable description. |
containers |
map | No | Container definitions (Voltainer). |
vms |
map | No | VM definitions (Voltvisor). |
services |
map | No | systemd service definitions. |
tasks |
map | No | Scheduled task definitions. |
networks |
map | No | Network definitions. |
volumes |
map | No | Volume definitions. |
configs |
map | No | Configuration file references. |
secrets |
map | No | Secret file references. |
Container Definition
containers:
<name>:
image: <string> # Image name (required)
build: # Build configuration (optional)
context: <path> # Build context directory
file: <path> # Build spec file
ports: # Port mappings
- "host:container"
volumes: # Volume mounts
- host_path:container_path[:ro]
- volume_name:container_path
networks: # Networks to join
- network_name
environment: # Environment variables
KEY: value
env_file: # Load env vars from files
- .env
depends_on: # Dependencies
other_service:
condition: service_started|service_healthy|service_completed_successfully
restart: no|always|on-failure|unless-stopped
restart_max_retries: <int> # Max restart attempts (for on-failure)
resources:
cpu: "<number>" # CPU shares/quota
memory: <size> # e.g., 256M, 1G
memory_swap: <size> # Swap limit
healthcheck:
command: ["cmd", "args"] # Health check command
interval: <duration> # Check interval (e.g., 30s)
timeout: <duration> # Check timeout
retries: <int> # Retries before unhealthy
start_period: <duration> # Grace period on start
labels:
key: value
Container Example
containers:
app-server:
image: armoredgate/node:20
build:
context: ./app
file: build-spec.yaml
ports:
- "8080:8080"
volumes:
- app-data:/app/data
- ./config:/app/config:ro
networks:
- backend
environment:
NODE_ENV: production
DATABASE_URL: "postgresql://app:${DB_PASSWORD}@db:5432/myapp"
env_file:
- .env
- .env.production
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
restart: on-failure
restart_max_retries: 5
resources:
cpu: "2"
memory: 1G
memory_swap: 2G
healthcheck:
command: ["curl", "-sf", "http://localhost:8080/health"]
interval: 15s
timeout: 3s
retries: 5
VM Definition
vms:
<name>:
image: <string> # Base image (required)
cpu: <int> # vCPU count
memory: <size> # Memory allocation (e.g., 4G)
disks: # Additional disks
- name: <string>
size: <size>
mount: <path> # Mount point inside VM
networks:
- network_name
ports:
- "host:vm"
provision: # First-boot scripts
- name: <string>
shell: |
commands to run
healthcheck:
command: ["cmd", "args"]
interval: <duration>
timeout: <duration>
retries: <int>
restart: no|always|on-failure
tune: # Performance tuning
cpu_pin: [<int>, ...] # Pin to physical CPUs
hugepages: <bool> # Use hugepages
io_scheduler: <string> # I/O scheduler
VM Example
vms:
db-primary:
image: armoredgate/ubuntu-24.04
cpu: 4
memory: 8G
disks:
- name: system
size: 40G
- name: pgdata
size: 200G
mount: /var/lib/postgresql/data
networks:
- backend
ports:
- "5432:5432"
provision:
- name: install-postgres
shell: |
apt-get update && apt-get install -y postgresql-16
systemctl enable postgresql
healthcheck:
command: ["pg_isready", "-U", "postgres"]
interval: 30s
timeout: 5s
retries: 3
restart: always
tune:
cpu_pin: [4, 5, 6, 7]
hugepages: true
io_scheduler: none
Service Definition
Define systemd services managed by the Constellation:
services:
<name>:
unit:
type: simple|oneshot|forking|notify
exec: <string> # Command to run (required)
user: <string>
group: <string>
restart: no|always|on-failure
networks:
- network_name
healthcheck:
command: ["cmd", "args"]
interval: <duration>
resources:
memory: <size>
depends_on:
other_service:
condition: service_started
Service Example
services:
cache-redis:
unit:
type: simple
exec: "/usr/bin/redis-server /etc/redis/redis.conf"
user: redis
group: redis
restart: always
networks:
- backend
healthcheck:
command: ["redis-cli", "ping"]
interval: 10s
resources:
memory: 512M
Task Definition
Define scheduled tasks (systemd timers):
tasks:
<name>:
exec: <string> # Command to run (required)
schedule:
on_calendar: <string> # systemd calendar syntax
every: <duration> # Alternative: interval
environment:
KEY: value
user: <string>
persistent: <bool> # Run missed tasks on boot
Task Example
tasks:
db-backup:
exec: "/usr/local/bin/backup.sh --target db-primary"
schedule:
on_calendar: "*-*-* 02:00:00"
environment:
BACKUP_DEST: /mnt/backups
cleanup:
exec: "/usr/local/bin/cleanup-old-logs.sh"
schedule:
every: 6h
Network Definition
networks:
<name>:
driver: bridge # Network driver (default: bridge)
subnet: <cidr> # e.g., 10.20.0.0/24
internal: <bool> # If true, no external access
options:
mtu: <int> # MTU (default: 1500)
Network Examples
networks:
# Public-facing network
frontend:
driver: bridge
subnet: 10.20.0.0/24
options:
mtu: 9000
# Internal only — no external access
backend:
driver: bridge
subnet: 10.30.0.0/24
internal: true
Volume Definition
volumes:
<name>:
driver: local # Storage driver
size: <size> # Optional size for file-backed volumes
Volume Examples
volumes:
web-static:
driver: local
app-data:
driver: local
size: 10G
pgdata:
driver: local
size: 200G
Configs and Secrets
configs:
<name>:
file: <path> # Path to config file
secrets:
<name>:
file: <path> # Path to secret file
Example
configs:
nginx-conf:
file: ./config/nginx.conf
app-env:
file: ./.env.production
secrets:
db-password:
file: ./secrets/db-password.txt
tls-cert:
file: ./secrets/server.crt
tls-key:
file: ./secrets/server.key
Dependency Conditions
When specifying depends_on, the condition field controls when the dependent service starts:
| Condition | Description |
|---|---|
service_started |
Dependency has started (default) |
service_healthy |
Dependency passes its health check |
service_completed_successfully |
Dependency ran and exited with code 0 |
depends_on:
db:
condition: service_healthy
migrations:
condition: service_completed_successfully
cache:
condition: service_started
Environment Variable Interpolation
The Constellation definition supports shell-style variable interpolation:
environment:
DATABASE_URL: "postgresql://app:${DB_PASSWORD}@db:5432/myapp"
APP_VERSION: "${APP_VERSION:-latest}"
Variables are resolved from:
- Host environment variables
.envfile in the same directory as the Constellation definition- Files specified in
env_file
Unset variables with no default cause an error.
Compose Commands
Lifecycle
# Deploy the Constellation — create and start everything
volt compose up
# Detached mode (background)
volt compose up -d
# Specific Constellation file
volt compose -f production.yaml up -d
# Build images first
volt compose up --build
# Force recreate
volt compose up --force-recreate
# Tear down the Constellation
volt compose down
# Also remove volumes
volt compose down --volumes
Status and Logs
# Stack status
volt compose ps
# All logs
volt compose logs
# Follow logs
volt compose logs --follow
# Logs for one service
volt compose logs api
# Last 50 lines
volt compose logs --tail 50 api
# Resource usage
volt compose top
# Events
volt compose events
Operations
# Start existing (without recreating)
volt compose start
# Stop (without removing)
volt compose stop
# Restart
volt compose restart
# Execute command in a service
volt compose exec api -- node --version
# Pull images
volt compose pull
# Build images
volt compose build
# Validate Constellation
volt compose config
Project Naming
# Override project name
volt compose --project my-project up
# This prefixes all workload names: my-project-web, my-project-api, etc.
Full Example: Production Constellation
# volt-compose.yaml — Production Constellation
version: "1"
name: production
description: "Production web application"
containers:
web-proxy:
image: armoredgate/nginx:1.25
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- web-static:/usr/share/nginx/html:ro
networks:
- frontend
- backend
depends_on:
app-server:
condition: service_healthy
restart: always
resources:
cpu: "0.5"
memory: 256M
healthcheck:
command: ["curl", "-sf", "http://localhost/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
app-server:
image: armoredgate/node:20
build:
context: ./app
file: build-spec.yaml
environment:
NODE_ENV: production
DATABASE_URL: "postgresql://app:${DB_PASSWORD}@db-primary:5432/myapp"
REDIS_URL: "redis://cache-redis:6379"
env_file:
- .env.production
ports:
- "8080:8080"
volumes:
- app-data:/app/data
networks:
- backend
depends_on:
db-primary:
condition: service_healthy
cache-redis:
condition: service_started
restart: on-failure
restart_max_retries: 5
resources:
cpu: "2"
memory: 1G
healthcheck:
command: ["curl", "-sf", "http://localhost:8080/health"]
interval: 15s
timeout: 3s
retries: 5
vms:
db-primary:
image: armoredgate/ubuntu-24.04
cpu: 4
memory: 8G
disks:
- name: system
size: 40G
- name: pgdata
size: 200G
mount: /var/lib/postgresql/data
networks:
- backend
ports:
- "5432:5432"
provision:
- name: install-postgres
shell: |
apt-get update && apt-get install -y postgresql-16
systemctl enable postgresql
healthcheck:
command: ["pg_isready", "-U", "postgres"]
interval: 30s
timeout: 5s
retries: 3
restart: always
tune:
cpu_pin: [4, 5, 6, 7]
hugepages: true
io_scheduler: none
services:
cache-redis:
unit:
type: simple
exec: "/usr/bin/redis-server /etc/redis/redis.conf"
user: redis
group: redis
restart: always
networks:
- backend
healthcheck:
command: ["redis-cli", "ping"]
interval: 10s
resources:
memory: 512M
log-shipper:
unit:
type: simple
exec: "/usr/local/bin/vector --config /etc/vector/vector.toml"
restart: on-failure
depends_on:
app-server:
condition: service_started
tasks:
db-backup:
exec: "/usr/local/bin/backup.sh --target db-primary"
schedule:
on_calendar: "*-*-* 02:00:00"
environment:
BACKUP_DEST: /mnt/backups
cleanup:
exec: "/usr/local/bin/cleanup-old-logs.sh"
schedule:
every: 6h
networks:
frontend:
driver: bridge
subnet: 10.20.0.0/24
options:
mtu: 9000
backend:
driver: bridge
subnet: 10.30.0.0/24
internal: true
volumes:
web-static:
driver: local
app-data:
driver: local
size: 10G
configs:
nginx-conf:
file: ./config/nginx.conf
secrets:
db-password:
file: ./secrets/db-password.txt
tls-cert:
file: ./secrets/server.crt
tls-key:
file: ./secrets/server.key
Full Example: Developer Constellation
# volt-compose.yaml — Developer Constellation
version: "1"
name: dev-environment
vms:
dev-box:
image: armoredgate/fedora-workstation
cpu: 4
memory: 8G
disks:
- name: system
size: 80G
volumes:
- ~/projects:/home/dev/projects
networks:
- devnet
ports:
- "2222:22"
- "3000:3000"
- "5173:5173"
provision:
- name: dev-tools
shell: |
dnf install -y git nodejs rust golang
npm install -g pnpm
containers:
test-db:
image: armoredgate/postgres:16
environment:
POSTGRES_PASSWORD: devpass
POSTGRES_DB: myapp_dev
volumes:
- test-pgdata:/var/lib/postgresql/data
networks:
- devnet
ports:
- "5432:5432"
mailhog:
image: armoredgate/mailhog:latest
networks:
- devnet
ports:
- "1025:1025"
- "8025:8025"
networks:
devnet:
subnet: 10.99.0.0/24
volumes:
test-pgdata:
driver: local