OctoCompose - concept
It will be a micro service operator for go-orb and will work without go-orb as well.

Main Goal is to have a tool that makes it very simple to deploy an Application
that comes with a subset of Services
on a environment supported by one of the operators
.
Operator
can be one of baremetal
, docker
and kubernetes
. It's planed to have operator replaceable, that means there can be more of them.
Initial goal will be the baremetal
operator.
What can I expect as a user
- easy to get started: Include configuration files from a Vendor/Project, customize/overwrite these settings in your own
config.yaml
and have a ready to use Application. - smart stepped upgrades: Single command to update the application, with
smart stepping
which means it will upgrade always to the latest minor version and then to the major. - Preflight checks: Validate you'r configuration before running it, have meaningfull error messages when something isn't right with the config.
- secure secrets: Optionaly this will integrate with systems like
HashiCorp Vault
which means there are no plaintext secrets around.
For a Vendor/Project
- Ship versioned configurations that works from your Servers/Github repo.
- Let the user decide which components of your Application and which plugins he wanna use, by defining individual configurations per component.
- powerfull configuration system:
includes
,globals
,templating
andmerging
are just some of the features of the config system.
Name finding
I found it very hard to find a good name for this tool, while writing this concept doc I changed the name multiple times.
There are either no free Domain Names, no Github or other clashes.
OctoCompose
is a combination/mixture of Octopus
and docker-compose
. I'm still not sure this is the right name. Previous names have been octctl
and orberator
.
Technical Overview
Will be a operator/orchestration tool.
It can be used with go-orb but it's not limited to that.
You might see it as alternative to docker compose, but it will run baremetal and in kubernetes as well.
It should be able to download binaries from various sources or maybe
build them from source using git.
Modular Architecture
With OctoCompose I want to follow the Unix Philosophy: "Do one thing and do it well.".
This is why it comes with a plugin based system. The Idea of running tools
as commands and parsing theier output comes from the nagios
project.
Configuration
OctoCompose will share its config with the app and the services, this means there will be a single config for the whole stack.
The services will get merged Config with just theier content over a CONFIG
variable which contains a URL to an https
endpoint to the operator. The service then might run a templating engine on it.
Example core
config
I put a lot of features into these config files, there might be just a subset of these in the real tool.
Here is an example config which you might host at:
https://raw.githubusercontent.com/yourproject/octocompose-chart/refs/tags/v2.0.0/config/core.yaml
# Globals are applied to each service, individual services can overwrite them.
globals:
client:
preferredTransports:
- orbdrpc # orb uses it's own wire Format for results on top of DRPC to deliver responses for metadata.
- grpc
server:
drpc:
# Templating happens at the service level.
listen: unix://{{env.XDG_RUNTIME_DIR}}/{{project.Name}}/{{project.ID}}/{{service.App.Name}}-drpc.sock
grpc:
listen: unix://{{env.XDG_RUNTIME_DIR}}/{{project.Name}}/{{project.ID}}/{{service.App.Name}}-grpc.sock
kvstore:
# kvstore/natsjs is fully compatible with these settings
# to go-micro/store/natsjs which is used in opencloud.
plugin: natsjs
servers:
- nats://localhost:9233
bucketPerTable: false
jsonKeyValues: true
compress: false
registry:
# registry/micro-kvstore is a opencloud/nats-js-kv compatible registry.
plugin: micro-kvstore
defaultTransport: grpc
kvstore:
plugin: natsjs
bucketPerTable: false
jsonKeyValues: true
compress: false
servers:
- nats://localhost:9233
octoctl:
operator: baremetal # One of `baremetal`, `docker`, `kubernetes` or you provide your own.
project: yourproject # Path for the cache
version: v2.0.0 # Version for the cache path
# Prompts will be asked before the operator starts or before preflight checks.
# Having prompts will disable all autostart features.
prompts:
- name: "Enter the password for vault"
type: password
var: VAULT_PASSWORD
secrets:
# Secrets will be fetched per service from the given provider and supplied into the merged config
# to the service, here we have HashiCorp Vault as provider.
tool: vault-client
depends:
- service: vault
external: false
operator:
repos:
core:
url: https://raw.githubusercontent.com/yourproject/octocompose-chart/refs/tags/v2.0.0/repos/core.yaml
services:
nats:
config:
# This will disable the global config for this service.
noGlobals: true
priority: 100
healthCheck:
- tool: check-tcp # will check for an open port, it will only run in `baremetal` envs.
port: {{service.nats.port}} # This is the 9233 defined below or 4222 in the users config.
interval: 10s
successTreshold: 1
failureTreshold: 3
preflightCheck:
- tool: check-tcp-port # will check if a connection to that port is possible.
port: {{service.nats.port}}
- tool: operator-run # tool `operator-run` will run the service trough the operator with the given arguments.
args: ["preflight"]
hooks:
preStart:
- tool: operator-run
args: ["migrate"]
idp:
priority: 200
auth-service:
priority: 300
depends:
- service: idp
- service: nats
webdav:
priority: 1000
healthCheck:
- tool: check-grpc
url: {{service.webdav.server.grpc.listen}}
endpoint: /health.v1alpha.Health/Healthz
interval: 10s
successTreshold: 1
failureTreshold: 3
preflightCheck:
- tool: check-server-url # will check if the given url is valid (TCP Port or Unix socket)
url: {{service.webdav.server.grpc.listen}}
- tool: operator-run # tool `operator-run` will run the service trough the operator with the given arguments.
args: ["preflight"]
depends:
- service: auth-service
# Service configurations:
service:
nats:
port: 9233
And here is an extensions for collabora
octoctl:
repos:
collabora:
url: https://raw.githubusercontent.com/yourproject/octocompose-chart/refs/tags/v2.0.0/repos/collabora.yaml
services:
collabora:
priority: 1500
The users config.yaml
Here is an example cli provided config.yaml
:
project:
name: yourproject
# This will be generated by the octoctl if none is provided, it will be a shortUUID.
id: 1234567890
include:
# ?template=true means that the config will be templated by text/template with a yet to be defined set of variables.
- url: https://raw.githubusercontent.com/yourproject/octocompose-chart/refs/tags/v2.0.0/config/core.yaml?template=true
versions: github
- url: https://raw.githubusercontent.com/yourproject/octocompose-chart/refs/tags/v2.0.0/config/collabora.yaml?template=true
versions: github
# Globals are applied to each service.
globals:
server:
drpc:
listen: tcp://0.0.0.0:8081
grpc:
listen: tcp://0.0.0.0:8080
kvstore:
servers:
- nats://nats:4222
registry:
plugin: kubedns
namespace: yourproject
cluster_domain: cluster.local
# This defines helper variables for the operator.
operator:
ports:
drpc: 8081
grpc: 8080
# The configuration to setup the operator, this wont get uploaded.
octoctl:
# The kubernetes operator will run itself inside kubernetes and communicate via RPC with that "operator".
# It will upload the merged config to a kubernetes secret, the operator then executes it.
plugin: kubernetes
namespace: yourproject
# Prefix for each resource item.
prefix: instance1
api: https://rancher.example.com/k8s/clusters/local
token: <token>
operator:
repos:
mycustom:
url: https://raw.githubusercontent.com/jochumdev/yourproject-plugins/refs/heads/main/repo.yaml
services:
nats:
replicas: 3
webdav:
replicas: 2
my-supi:
priority: 2000
depends:
- service: auth-service
badservice:
# Its possible disable services
enabled: false
notifications:
- notifier: smtp
server: mail.example.com
from: yourproject@example.com
user: yourproject@example.com
password: Abc123456
to: yourproject-users@example.com
# Service configurations:
service:
nats:
port: 4222
cluster: true
my-supi:
supibot:
name: Alex
number: 42
Example repo.yaml
This defines where to get binaries/sources/docker containers and howto run them.
# We allow includes in repos.
include:
# This example might have some tools which yourproject v2.0.0 needs.
# Full URL will be generated from the parent path: https://raw.githubusercontent.com/yourproject/orberator-chart/refs/tags/v2.0.0/repo/
# This allows to use the same repo for Development and Production (file:// vs. https://)
- url: ./tools/yourproject.yaml?template=true
# This example will add the service abc.
- url: ./services/abc.yaml?template=true
service:
# Each service has it's own entry nats is just a template for many of them.
nats:
binary:
- os: linux
arch: amd64
url: https://github.com/yourproject/yourproject/releases/download/v2.0.0/yourproject-nats-2.0.0-linux-amd64
sha256URL: https://github.com/yourproject/yourproject/releases/download/v2.0.0/yourproject-nats-2.0.0-linux-amd64.sha256
archiveBinaryPath: yourproject-nats
args: ["server"]
- os: linux
arch: arm64
url: https://github.com/yourproject/yourproject/releases/download/v2.0.0/yourproject-nats-2.0.0-linux-arm64
sha256URL: https://github.com/yourproject/yourproject/releases/download/v2.0.0/yourproject-nats-2.0.0-linux-arm64.sha256
archiveBinaryPath: yourproject-nats
args: ["server"]
oci:
- arch: amd64
registry: docker.io
image: yourprojecters/yourproject-nats
tag: v2.0.0
source:
url: https://github.com/yourproject/yourproject.git
branch: v2.0.0
buildCmds:
- OS={{GOOS}} ARCH={{GOARCH}} make yourproject-nats
binaryPath: dist/nats/yourproject-nats-{{GOOS}}-{{GOARCH}}
The operator aka engine
All operators will run a RPC Server which the cli and other tools can access.
The operators will provide a HTTP URL with basic auth for the service config and as well as a CONFIG
env variable.
There will be 3 different operators, but it will beasy to create your own.
Authors
Community
Join our active community:
- Matrix: https://matrix.to/#go-orb:jochum.dev - Real-time chat and support
- Discord: https://discord.gg/4n6E4NYjnR - Alternative communication channel