Configuration

Client config, daemon config, and the contract every app repo must satisfy.

Client config

The CLI reads ~/.stackcube/client.yml on every invocation. stackcube init writes it; you can also edit it by hand.

server: paas.example.com:9090
identity: ~/.ssh/id_ed25519
tls: true

Fields

server (string) — daemon address as host:port. Default written by stackcube init: localhost:9090.
identity (string) — path to the SSH private key used to authenticate. Default: ~/.ssh/id_ed25519.
tls (bool) — whether to dial with TLS. Required when the daemon sits behind a reverse proxy like Caddy; false for plain-text local connections. Default: false.

If the file is missing, the CLI prints client not configured — run 'stackcube init' first and exits.

Daemon config

The daemon reads <data-dir>/config.yml on startup, where <data-dir> defaults to ~/.stackcubed. If the file is absent, the daemon uses defaults — most installations only need to override fields if the host already uses port 9090 or a non-default Docker setup.

# ~/.stackcubed/config.yml
port: 9090
repos_dir: ~/.stackcubed/repos
deploy_dir: ~/.stackcubed/deploy
network: stackcube-net
port_range_start: 8080
compose_command: ""
docker_socket: ""
daemon_domain: paas.example.com

Fields

port (int) — gRPC server port the daemon listens on. Default: 9090.
repos_dir (string) — directory holding bare git repos for each app. Default: <data-dir>/repos.
deploy_dir (string) — working directory the daemon checks out commits into and runs docker compose from. Default: <data-dir>/deploy.
network (string) — Docker network apps are attached to so the front proxy can route to them by container name. Default: stackcube-net.
port_range_start (int) — starting host port for app auto-allocation. The daemon hands out ports from here upward. Default: 8080.
compose_command (string) — override for the docker compose binary. Empty means autodetect (docker compose or docker-compose). Default: empty.
docker_socket (string) — override for the Docker socket path. Empty means use the default for the platform. Default: empty.
daemon_domain (string) — the domain the bundled stackcube-proxy Caddy container listens on and reverse-proxies to the daemon's gRPC port. Set by stackcubed init --domain. Default: empty.

Unset fields fall back to the defaults above — you can keep the file minimal and only list the values you need to change.

App repo contract

Every app repo deployed to StackPaaS must satisfy these rules. stackcube lint checks them; stackcube deploy runs lint first and refuses to deploy on errors.

Required files

Compose service shape

Every service must set container_name (the daemon routes traffic by container name) and publish its port via the daemon-injected ${HOST_PORT}:

services:
  web:
    container_name: my-api
    build: .
    env_file: .env
    ports:
      - "${HOST_PORT}:${APP_PORT}"
    restart: unless-stopped
# .env
APP_PORT=3000

At deploy time, the daemon injects HOST_PORT with the host port allocated for the app, so the published port mapping resolves to <allocated-port>:3000.

Note: The fastest way to a contract-compliant repo is stackcube scaffold, which generates both files using the conventions above.

Networking

Containers are attached to stackcube-net (or whatever network is set to in the daemon config). Apps that need to talk to each other can resolve each other by container name on this network. The daemon handles attachment automatically — you don't declare the network in the app's compose file.