Spec Outline

Every cycle.json stack file will follow the same rules.

The following sections will be the base of your stack file.

Spec Framework
  • version
    string

    This is the version of the Cycle Stack Spec (currently 1.0)

  • about
    object | null

    Extra information about this stack. Not used by the platform.

    Show child fields
  • tests
    array of objects

    Test containers run after deployment but before initial start. These have to pass before an environment based on this stack will be set to live.

    Describe the test containers in the same way you would describe a normal container object.

  • services
    object

    Describes service container policies for this stack. The values are listed here.

  • containers
    object | null

    An object where the key is a container identifier and the value is a container object.
    A container identifier is always lowercase and cannot have spaces. The only non-alphanumeric character allowed is hyphen (-). The container identifier is used as a reference in other parts of the stack and the platform.

  • annotations
    object
    A key value store of custom data for your stack. Not used by the platform internally.
cycle.json
{
"version": "1.0",
"about": {
"version": "2019.3.18.1-name",
"description": "an example"
},
"tests": [],
"services": {
"loadbalancer": null,
"vpn": null
},
"containers": {
"database"
: {}
},
"annotations": {
"data"
: "value"
}
}

Services

The services section describes settings for Cycle service containers, such as the load balancer and VPN.

Load Balancer

If this section is set to null, a default load balancer configuration will be applied.

Services.LoadBalancer
  • deploy
    string
    The deployment strategy for this environment's load balancer(s).
    • single: Deploys a single load balancer instance to the first available node in the target environment's cluster.
    • per-provider: Deploys a load balancer instance to the first available node for every provider in the target environment's cluster.
    • per-location: Deploys a load balancer instance to one node per location in the target environment's cluster.
  • haproxy
    object | null
    Describes settings that are passed to HAProxy within the load balancer.
    Show child fields
  • ipv4
    bool | null
    Allow / disallow traffic to be routed via IPv4.
  • ipv6
    bool | null
    Allow / disallow traffic to be routed via IPv6.

VPN

Configuration options for the VPN service container deployed within the target environment.

services.Vpn
  • auth
    object
    Authorization details for the VPN service.
    Show child fields
  • allow_internet
    bool
    If true, enables routes to let VPN traffic hit the public internet.

Basic Services Configuration

services
{
"loadbalancer": {
"deploy": "single",
"haproxy": {
"default": {
"frontend": {
"mode": "http",
"max_connections": 1000,
"timeouts": {
"client_secs": 15,
"client_fin_ms": 100,
"http_keep_alive_ms": 100,
"http_request_ms": 100
}
},
"backend": {
"balance": "roundrobin",
"timeouts": {
"server_secs": 15,
"server_fin_ms": 100,
"connect_ms": 100,
"queue_ms": 100,
"tunnel_secs": 25
}
}
},
"ports": {
"3000"
: {
"frontend": {
"mode": "http",
"max_connections": 1000,
"timeouts": {
"client_secs": 15,
"client_fin_ms": 100,
"http_keep_alive_ms": 100,
"http_request_ms": 100
}
},
"backend": {
"balance": "first",
"timeouts": {
"server_secs": 15,
"server_fin_ms": 100,
"connect_ms": 100,
"queue_ms": 100,
"tunnel_secs": 25
}
}
}
}
},
"ipv4": true,
"ipv6": true
},
"vpn": {
"auth": {
"web_hook": "/url/to/endpoint",
"cycle_accounts": true,
"vpn_accounts": false
},
"allow_internet": true
}
}

Containers

The containers section is the meat of the stack file, and describes what containers should be deployed, and how. The object keys of this section are custom identifiers for the container. They may be used in other parts of the stack, or in upcoming CI/CD features.

containers.[identifier]
  • name
    string
    A name for this container.
  • image
    object
    Section describing the image to use for this container. Jump to image section.
  • stateful
    bool
    If true, Cycle will disable auto-scaling for this container. This also enables custom stateful configurations for this container's instances.
  • config
    object
    Section describing detailed container configurations. Jump to config section.
  • role
    optional
    If set, describes the custom role for this container. Currently can only be orchestrator.
    • orchestrator - This container will be granted additional permissions in Cycle's internal API. This will also allow other containers to specify it as the orchestrator (by ID) under their scaling configuration section. Cycle will then defer to this container for how to scale.
  • volumes
    array of objects
    An array of volume configurations for each volume listed in the container's image. Jump to volumes section.

Image

The image section of a container describes the source of the container, either from an existing container image, or built from source. You can only choose one source.
containers.[identifier].image
  • name
    string
    The name of the image.
  • source
    object
    The source describes where the container image comes from. Only choose one of these source options.
    Show child fields

Config

The config section describes all the various settings and options for this container.

containers.[identifier].config.network
  • public
    string
    Can be one of either enable, disable, egress-only. Set to enable to fully enable public internet. set to disable to fully disable any public internet communications. set to egress-only to allow outbound public traffic, but block inbound
  • hostname
    string
    A hostname that can be used to identify this container on the private network.
  • ports
    array of strings
    An array of port mappings in the form of external:container
containers.[identifier].config.deploy
  • instances
    integer
    The number of initial desired instances when this container starts.
  • strategy
    string | null
    The deployment strategy Cycle will use to balance instances. If null, will default to Cycle's base deployment strategy, which is resource density. Can be one of:
    • resource-density - Cycle will try to balance based on resource usage of the servers that match the tags.
    • high-availability - Cycle will try to spread instances out to different geographic locations.
    • first-available - Cycle will deploy instances to the first available boxes.
  • stateful
    object | null
    Settings for containers that have been marked as stateful.
    Show child fields
  • constraints
    object | null
    Settings that narrow what infrastructure an instance can be deployed to and the order it should start in.
    Show child fields
  • shutdown
    object | null
    Settings regarding instance shutdowns.
    Show child fields
  • startup
    object | null

    Settings related to instance startups.

    Show child fields
  • restart
    object | null
    Settings related to instances that stop unexpectedly.
    Show child fields
  • health_check
    object | null
    Settings related to how Cycle determines a container's "health".
    Show child fields
  • update
    object | null
    Settings related to how this container updates it's image.
    Show child fields
containers.[identifier].config.scaling
  • auto
    object | null
    Settings related to Cycle's auto scaling features.
    Show child fields
  • orchestrator
    string
    A container identifier in this spec pointing to a container with a role of orchestrator. Cycle will defer to that container to handle all scaling.
containers.[identifier].config.runtime
  • command
    object | null
    Settings to override the default image command that runs when the container starts.
    Show child fields
  • namespaces
    array of strings | null
    Namespaces this container has access to. Can be any of
    • ipc
    • pid
    • uts
    • network
    • mount
    • user
    See here for more information on namespaces.
  • environment_vars
    object
    An object holding a key-value pair of environment variables.
  • privileged
    bool
    Set to true to enable privileged capabilities. DANGEROUS AND NOT RECOMMENDED.
  • capabilities
    array of strings | null
    A list of linux kernel capabilities to apply to this container.
    Click here for more info on capabilities
  • workdir
    string | null
    Set the working directory the command executes in.
containers.[identifier].config.resources
  • cpu
    object
    How CPU resources should be limited/reserved for this container. This number is based on shares. A full share is 10 and equates to a single virtualized core (thread).
    Show child fields
  • ram
    object
    How RAM resources should be limited/reserved for this container.
    Show child fields
containers.[identifier].config.integrations
  • events
    object
    optional
    Fields that allow hooking into Cycle from an external source.
    Show child fields
  • lets_encrypt
    object
    optional
    Allow lets encrypt to create and manage this containers TLS certs.
    Show child fields
  • files
    array of objects
    optional
    Describes a list of files you would like to copy into the container.
    Show child fields

Volumes

A container "resets" each time it is restarted. Volumes offer a way to keep data persistent between restarts. They are mapped onto a path within the container itself, and any data that is there will survive the container. These settings configure volumes that are described in the container image.

Volumes
  • volume
    array of objects
    An array of volume setting objects.
    Show child fields

Sample Container Configuration

containers
{
"wordpress": {
"name": "wordpress",
"image": {
"name": "wordpress",
"source": {
"docker_file": {
"dir": "/wordpress",
"build_file": "/wordpress/Dockerfile"
}
}
},
"stateful": true,
"config": {
"network": {
"public": "enable",
"hostname": "wordpress_host",
"ports": [
"80:80",
"81:80",
"43564:65233"
]
},
"deploy": {
"instances": 3,
"strategy": "high-availability",
"stateful": {
"instances": [
{
"hostname": "wordpress_host",
"command": {
"path": "/path/to/executable",
"args": "--use theseArgs"
},
"environment_vars": {
"ENV_VAR_ONE"
: "value_one",
"ENV_VAR_TWO"
: "value_two"
},
"ports": [
"55000:55000",
"34000:34000"
]
}
]
},
"constraints": {
"node": {
"tags": {
"any": [
"nyc",
"tokyo"
],
"all": [
"db"
]
}
},
"containers": [
"mariadb"
]
},
"shutdown": {
"graceful_timeout": 30,
"signals": [
"SIGINT"
]
},
"startup": {
"delay": 5,
"order": 1
},
"restart": {
"condition": "failure",
"delay": 5,
"max_attempts": 3,
"notify": {
"emails": [
"example@cycle.io",
"youremail@dev.io"
],
"web_hook": "/notify/this/endpoint"
}
},
"health_check": {
"command": "apache2-foreground",
"retries": 5,
"interval": 15,
"timeout": 45,
"restart": true
},
"update": {
"parallelism": 1,
"delay": 5
}
},
"scaling": {
"instances": {
"min": 1,
"max": 20
}
},
"runtime": {
"command": {
"path": "/system/path/for/command",
"args": "args to pass"
},
"namespaces": [
"ipc",
"pid",
"uts",
"network",
"mount",
"user"
],
"environment_vars": {
"ENV_VAR_ONE"
: "value_one",
"ENV_VAR_TWO"
: "value_two"
},
"privileged": false,
"capabilities": [
"CAP_CHOWN",
"CAP_FSETID",
"CAP_DAC_OVERRIDE",
"CAP_FOWNER",
"CAP_SETFCAP",
"CAP_SETGID",
"CAP_SETUID",
"CAP_KILL",
"CAP_MKNOD",
"CAP_NET_BIND_SERVICE",
"CAP_AUDIT_WRITE",
"CAP_SYS_CHROOT"
],
"workdir": "/wordpress"
},
"resources": {
"cpu": {
"limit": 20,
"reserve": 10,
"cpus": [
0,
2
]
},
"ram": {
"limit": "2G",
"reserve": "256K",
"swappiness": 3,
"kernel": "128K",
"kernel_tcp": "128K"
}
},
"integrations": {
"events": {
"deploy": "hit/this/url/on/deploy",
"start": "hit/this/url/on/start",
"stop": "hit/this/url/on/stop"
},
"lets_encrypt": {
"enable": true,
"certificate_path": "destination_path/for_cert",
"chain_path": "/var/run/cycle/tls/current.chain",
"key_path": "/var/run/cycle/tls/current.key",
"bundle_path": "/var/run/cycle/tls/current.bundle"
},
"files": [
{
"source": "/path/to/source",
"destination": "/path/to/destination"
}
]
}
},
"volumes": [
{
"read_only": false,
"local": {
"max_size": "1G"
},
"destination": "/var/lib/wp_files",
"remote_access": {
"enable": true,
"ips": [
{
"ip": "192.168.1.1",
"read_only": false,
"password": {
"algorithm": "raw",
"data": "yourpassword"
}
},
{
"ip": "192.168.1.23",
"read_only": true,
"password": {
"algorithm": "raw",
"data": "otherpassword"
}
}
],
"web_hook": "hit/this/endpoint",
"password": {
"algorithm": "raw",
"data": "your_password_here"
}
}
}
]
}
}