/ 01Stack

Hierarchical Structure

A stack is an application organized as paths instead of loose service names. Use map to place a GitHub project at a domain, mount to attach frontend dependencies such as an API endpoint, import to bring services into the root, and link to connect those services to the blocks that need them.

stack map · stack mount · stack import · stack link
# Map a GitHub project to a public domain
$ stack map github.com/acme/frontend example.com
Mapped github.com/acme/frontend at example.com

# Mount the frontend API dependency under the domain
$ stack mount myorg/api:1.4 example.com/api
Mounted /api

# Import shared services under the stack root
$ stack import mysql:8 example.com/mysql
Imported /mysql
$ stack import redis:7 example.com/redis
Imported /redis

# Link services into the API address space
$ stack link example.com/mysql example.com/api/mysql
Linked /api/mysql to /mysql
$ stack link example.com/redis example.com/api/redis
Linked /api/redis to /redis

# Inspect the live tree
$ stack ls -r example.com
TYPE       PATH                    IMAGE              VECTORS  PORTS
stack      example.com             github/acme/front  —        443/tcp
component  example.com/api         myorg/api:1.4      —        8080/tcp
service    example.com/mysql       mysql:8            —        3306/tcp
service    example.com/redis       redis:7            —        6379/tcp
link       example.com/api/mysql   example.com/mysql  —        —
link       example.com/api/redis   example.com/redis  —        —
/ 02Snap

Federated Deployment

Federated deployment does not require a new control system for every environment. SSH into a cloud node, run the same snap command, and the complete stack materializes from the shared model on that node.

ssh · stack snap
# Open the AWS node console
$ ssh ops@aws-use1.internal
Connected to aws-use1.internal

# Snap the complete stack onto AWS
aws$ stack snap -r example.com
Snapped example.com on aws-use1.internal
/ 03Scale

Vector Scaling

Vector scaling is the same operation from another node. SSH into a second cloud, run the same recursive snap, and Microstacks adds another runtime vector without changing the authored stack.

ssh · stack snap
# Open the Azure node console
$ ssh ops@azure-eastus.internal
Connected to azure-eastus.internal

# Run the same command to add a second vector
azure$ stack snap -r example.com
Snapped example.com on azure-eastus.internal
/ 04Code

Infrastructure as Code

The same model is available from code. You can define blocks, mount paths, import services, and snap vectors programmatically, then version and test those changes like the rest of your application.

stack/main.go
package main

import (
    "github.com/microstacks/stack"
    "github.com/microstacks/stack/block"
    "github.com/microstacks/stack/vector"
)

func main() {
    hub, _ := stack.Hub("https://example.com")
    gw,  _ := hub.Gateway("example.com")
    root, _ := gw.Root()

    // Define a block — same fields as `stack import`.
    api := block.New("myorg/api:1.4",
        block.Kind(block.SERVICE),
        block.Env("DB_URL", "postgres://db/app"),
        block.Endpoint(8080, "tcp"),
    )

    // Mount at /api (like `stack mount`).
    root.Mount(api, "/api")

    // Place vectors close to users in two regions.
    api.Snap(vector.Node{Address: "ssh://ops@edge-fra1"})
    api.Snap(vector.Node{Address: "ssh://ops@edge-sin1"})
}