[System]
You are a helpful assistant that answers strictly in JSON. Here's the JSON schema you must adhere to:
<schema>
{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"StackSpec","description":"A Cycle stack file is an \"environment as code\". This allows an environment to be generated consistently based on a fixed specification. \nStack files can describe multiple containers and their configurations, environment service settings, scoped variables, and important metadata.\n","type":"object","required":["version","containers"],"properties":{"version":{"type":"string","description":"The version of the Cycle stack file used.","enum":["1.0"]},"about":{"oneOf":[{"type":["object","null"],"required":["description","version"],"properties":{"version":{"type":"string","description":"A custom, user-defined version of the stack."},"description":{"type":"string","description":"Custom, user-defined details about this stack."}}},{"title":"StackVariable","description":"A variable specified in a stack spec.","pattern":"\\\"?{{(\\$)?([a-z0-9\\-]+)}}\\\"?","type":"string","examples":["{{$stack-variable}}"]}]},"scoped_variables":{"description":"Describes variables that are assigned to one or more containers at runtime. Can be assigned as an environment variable, written as a file inside the container(s), or accessed over the internal API.","oneOf":[{"type":["array","null"],"items":{"title":"StackSpecScopedVariable","type":"object","required":["identifier","scope","access"],"properties":{"identifier":{"oneOf":[{"title":"Identifier","type":"string","description":"A human-readable identifier used to refer to a resource, where using the official ID may be inconvenient.\nThe identifier is automatically tokenized from the name/relevant field of the resource if one is not provided. For example, a container named \"My Container\" will\nhave the identifier of `my-container` and is automatically created by the platform.\n\nThe identifier does not have to be unique.\n"},{"$ref":"#/properties/about/oneOf/1"}]},"scope":{"oneOf":[{"type":"object","required":["containers"],"properties":{"containers":{"description":"Describes the containers that have access to this scoped variable.","oneOf":[{"type":"object","required":["global"],"properties":{"global":{"description":"If true, all containers in the environment will have access to this variable.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"ids":{"description":"A list of container IDs that are granted access to this variable.","oneOf":[{"type":["array","null"],"items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]},"identifiers":{"description":"A list of container identifiers that are granted access to this variable.","oneOf":[{"type":["array","null"],"items":{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/identifier/oneOf/0"}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"access":{"oneOf":[{"type":"object","properties":{"env_variable":{"description":"Grants access to this variable from within a container as an environment variable.","oneOf":[{"type":"object","required":["key"],"properties":{"key":{"description":"The environment variable inside the container that stores the value of the variable.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"internal_api":{"description":"Grants access to this variable over the Internal API.","oneOf":[{"type":["object","null"],"properties":{"duration":{"description":"Sets the duration that this variable can be accessed over the Internal API, after container start. Provides additional security as sensitive data can only be accessed for a limited time.","anyOf":[{"title":"Duration","type":"string","description":"A string signifying a duration of time. Valid time units are \"ns\", \"us\" (or \"\u00b5s\"), \"ms\", \"s\", \"m\", \"h\", \"d\", \"w\", \"y\".","examples":["72h45m2s"]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"file":{"description":"Grants access to this variable as a file inside the container.","oneOf":[{"type":["object","null"],"required":["decode","path"],"properties":{"decode":{"description":"When true, Cycle will interpret this variable as a base-64 encoded string, and decode it before writing it to the file inside the container.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"path":{"description":"The absolute path to write the variable to (including file name). If `null`, it will be written to `/var/run/cycle/variables/{variable-identifier}`.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}],"examples":["/var/run/cycle/variables/<myVariable>"]},"permissions":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}],"description":"A linux file mode that will be set on the injected file.","examples":["0644"]},"uid":{"oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}],"description":"The linux UID to set on the file.","examples":[777]},"gid":{"oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}],"description":"The linux GID to set on the file.","examples":[777]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"source":{"anyOf":[{"type":"object","description":"Describes the source/value of the variable.\n- **raw**: Directly set the value of the variable in the stack. - **url**: Cycle will fetch the variable content from a remote source when the container starts.\n","discriminator":{"propertyName":"type","mapping":{"url":"./StackSpecScopedVariableUrlSource.yml","raw":"./StackSpecScopedVariableRawSource.yml"}},"oneOf":[{"title":"StackSpecScopedVariableUrlSource","type":"object","description":"A variable who's value is fetched from a URL when the container starts.","required":["type","details"],"properties":{"type":{"type":"string","description":"The type of scoped variable.","enum":["url"]},"details":{"oneOf":[{"type":"object","required":["url","headers","auth_token_url"],"properties":{"url":{"description":"The URL to call to fetch the value.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"headers":{"description":"Additional headers that can be attached to the URL request. Useful for adding meta-data to third-party services.","oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]},"auth_token_url":{"description":"A URL that can be provided to authenticate with a third party secret service. Cycle will make a request to this URL before fetching the secret URL, and use the response as the value of an Authorization header when requesting the secret.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecScopedVariableRawSource","type":"object","description":"A variable with a hard-coded value.","required":["type","details"],"properties":{"type":{"description":"The type of scoped variable.","type":"string","enum":["raw"]},"details":{"oneOf":[{"type":"object","required":["value","blob"],"properties":{"value":{"description":"The value of the variable.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"blob":{"description":"A boolean where true represents the text the user is entering will be multi line.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"secret":{"oneOf":[{"type":["object","null"],"properties":{"iv":{"description":"A string describing the IV Hex associated with the encryption of the variable.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"hint":{"description":"A user specified hint that will suggest what the encryption key might be","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}}]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"containers":{"oneOf":[{"type":"object","description":"A mapping of containers that will be deployed as a part of this stack. The key is used as the container's identifier.","additionalProperties":{"title":"StackSpecContainer","description":"A container template defined within a stack.","type":"object","required":["name","image","config","stateful"],"properties":{"name":{"type":"string","description":"The human-readable name of this container."},"image":{"x-ogen-name":"StackSpecContainerImageProperty","description":"Details about the image used for this container.","oneOf":[{"title":"StackSpecContainerImage","type":"object","required":["origin"],"properties":{"name":{"description":"The human-readable name of this image.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"origin":{"description":"Instructions on how to fetch or build this image.","oneOf":[{"title":"StackSpecImageOrigin","type":"object","description":"The origin of the image.","discriminator":{"propertyName":"type","mapping":{"docker-hub":"../../components/schemas/images/origins/dockerHub/DockerHubOrigin.yml","docker-file":"../../components/schemas/images/origins/dockerFile/DockerFileOrigin.yml","docker-registry":"../../components/schemas/images/origins/dockerRegistry/DockerRegistryOrigin.yml","oci-registry":"../../components/schemas/images/origins/ociRegistry/OciRegistryOrigin.yml","cycle-source":"../../components/schemas/images/origins/cycleSource/CycleSourceOrigin.yml"}},"oneOf":[{"title":"DockerHubOrigin","type":"object","description":"An image origin where the image is pulled from DockerHub.","required":["type","details"],"properties":{"type":{"type":"string","enum":["docker-hub"]},"details":{"type":"object","required":["target"],"properties":{"existing":{"anyOf":[{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/image/oneOf/0/properties/origin/oneOf/0/oneOf/2/properties/details/properties/existing"},{"type":"null"}]},"target":{"type":"string","description":"The DockerHub target string. ex - `mysql:5.7`"},"username":{"type":"string","description":"For authentication, a username."},"token":{"type":"string","description":"For authentication, a token."}}}}},{"title":"DockerFileOrigin","type":"object","description":"An image origin where the image is built from a Dockerfile located in a git repository.","required":["type","details"],"properties":{"type":{"type":"string","enum":["docker-file"]},"details":{"type":"object","properties":{"existing":{"anyOf":[{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/image/oneOf/0/properties/origin/oneOf/0/oneOf/2/properties/details/properties/existing"},{"type":"null"}]},"repo":{"anyOf":[{"title":"RepoSourceType","type":"object","description":"Information about the repository.","required":["url"],"properties":{"url":{"type":"string","description":"The URL of the repository."},"branch":{"type":"string","description":"An optional branch arguement.  Default value is `master`."},"auth":{"anyOf":[{"type":"null"},{"type":"object","description":"Authentication information for the repository.","discriminator":{"propertyName":"type","mapping":{"http":"../CredentialsHTTP.yml","ssh":"../CredentialsSSH.yml"}},"oneOf":[{"title":"HTTPSourceCredentials","type":"object","required":["type","credentials"],"properties":{"type":{"type":"string","enum":["http"]},"credentials":{"type":"object","description":"Authentication credentails for the Dockerfile image source type when authenticating over HTTP.","required":["username","password"],"properties":{"username":{"type":"string","description":"For authentication, the username."},"password":{"type":"string","description":"For authentication, the password."}}}}},{"title":"SSHSourceCredentials","type":"object","required":["type","credentials"],"properties":{"type":{"type":"string","enum":["ssh"]},"credentials":{"type":"object","description":"Authentication credentials for the Dockerfile image source type when authenticating with SSH.","required":["username","passphrase","private_key"],"properties":{"username":{"type":"string","description":"The username for the repo service, that is used to authenticate an ssh key."},"passphrase":{"type":"string","description":"The passphrase used for the key."},"private_key":{"type":"string","description":"A pem encoded private key."}}}}}]}]},"ref":{"oneOf":[{"type":"object","description":"Repository reference information.","required":["type","value"],"properties":{"type":{"type":"string","description":"The type of reference being used."},"value":{"type":"string","description":"The value for the given reference type."}}},{"type":"null"}]}}},{"type":"null"}]},"targz_url":{"type":["string","null"],"description":"An endpoint that serves the tar file."},"context_dir":{"type":["string","null"],"description":"The path to the directory to use as the context when building the image."},"build_file":{"type":["string","null"],"description":"The path to the Dockerfile to be used for buiding the image."},"credentials":{"anyOf":[{"title":"DockerfileCredentails","description":"An array of credentials objects to be used when authenticating against private images used by the Dockerfile.","type":"array","items":{"type":"object","description":"Credentials object used for authentication of indirect resources such as private parent images.","properties":{"url":{"type":"string","description":"The url the resource is located at."},"username":{"type":"string","description":"A username for authentication."},"token":{"type":"string","description":"A token for authentication."}}}},{"type":"null"}]}}}}},{"title":"DockerRegistryOrigin","type":"object","description":"An image origin where the image is pulled from a private Docker registry.","required":["type","details"],"properties":{"type":{"type":"string","enum":["docker-registry"]},"details":{"type":"object","required":["target","url"],"properties":{"existing":{"title":"ExistingSource","type":"object","description":"In a stack, specifies an image source ID from which Cycle will derive any values not specified in the stack file. This is useful for avoiding direct placement of credentials in a stack file, for example.","properties":{"source_id":{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/image/oneOf/0/properties/origin/oneOf/0/oneOf/4/properties/details/properties/source_id","description":"The ID of the image source this image should be built from."}}},"target":{"type":"string","description":"The image name on the registry."},"url":{"type":"string","description":"The url of the remote registry."},"username":{"type":"string","description":"For authentication, a username."},"token":{"type":"string","description":"For authentication, a token."},"password":{"type":"string","description":"For authentication, a password."}}}}},{"title":"OciRegistryOrigin","type":"object","description":"An image origin that pulls images fro an OCI-compatible registry. Also used for provider-native registries, such as AWS ECR.","required":["type","details"],"properties":{"type":{"type":"string","enum":["oci-registry"]},"details":{"type":"object","required":["target","url"],"properties":{"existing":{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/image/oneOf/0/properties/origin/oneOf/0/oneOf/2/properties/details/properties/existing"},"target":{"type":"string","description":"The image name on the registry."},"url":{"type":"string","description":"The url of the remote registry."},"auth":{"oneOf":[{"title":"RegistryAuth","type":"object","description":"Authentication details for a third party image registry/source.","discriminator":{"propertyName":"type","mapping":{"user":"RegistryAuthUser.yml","provider":"RegistryAuthProvider.yml","webhook":"RegistryAuthWebhook.yml"}},"oneOf":[{"title":"RegistryAuthUser","description":"User/token based credentials for authentication to a third-party image source.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["user"]},"details":{"type":"object","properties":{"username":{"type":"string"},"token":{"type":"string"}}}}},{"title":"RegistryAuthProvider","description":"Credentials for authentication to a provider-native image registry, such as AWS ECR.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["provider"]},"details":{"type":"object","required":["flavor","credentials"],"properties":{"flavor":{"type":"string","enum":["ecr"]},"credentials":{"title":"RegistryAuthProviderCredentials","type":"object","properties":{"region":{"type":"string"},"namespace":{"type":"string"},"api_key":{"type":"string"},"secret":{"type":"string"},"subscription_id":{"type":"string"},"client_id":{"type":"string"},"config":{"type":"string","description":"A base64'd string of additional configuration options."}}}}}}},{"title":"RegistryAuthWebhook","description":"Webhook-based authentication to the provided URL. This webhook expects to receive a base-64 string that when decoded is in the format `username:password`","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["webhook"]},"details":{"type":"object","required":["url"],"properties":{"url":{"type":"string"}}}}}]},{"type":"null"}]}}}}},{"title":"CycleSourceOrigin","type":"object","description":"An image origin that references an image source on Cycle. \n\nThis origin will never be embedded in an image source. It is for use in stacks, describing an image which is already a part of an image source on Cycle.\n","required":["type","details"],"properties":{"type":{"type":"string","enum":["cycle-source"]},"details":{"type":"object","required":["source_id"],"properties":{"source_id":{"description":"The ID referencing the image source where this image originated.","title":"ID","type":"string","format":"objectid","examples":["651586fca6078e98982dbd90"]}}}}}]},{"$ref":"#/properties/about/oneOf/1"}]},"build":{"description":"Additional details applied when building an image.","oneOf":[{"type":["object","null"],"required":["args"],"properties":{"args":{"description":"A map of build arguments applied to the image at build time.","oneOf":[{"type":"object","additionalProperties":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"builder":{"description":"A specific builder to use. By default, Cycle uses its factory service and a standard build command to build images, but this can be enhanced by using an image builder integration.","oneOf":[{"type":["object","null"],"required":["integration_id"],"properties":{"integration_id":{"description":"The ID of the integration to use when building the image. The integration must support image building to be compatible.","$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/config/oneOf/0/properties/integrations/anyOf/0/properties/backups/oneOf/0/properties/integration_id/oneOf/0"}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"annotations":{"oneOf":[{"type":["object","null"],"description":"Additional user-provided meta data about the container.","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]},"stateful":{"description":"Whether or not to mark the container as stateful when deployed. Stateful containers can utilize volumes (stateful data) and are generally used for running databases or other data management applications.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"config":{"oneOf":[{"type":"object","description":"Configuration options for this container that will be applied when deployed as part of the stack.","title":"StackContainerConfig","required":["network","deploy"],"properties":{"network":{"oneOf":[{"title":"StackSpecContainerConfigNetwork","x-ogen-name":"StackSpecContainerConfigNetwork","description":"Stack configuration options related to the container's network.","type":"object","required":["public","hostname"],"properties":{"public":{"description":"The level of public network access this container should have.","oneOf":[{"type":"string","enum":["enable","disable","egress-only"]},{"$ref":"#/properties/about/oneOf/1"}]},"hostname":{"description":"The hostname of the container. This is how it can be referenced by other containers in the same environment.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"ports":{"description":"A list of port mappings on this container.","oneOf":[{"type":"array","items":{"type":"string"},"examples":["80:80","443:80","3000"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"deploy":{"oneOf":[{"title":"StackSpecContainerConfigDeploy","type":"object","description":"Stack configuration options related to how the container behaves over its lifecycle (startup, shutdown, health checks, etc).","required":["instances"],"properties":{"instances":{"description":"The number of desired instances to deploy.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"strategy":{"description":"The strategy Cycle will apply when deploying instances of this container.\n\n- ** resource-density **: Cycle will distribute instances across servers to maintain balanced resource usage.\n- ** high-availability **: Cycle will deploy instances across servers with an emphasis on geographic and physical separation. Requires multiple locations.\n- ** distributed **: Cycle will deploy instances across servers with an emphasis on physical separation. Does not require multiple locations.\n- ** first-available **: Cycle will deploy one instance to every server that matches the specified criteria. (default)\n- ** node **: Cycle will deploy one instance to every server that matches the specified criteria.\n- ** edge **: Cycle will prioritize geographic distribution of instances.\n- ** function **: Every ingress request/connection receives its own instance. \n- ** manual **: Cycle will not make any decisions on where instances are deployed. Instead, instances must be deployed manually using the portal or API.\n","oneOf":[{"type":["string","null"],"enum":["resource-density","manual","high-availability","first-available","node","edge","function"],"default":"first-available"},{"$ref":"#/properties/about/oneOf/1"}]},"function":{"description":"Configuration options for containers using the 'function' deployment strategy.","oneOf":[{"type":["object","null"],"properties":{"max_pool_size":{"description":"The maximum number of instances that Cycle can pre-allocate (includes auto-scaled instances).","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"max_shard_concurrency":{"description":"For each shard (scheduler), the maximum number of tasks it can run in parallel.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"max_runtime":{"description":"The maximum amount of time a function instance can run before timing out.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"max_queue_time":{"description":"The maximum amount of time Cycle will wait for an instance to be available.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"stateful":{"description":"Configuration options for stateful containers.","oneOf":[{"type":["object","null"],"required":["options"],"properties":{"options":{"description":"Stateful container options.","type":["object","null"],"properties":{"use_base_hostname":{"description":"When enabled, instances will utilize stateless base hostnames instead of being prefixed with a unique ID.","type":["boolean","null"]}}}}},{"$ref":"#/properties/about/oneOf/1"}]},"constraints":{"description":"Configuration options that provide the ability to set restrictions on which nodes instances of this container are able to be deployed to. (i.e. if you have a GPU container, it should only go on nodes with a GPU).","oneOf":[{"type":["object","null"],"properties":{"node":{"type":["object","null"],"required":["tags"],"properties":{"tags":{"description":"Tags applied to a node. Cycle generates some automatically, but additional, custom tags can be applied on a per-node basis.","oneOf":[{"type":"object","properties":{"any":{"description":"If a node has at least one of these tags, it is considered a valid deployment target for this container.","oneOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]},"all":{"description":"A node must have **ALL** of these tags to be considered a valid deployment target for this container.","oneOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}}}},{"$ref":"#/properties/about/oneOf/1"}]},"shutdown":{"description":"Configuration options for how this container behaves during shutdown.","oneOf":[{"type":["object","null"],"properties":{"graceful_timeout":{"description":"How long the platform will wait for a container to stop gracefully.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"signals":{"oneOf":[{"type":"array","description":"Signals that should be sent to the container on shutdown.","items":{"title":"ShutdownSignal","type":"string","description":"Process signals that Cycle can be configured to send to the container on a shutdown event.","enum":["SIGTERM","SIGINT","SIGUSR1","SIGUSR2","SIGHUP","SIGQUIT"]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"startup":{"description":"Configuration options for how this container behaves during startup.","oneOf":[{"type":["object","null"],"properties":{"delay":{"description":"How long the platform will wait before sending the start signal to the given container.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"update":{"description":"Configurations for how the container behaves during updates.","oneOf":[{"type":["object","null"],"properties":{"stagger":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"description":"When set, Cycle will pick a random time from `0 - this duration`, and stagger the instances so they all start at different times (up to the time specified here)."}}},{"$ref":"#/properties/about/oneOf/1"}]},"restart":{"description":"Configuration options for how Cycle should handle restarting this container (i.e. in case the process inside the container dies).","oneOf":[{"type":["object","null"],"required":["condition","delay","max_attempts"],"properties":{"condition":{"description":"Under what circumstances Cycle should try to restart this container.","oneOf":[{"type":"string","enum":["always","never","failure"]},{"$ref":"#/properties/about/oneOf/1"}]},"delay":{"description":"How long the platform will wait between restart attempts.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]},"max_attempts":{"description":"The maximum number of restart attempts Cycle will make.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"health_check":{"description":"Configuration options for automated container health checks.","oneOf":[{"type":["object","null"],"required":["command","retries","interval","timeout","restart"],"properties":{"command":{"description":"The command or script to run to verify the health of the container. This script is run inside the container by Cycle.\nThis command accepts two types of entries:\n- The first is a reference to a script that already lives in the container filesystem. This can be defined by giving the full path to the script as the value.   - The second format is an inline script.  If you need the code to execute within a shell, wrap the commands in escaped quotes like this `\"\\\"curl -s -o /dev/console -w \\\"%{http_code}\\\" http://localhost:3000/_health | grep '200'  && exit 0 || exit 1\\\"\"`.  Do not use the `/bin/sh -c <commands>` format, this will not be accepted.\n","oneOf":[{"type":"string","examples":["/bin/sh healthcheck.sh"]},{"$ref":"#/properties/about/oneOf/1"}]},"retries":{"description":"The number of times to retry the command before marking an instance unhealthy.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"interval":{"description":"How long to wait between running health checks.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]},"timeout":{"description":"How long before a health check attempt times out.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]},"restart":{"description":"A boolean where true represents the desire for the container to restart if any instance is unhealthy.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"delay":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"description":"How long to wait after a container start event before running health checks."}}},{"$ref":"#/properties/about/oneOf/1"}]},"telemetry":{"description":"Configuration options for how the instance telemetry (CPU usage, etc) is handled.","oneOf":[{"type":["object","null"],"required":["disable"],"properties":{"retention":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"description":"How long telemetry data should be retained."},"interval":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"description":"The duration between samples."},"webhook":{"description":"A URL where Cycle will send telemetry data to. The payload will be an instance resource snapshot.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"disable":{"description":"If true, Cycle will not aggregate telemetry for this container's instances.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"scaling":{"description":"Configuration options for auto-scaling.","anyOf":[{"title":"StackSpecContainerConfigScaling","type":"object","description":"Stack configuration options for auto-scaling.","required":["autoscale_group","instances","window","thresholds"],"properties":{"autoscale_group":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/identifier/oneOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"description":"The identifier of the auto-scaling group assigned to this container. The auto-scale group determines which infrastructure this container can spin up if it needs more resources to meet demand. Setting it to `null` will limit auto-scaling to only instances."},"instances":{"oneOf":[{"type":"object","description":"Describes the criteria for deploying new instances when an auto-scale criteria is met.","required":["max","max_server","min_ttl"],"properties":{"max":{"description":"Maximum additional instances the auto-scaler will run at any time.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"max_server":{"description":"Minimum number of instances per server.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"min_ttl":{"description":"Minimum amount of time an instance will live.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"window":{"description":"Duration in which the auto-scaler will watch for changes.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]},"thresholds":{"description":"An array of rules that dictate when a scaling event will be triggered.","oneOf":[{"type":"array","items":{"title":"StackSpecContainerScaleThreshold","type":"object","description":"Discriminated union describing the different types of scaling threshold and their respective details","discriminator":{"propertyName":"type","mapping":{"ram":"./StackSpecContainerScaleThresholdRam.yml","cpu":"./StackSpecContainerScaleThresholdCpu.yml","custom":"./StackSpecContainerScaleThresholdCustom.yml","network-connections":"./StackSpecContainerScaleThresholdNetworkConnections.yml","network-requests":"./StackSpecContainerScaleThresholdNetworkRequests.yml","network-throughput":"./StackSpecContainerScaleThresholdNetworkThroughput.yml"}},"oneOf":[{"title":"StackSpecContainerScaleThresholdRam","type":"object","description":"Describes the RAM threshold at which scaling will occur.","required":["type","details"],"properties":{"type":{"type":"string","enum":["ram"]},"details":{"type":"object","required":["usage"],"properties":{"usage":{"type":"string","description":"The target average RAM usage of all instances of this container. Going above this threshold will trigger a scaling event. This threshold must be greater than 25MB.","examples":["2G","25MB"]}}}}},{"title":"StackSpecContainerScaleThresholdCpu","type":"object","description":"Describes the CPU threshold at which scaling will occur.","required":["type","details"],"properties":{"type":{"type":"string","enum":["cpu"]},"details":{"type":"object","required":["utilization"],"properties":{"utilization":{"type":"integer"}}}}},{"title":"StackSpecContainerScaleThresholdNetworkConnections","type":"object","description":"Describes the network connections threshold at which scaling will occur.","required":["type","details"],"properties":{"type":{"type":"string","enum":["network-connections"]},"details":{"type":"object","required":["connections_total"],"properties":{"connections_total":{"type":"integer"}}}}},{"title":"StackSpecContainerScaleThresholdNetworkRequests","type":"object","description":"Describes the network requests threshold at which scaling will occur.","required":["type","details"],"properties":{"type":{"type":"string","enum":["network-requests"]},"details":{"type":"object","required":["requests_total"],"properties":{"requests_total":{"type":"integer"}}}}},{"title":"StackSpecContainerScaleThresholdNetworkThroughput","type":"object","description":"Describes the network throughput threshold at which scaling will occur.","required":["type","details"],"properties":{"type":{"type":"string","enum":["network-throughput"]},"details":{"type":"object","required":["private","bandwidth"],"properties":{"private":{"type":"boolean"},"bandwidth":{"type":"string","description":"The limit (maximum) amount of throughput each instance of the given container can use before triggering a scaling event.","examples":["1gbps","50mbps"]}}}}}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"runtime":{"anyOf":[{"title":"StackSpecContainerConfigRuntime","description":"Configuration options related to how the container behaves while it is running (environment variables, command overrides, kernel capabilities, etc. )","type":"object","properties":{"workdir":{"description":"The working directory to execute the command in.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"command":{"description":"The command to execute when this container starts. Will override the default specified in the container.","oneOf":[{"type":"object","properties":{"path":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"args":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"environment_vars":{"description":"A map of environment variables that will be injected into the container.","oneOf":[{"type":"object","additionalProperties":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]},"namespaces":{"description":"Container namespaces to apply. By default, all are applied. Removing/changing this can have security implications.","oneOf":[{"type":"array","items":{"type":"string","enum":["ipc","pid","uts","network","mount","user","cgroup"]}},{"$ref":"#/properties/about/oneOf/1"}]},"sysctl":{"description":"Sysctl options to apply.","oneOf":[{"type":"object","additionalProperties":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]},"rlimits":{"description":"RLIMIT options to apply.","oneOf":[{"type":"object","additionalProperties":{"type":"object","required":["hard","soft"],"properties":{"hard":{"oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"soft":{"oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"seccomp":{"description":"Configuration options for seccomp. Cycle enables seccomp by default.","oneOf":[{"type":"object","required":["disable","rules"],"properties":{"disable":{"oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"rules":{"oneOf":[{"type":"array","items":{"oneOf":[{"type":"object","required":["capabilities","syscall"],"properties":{"capabilities":{"oneOf":[{"type":"object","required":["includes","excludes"],"properties":{"includes":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"excludes":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"syscall":{"oneOf":[{"type":"object","required":["names","action"],"properties":{"names":{"type":"array","items":{"type":"string"}},"action":{"type":"string","enum":["SCMP_ACT_KILL","SCMP_ACT_KILL_PROCESS","SCMP_ACT_KILL_THREAD","SCMP_ACT_TRAP","SCMP_ACT_ERRNO","SCMP_ACT_TRACE","SCMP_ACT_ALLOW","SCMP_ACT_LOG","SCMP_ACT_NOTIFY"]},"errnoRet":{"type":"integer"},"args":{"type":"array","items":{"type":"object","required":["index","value","op"],"properties":{"index":{"type":"integer"},"value":{"type":"integer"},"valuetwo":{"type":"integer"},"op":{"type":"string","enum":["SCMP_CMP_NE","SCMP_CMP_LT","SCMP_CMP_LE","SCMP_CMP_EQ","SCMP_CMP_GE","SCMP_CMP_GT","SCMP_CMP_MASKED_EQ"]}}}}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"host":{"description":"Configuration options regarding the underlying host.","oneOf":[{"type":["object","null"],"properties":{"expose_proc":{"description":"If true, Cycle will mount the `/proc` directory into the container, giving it access to the host metrics. This is useful if you're running i.e. a monitoring agent.","oneOf":[{"type":["boolean","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"expose_cgroups":{"description":"If true, Cycle will mount the host's `/sys/fs/cgroups` directory into the container at `/var/run/cycle/host/cgroups`.","oneOf":[{"type":["boolean","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"power_management":{"description":"If true, Cycle will give the container instances access via internal api to power off or reboot the host server.","oneOf":[{"type":["boolean","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"privileged":{"description":"If true, the container process will run in fully-privileged mode. **WARNING** This is considered insecure, and should only be done if you know what you're doing.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"capabilities":{"description":"Additional Linux kernel capabilities to apply to this container process.","oneOf":[{"type":"array","items":{"type":"string","enum":["CAP_CHOWN","CAP_FSETID","CAP_DAC_OVERRIDE","CAP_FOWNER","CAP_SETFCAP","CAP_SETGID","CAP_SETUID","CAP_KILL","CAP_MKNOD","CAP_NET_BIND_SERVICE","CAP_NET_RAW","CAP_AUDIT_WRITE","CAP_SYS_CHROOT","CAP_SETPCAP","CAP_DAC_READ_SEARCH","CAP_NET_ADMIN","CAP_NET_BROADCAST","CAP_SYS_ADMIN","CAP_SYS_MODULE","CAP_SYS_NICE","CAP_SYS_PACCT","CAP_SYS_PTRACE","CAP_SYS_RAWIO","CAP_SYS_RESOURCE","CAP_SYS_BOOT","CAP_SYS_TIME","CAP_SYS_TTY_CONFIG","CAP_SYSLOG","CAP_AUDIT_CONTROL","CAP_AUDIT_READ","CAP_IPC_LOCK","CAP_IPC_OWNER","CAP_LINUX_IMMUTABLE","CAP_MAC_ADMIN","CAP_MAC_OVERRIDE","CAP_BLOCK_SUSPEND","CAP_LEASE","CAP_WAKE_ALARM"]}},{"$ref":"#/properties/about/oneOf/1"}]},"rootfs":{"description":"Configuration options for the root filesystem.","oneOf":[{"type":"object","required":["readonly"],"properties":{"readonly":{"description":"If true, the container's filesystem will be read-only.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"resources":{"anyOf":[{"title":"StackSpecContainerConfigResources","description":"Configuration options for container resource limits and reserves.","type":"object","required":["cpu","ram"],"properties":{"cpu":{"oneOf":[{"type":"object","properties":{"shares":{"oneOf":[{"type":"object","required":["limit","reserve"],"properties":{"limit":{"oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"reserve":{"oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"cpus":{"type":"string"}}},{"$ref":"#/properties/about/oneOf/1"}]},"ram":{"oneOf":[{"type":"object","properties":{"limit":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"reserve":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"swappiness":{"oneOf":[{"type":"number"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"integrations":{"anyOf":[{"title":"StackSpecContainerConfigIntegrations","type":"object","description":"Configuration options for additional integrations/features that Cycle provides.","properties":{"webhooks":{"description":"Enable additional webhooks that Cycle will call out to during the course of a container's lifetime. All webhooks send a payload as an object containing the instance, container, server, and environment IDs.","oneOf":[{"type":["object","null"],"properties":{"events":{"description":"Webhooks that are triggered during a container event.","oneOf":[{"type":["object","null"],"properties":{"deploy":{"description":"Cycle will call this endpoint when the container is deployed.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"start":{"description":"Cycle will call this endpoint when the container is started.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"stop":{"description":"Cycle will call this endpoint when the container is stopped.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"config":{"description":"The webhook to hit when the container's configuration is changed.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"lets_encrypt":{"description":"When enabled, this integration will configure Let's Encrypt certificates that will be injected into the container at runtime. The certificates will be managed by the platform and renewed automatically.","oneOf":[{"type":["object","null"],"properties":{"certificate_path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"chain_path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"key_path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"bundle_path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"additional_certs_path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"files":{"description":"When enabled, Cycle will fetch and inject remote files into the container at the specified destination during runtime.","oneOf":[{"type":["array","null"],"items":{"type":"object","required":["source","destination"],"properties":{"source":{"oneOf":[{"$ref":"#/properties/about/oneOf/1"},{"type":"string"}]},"destination":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"backups":{"description":"When enabled, Cycle will automatically manage backups of this container. This is only available for stateful containers.","oneOf":[{"type":["object","null"],"required":["destination","backup","restore","retention"],"properties":{"integration_id":{"description":"An identifier of an integration that supports backups. All backups will be sent to this destination.","oneOf":[{"title":"HybridIdentifier","type":"string","description":"Either a resource ID (objectid - i.e. 651586fca6078e98982dbd90) or a resource Identifier (human-readable)","examples":["my-image-source"]},{"$ref":"#/properties/about/oneOf/1"}]},"backup":{"description":"Configuration options for how the container should be backed up.","oneOf":[{"type":"object","required":["command","timeout","cron_string"],"properties":{"command":{"description":"The command to run to capture a backup. The output sent to `STDOUT` will be captured and sent to the specified integration.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"timeout":{"description":"How long the backup will attempt to run before timing out.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"cron_string":{"description":"A cron string describing how often to run the backup command.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"restore":{"description":"Configuration options for how the backup should be restored.","oneOf":[{"type":["object","null"],"required":["command","timeout"],"properties":{"command":{"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"timeout":{"description":"The time in seconds for the restore to attempt to complete before timing out.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"retention":{"description":"How long the platform will keep backups. Default is 1 year.","anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}],"default":"365d"}}},{"$ref":"#/properties/about/oneOf/1"}]},"shared_file_systems":{"description":"When enabled, Cycle will mount a shared host directory into this container. The directory will be shared with all other containers that mount it.","oneOf":[{"type":["object","null"],"additionalProperties":{"oneOf":[{"type":"object","required":["writable","mount_point"],"properties":{"writable":{"oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"mount_point":{"oneOf":[{"$ref":"#/properties/about/oneOf/1"},{"type":"string"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"role":{"description":"The role applied to this container. **Not yet implemented**","type":["string","null"],"enum":["conductor"]},"volumes":{"description":"A list of configurations for volumes that will be attached to the container. Only applicable if the container is set to `stateful`.","oneOf":[{"type":["array","null"],"items":{"title":"StackSpecContainerVolume","description":"A container volume configuration.","type":"object","required":["destination"],"properties":{"local":{"description":"Configuration options for local volumes.","oneOf":[{"type":"object","required":["max_size"],"properties":{"max_size":{"description":"The maximum size this volume can grow to. Container volumes on Cycle are thinly provisioned, meaning this isn't an allocation - the volume will only use the space it needs up to this size.","oneOf":[{"type":"string","examples":["5G","500M"]},{"$ref":"#/properties/about/oneOf/1"}]},"storage_pool":{"description":"A boolean where true signifies using the largest drive over 2TB for the target server.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"destination":{"description":"The path this volume should be mounted at inside the container.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"read_only":{"description":"If true, the container will be unable to write data to the volume.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"block_device":{"oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}],"description":"Indicates that the volume will be used as unformatted block storage.\n"},"remote_access":{"description":"Configuration options for setting up remote access to this volume via SFTP.","oneOf":[{"type":"object","required":["enable","password"],"properties":{"enable":{"description":"If true, this volume will be accessible over SFTP.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"ips":{"description":"A list of IPs that SFTP access will be limited to.","oneOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]},"webhook":{"description":"If set, Cycle will call out to this URL for authentication. Anything other than a 200 response will be considered a validation failure.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"password":{"description":"The password used for logging in to this volume via SFTP.","oneOf":[{"type":"object","required":["algorithm","data"],"properties":{"algorithm":{"description":"The algorithm the password is encoded with. `raw` means the password is plain-text.","oneOf":[{"type":"string","enum":["raw","sha512","md5"]},{"$ref":"#/properties/about/oneOf/1"}]},"data":{"description":"The password string.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"deprecate":{"description":"If true, the container is marked as `deprecated`, and cannot be started anymore. Deprecated containers also don't count toward resource utilization.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"lock":{"description":"If true, the container is marked as `locked` and cannot be deleted in any way until the lock is lifted.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"monitoring":{"description":"Monitoring options for containers within this stack.","oneOf":[{"title":"StackSpecMonitoringConfig","description":"Monitoring options for the stack build & containers within this stack.","type":"object","properties":{"logs":{"oneOf":[{"title":"StackSpecMonitoringLogs","description":"Log configuration for containers in this stack.","type":"object","properties":{"logs":{"oneOf":[{"type":"object","properties":{"drain":{"description":"When enabled, log drain allows logs to be exported to a third party service.","oneOf":[{"type":"object","required":["url"],"properties":{"url":{"description":"The URL to the third party logging service where logs will be sent.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"format":{"description":"The format Cycle will use to send the logs.","oneOf":[{"type":"string","enum":["ndjson-headers","ndjson-raw"]},{"type":"null"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"type":"null"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"type":"null"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"type":"null"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"services":{"description":"Settings for any auxillary services deployed as part of the environment, such as load balancer and discovery services.","oneOf":[{"title":"StackSpecServices","type":["object","null"],"properties":{"discovery":{"anyOf":[{"title":"StackSpecDiscoveryService","description":"Configuration options for the discovery service.","type":"object","additionalProperties":false,"properties":{"service":{"anyOf":[{"$ref":"#/properties/services/oneOf/0/properties/vpn/anyOf/0/properties/service/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"config":{"anyOf":[{"title":"StackSpecDiscoveryConfig","type":"object","properties":{"empty_set_delay":{"anyOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"dual_stack_legacy":{"description":"When enabled, discovery will return both IPv6 and IPv4 when in legacy mode.  Otherwise, only IPv4 will be returned.","anyOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"hosts":{"description":"A custom mapping of hosts - for forced resolution of specific IPs for a domain.","oneOf":[{"type":["object","null"],"additionalProperties":{"type":"object","properties":{"ipv4":{"oneOf":[{"type":["array","null"],"items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]},"ipv6":{"oneOf":[{"type":["array","null"],"items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]},"custom_resolvers":{"description":"A list of custom DNS resolver strings.  Can specifify domains or ips.","anyOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"loadbalancer":{"anyOf":[{"title":"StackSpecLoadBalancerService","description":"Configuration options for the load balancer service.","type":"object","additionalProperties":false,"properties":{"service":{"anyOf":[{"$ref":"#/properties/services/oneOf/0/properties/vpn/anyOf/0/properties/service/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"config":{"anyOf":[{"title":"StackSpecLoadBalancerConfig","type":"object","description":"The config object for the loadbalancer service.","discriminator":{"propertyName":"type","mapping":{"haproxy":"types/haproxy/StackSpecHaProxyLbType.yml","v1":"types/v1/StackSpecV1LbType.yml","default":"types/StackSpecDefaultLbType.yml"}},"oneOf":[{"title":"StackSpecHaProxyLbType","type":"object","required":["type","details","ipv4","ipv6"],"properties":{"ipv4":{"description":"Allow / disallow traffic to be routed via IPv4.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"ipv6":{"description":"Allow / disallow traffic to be routed via IPv6.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"type":{"type":"string","enum":["haproxy"]},"details":{"anyOf":[{"title":"StackSpecHaProxyConfig","type":"object","description":"Describes settings that are passed to HAProxy within the load balancer.","required":["default","ports"],"properties":{"default":{"description":"Settings that are applied to any port that is not overridden in the following ports section.","oneOf":[{"title":"StackSpecHAProxyConfigSet","type":"object","required":["frontend","backend"],"properties":{"frontend":{"oneOf":[{"type":"object","description":"Settings that describe how incoming traffic to the load balancer is handled.","required":["mode","max_connections","timeouts"],"properties":{"mode":{"description":"The type of traffic expected by the load balancer for this port. Can be either: \n - tcp: Traffic is forwarded without any parsing or additional manipulation. \n - http: Traffic is treated as web traffic. If a LINKED record is configured for a container exposing this port, the domain will be parsed and it will be forwarded to the proper container. This allows multiple services to run on port 80 in the same environment.","oneOf":[{"type":"string","enum":["tcp","http"]},{"$ref":"#/properties/about/oneOf/1"}]},"max_connections":{"description":"The number of simultaneous connections that can be processed at a time.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"timeouts":{"description":"Various options for handling timeouts when communicating with the client.","oneOf":[{"type":["object","null"],"required":["client_secs","client_fin_ms","http_keep_alive_ms","http_request_ms"],"properties":{"client_secs":{"description":"The number of seconds the load balancer will wait for a response from a client before disconnecting.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"client_fin_ms":{"description":"The number of milliseconds the load balancer will wait for a client to send it data when one direction is already closed. This is particularly useful to avoid keeping connections in a waiting state for too long when clients do not disconnect cleanly.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"http_keep_alive_ms":{"description":"The number of milliseconds the load balancer will wait for a new HTTP request to start coming after a response was set. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20http-request) for more information. (`http` mode only)","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"http_request_ms":{"description":"The number of milliseconds the load balancer will wait for a complete HTTP request. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20http-request) for more information. (`http` mode only)","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"backend":{"oneOf":[{"type":"object","description":"Settings related to how the load balancer routes connections to container instances.","required":["balance","timeouts"],"properties":{"balance":{"description":"How connections are balanced across your container instances. Can be one of the following: \n - `roundrobin`: Each container instance is used in turns. \n - `static-rr`: Each container instance is used in turns, but is faster than Round Robin at the expense of being less dynamic. \n - `leastconn`: Routes traffic to the instance with the least number of active connections. \n - `first`: Routes traffic to the first available instance. \n - `source`: The same client IP always reaches the same container instance as long as no instance goes down or up.","oneOf":[{"type":"string","enum":["roundrobin","static-rr","leastconn","first","source"]},{"$ref":"#/properties/about/oneOf/1"}]},"timeouts":{"description":"Various options for handling timeouts when communicating with a container instance behind the load balancer.","oneOf":[{"type":["object","null"],"required":["server_secs","server_fin_ms","connect_ms","queue_ms","tunnel_secs"],"properties":{"server_secs":{"description":"The number of seconds the load balancer will wait for a response from the container instance. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20server) for more information.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"server_fin_ms":{"description":"The number of milliseconds the load balancer will wait for the server to send data when one direction is already closed. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20server-fin) for more information.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"connect_ms":{"description":"The number of milliseconds the load balancer will wait for a successful connection to a container instance. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20connect) for more information.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"queue_ms":{"description":"The number of milliseconds the load balancer will hold connections in a queue when the maximum number of connections has been reached. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20queue) for more information.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"tunnel_secs":{"description":"The number of milliseconds the load balancer will allow for inactivity on a bidirectional tunnel. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20tunnel) for more information.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"ports":{"description":"An object that defines how HAProxy will act on a specific port. The key is a custom port, and the value is the same settings object found under `default` above.","oneOf":[{"type":"object","additionalProperties":{"oneOf":[{"$ref":"#/properties/services/oneOf/0/properties/loadbalancer/anyOf/0/properties/config/anyOf/0/oneOf/0/properties/details/anyOf/0/properties/default/oneOf/0"},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"title":"StackSpecV1LbType","type":"object","required":["type","details","ipv4","ipv6"],"properties":{"ipv4":{"description":"Allow / disallow traffic to be routed via IPv4.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"ipv6":{"description":"Allow / disallow traffic to be routed via IPv6.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"type":{"type":"string","enum":["v1"]},"details":{"oneOf":[{"title":"StackSpecV1LbConfig","type":"object","required":["controllers"],"properties":{"controllers":{"description":"A configuration for a specific port.","oneOf":[{"type":"array","items":{"$ref":"#/properties/services/oneOf/0/properties/loadbalancer/anyOf/0/properties/config/anyOf/0/oneOf/1/properties/details/oneOf/0/properties/controller_template/anyOf/0"}},{"$ref":"#/properties/about/oneOf/1"}]},"controller_template":{"anyOf":[{"title":"StackSpecV1LbController","type":"object","required":["identifier","port"],"properties":{"identifier":{"description":"A human-readable identifier for this controller. It will default to the port, i.e. `port-443`, but can be renamed to anything, such as the service this controller represents.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"port":{"description":"The port inbound trafic is accepted on.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"waf":{"anyOf":[{"$ref":"#/properties/services/oneOf/0/properties/loadbalancer/anyOf/0/properties/config/anyOf/0/oneOf/1/properties/details/oneOf/0/properties/waf/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"transport":{"title":"V1LbControllerTransport","description":"Defines how traffic comes in to the load balancer, and how the load balancer handles it.","oneOf":[{"type":["object","null"],"required":["mode","config","routers","disable"],"properties":{"disable":{"description":"When true, this controller is disabled and will not be used.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"mode":{"description":"The kind of traffic (http/tcp/udp) that will be sent to the load balancer.","oneOf":[{"type":"string","enum":["tcp","udp","http"]},{"$ref":"#/properties/about/oneOf/1"}]},"config":{"description":"Defines how the transport for this controller operates.","oneOf":[{"type":"object","required":["performance","ingress","timeouts","verbosity"],"properties":{"performance":{"description":"Enable/disable performance mode. If enabled, some telemetry will be disabled to dedicate full processing to handling requests.\nYou will not see per-request breakdowns or URL logging if performance mode is enabled.\n","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"ingress":{"description":"Defines how traffic gets into the load balancer.","oneOf":[{"type":"object","properties":{"tls":{"oneOf":[{"type":["object","null"],"required":["enable"],"properties":{"enable":{"description":"Enables or disables TLS.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"timeouts":{"description":"Defines settings for various types of timeouts.","oneOf":[{"type":"object","required":["idle"],"properties":{"idle":{"description":"The total amount of time a connection can be idle before being killed.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"verbosity":{"description":"Verbosity describes the level of logging detail for the controller","oneOf":[{"type":"string","enum":["low","normal","high","debug"]},{"$ref":"#/properties/about/oneOf/1"}]},"extension":{"description":"Extended configurations for the specified transport mode (http/tcp)","oneOf":[{"type":"object","discriminator":{"propertyName":"type","mapping":{"tcp":"transports/StackSpecTcpTransportConfig.yml","http":"transports/StackSpecHttpTransportConfig.yml","udp":"transports/StackSpecUdpTransportConfig.yml"}},"oneOf":[{"title":"StackSpecTcpTransportConfig","description":"Additional configuration options for the TCP transport mode.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["tcp"]},"details":{"oneOf":[{"type":"object","required":["connections","telemetry"],"properties":{"connections":{"oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]},"telemetry":{"description":"Configuration options for how telemetry is handled on the load balancer.","oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecHttpTransportConfig","description":"Additional configuration options for the HTTP transport mode.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["http"]},"details":{"oneOf":[{"type":"object","required":["connections","telemetry"],"properties":{"connections":{"oneOf":[{"type":"object","required":["max_idle_conns_per_connection"],"description":"Defines extra configuration options connections to the load balancer","properties":{"max_idle_conns_per_connection":{"oneOf":[{"type":["integer","null"],"description":"Maximum number of simultaneous connections (via http/2) per connection."},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"telemetry":{"oneOf":[{"type":"object","description":"Configuration options for how telemetry is handled.","properties":{"max_trackable_urls":{"description":"Determines how many URLs the load balancer will track at one time. Defaults to 150.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"track_invalid_requests":{"description":"Whether or not to track invalid requests. An invalid request is a request that came in that no router existed for. Usually this means bot requests. Defaults to false.","oneOf":[{"type":["boolean","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"ignore_paths":{"description":"An array of paths to exclude from tracking.","oneOf":[{"type":["array","null"],"items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecUdpTransportConfig","description":"Additional configuration options for the UDP transport mode.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["udp"]},"details":{"oneOf":[{"type":"object","required":["telemetry"],"properties":{"telemetry":{"description":"Configuration options for how telemetry is handled on the load balancer.","oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}}]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"routers":{"description":"Defines where traffic is sent. Many can be defined per controller.","oneOf":[{"type":"array","items":{"oneOf":[{"title":"StackSpecV1LbRouterConfig","description":"A specific router configuration that describes how traffic matching the rule is handled.","type":"object","required":["match","mode","config"],"properties":{"match":{"oneOf":[{"type":"object","description":"The ruleset for this router to be selected. If both `domains`` and `internal_port` are null, then this match acts as a wildcard and will match all.","required":["domains","internal_ports"],"properties":{"domains":{"description":"The specific domains to match against.","oneOf":[{"type":["array","null"],"items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]},"internal_ports":{"description":"The specific ports to match against.","oneOf":[{"type":["array","null"],"items":{"type":"integer"}},{"$ref":"#/properties/about/oneOf/1"}]},"path":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"containers":{"description":"Match traffic destined (or not destined) for a particular container.","oneOf":[{"type":["object","null"],"properties":{"include":{"description":"Match any traffic that would be routed to one of these containers.","oneOf":[{"type":["array","null"],"items":{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/config/oneOf/0/properties/integrations/anyOf/0/properties/backups/oneOf/0/properties/integration_id/oneOf/0"}},{"$ref":"#/properties/about/oneOf/1"}]},"exclude":{"description":"Match any traffic that would NOT be routed to one of these containers.","oneOf":[{"type":["array","null"],"items":{"$ref":"#/properties/containers/oneOf/0/additionalProperties/properties/config/oneOf/0/properties/integrations/anyOf/0/properties/backups/oneOf/0/properties/integration_id/oneOf/0"}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"mode":{"description":"How to route the traffic to the destination.\n`random`: Pick a valid destination at random.\n`round-robin`: Send each request to the 'next' destination on the list, restarting from the beginning when the last destination is used.\n`source-ip`: Utilizes a hash function to ensure traffic from an IP will always hit the same destination instance.\n","oneOf":[{"type":"string","enum":["random","round-robin","source-ip"]},{"$ref":"#/properties/about/oneOf/1"}]},"config":{"oneOf":[{"type":"object","required":["sticky_sessions","destination_retries","timeouts"],"properties":{"sticky_sessions":{"description":"If a request comes in from the same origin, ensure it hits the same destination.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"destination_retries":{"description":"If a destination is unavailable, retry up to [x] times, instead of immediately failing with a 503/504 error.","oneOf":[{"type":"integer"},{"$ref":"#/properties/about/oneOf/1"}]},"destination_prioritization":{"oneOf":[{"type":"string","description":"Hints to the load balancer how to prioritize traffic to instances.\n**random**: Chooses a random instance. **latency**: Prioritizes lower latency instances. **fixed**: The order of the destinations will be the same regardless of instance or load balancer location.  Used primarily with source IP routing.\n","enum":["latency","random","fixed"]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"tls":{"description":"TLS termination configuration. If null, the platform will use the default configuration. Port 443 by default has TLS termination enabled.","oneOf":[{"type":["object","null"],"properties":{"server_name":{"description":"[Advanced] Change the domain the controller listens on.\n","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"allow_insecure":{"description":"If enabled, accept TLS traffic with an invalid certificate. This is usually done for development/testing, and is not recommended for production use.","oneOf":[{"type":["boolean","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"client_cert_auth":{"description":"A PEM encoded string of certificates.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"client_auth":{"description":"Defines how to validate the connecting TLS certificate.\n`none`: Do not require a TLS certificate to be sent\n`request`: Asks the client to send a TLS certificate, but does not require nor validate it.\n`require`: Requires a certificate be sent for the request to be valid, but does not validate the certificate.\n`require-verify`: Requires both that the client send a certificate, and that the certificate is valid. This is required when using https.\n","oneOf":[{"type":"string","enum":["none","request","require","require-verify"]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"timeouts":{"description":"Defines how the length of various sorts of timeouts when communicating with the destination.","oneOf":[{"type":"object","required":["destination_connection"],"properties":{"destination_connection":{"description":"The duration the load balancer will wait before timing out while attempting to connect to the destination.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"extension":{"anyOf":[{"type":"null"},{"type":"object","description":"Additional configuration options specific to the selected mode (tcp/http).","discriminator":{"propertyName":"type","mapping":{"tcp":"routers/StackSpecTcpRouterConfig.yml","udp":"routers/StackSpecUdpRouterConfig.yml","http":"routers/StackSpecHttpRouterConfig.yml"}},"oneOf":[{"title":"StackSpecTcpRouterConfig","description":"Additional configuration options for TCP mode routers","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["tcp"]},"details":{"oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecHttpRouterConfig","description":"Additional configuration options for HTTP mode routers.","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["http"]},"details":{"oneOf":[{"type":"object","properties":{"redirect":{"description":"Defines a built-in redirect for HTTP mode routers","oneOf":[{"type":["object","null"],"required":["auto_https_redirect","remove_www"],"properties":{"auto_https_redirect":{"description":"If enabled and a sibling controller exists for port 443, requests will be auto redirected to it. Essentially sets up automatic TLS redirection for this router.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"remove_www":{"description":"If true, any request comes in with \"www\" prefix will be permanently redirected to the same path without www.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"port":{"description":"The port to redirect traffic to.","oneOf":[{"type":["integer","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"scheme":{"description":"The scheme to redirect to. (i.e. `https`)","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"url":{"description":"A specific URL to redirect to.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"forward":{"oneOf":[{"type":["object","null"],"properties":{"scheme":{"oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"content_mod":{"description":"Allows the load balancer to modify content before it reaches the user.","oneOf":[{"type":["object","null"],"properties":{"replace":{"description":"An array that describes a list of replacement match/value pairs.","oneOf":[{"type":["array","null"],"items":{"oneOf":[{"type":"object","required":["match","value"],"properties":{"match":{"description":"String that will be replaced.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"value":{"description":"Replacement value.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"url":{"description":"The URL to forward the request to.\n\nGiven a path match of `^/example/(.*)$`, a route such as `/example/wow.jpg` would be forwarded as /wow.jpg.\n","examples":["/$$1"],"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"proxy":{"oneOf":[{"type":["object","null"],"properties":{"domain":{"description":"The domain that this router will proxy.","oneOf":[{"type":["string","null"]},{"$ref":"#/properties/about/oneOf/1"}]},"url":{"description":"The full URL that this router will proxy.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"content_mod":{"description":"Allows the load balancer to modify content before it reaches the user.","oneOf":[{"type":["object","null"],"properties":{"replace":{"description":"An array that describes a list of replacement match/value pairs.","oneOf":[{"type":["array","null"],"items":{"oneOf":[{"type":"object","required":["match","value"],"properties":{"match":{"description":"String that will be replaced.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"value":{"description":"Replacement value.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"caching":{"oneOf":[{"type":["object","null"],"properties":{"files":{"oneOf":[{"type":["array","null"],"items":{"oneOf":[{"type":"object","required":["match","ttl"],"properties":{"match":{"description":"Regex string that describes the files to cache.","examples":["(.*)\\.(js|jpg|css|png|svg)$"],"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"ttl":{"description":"Time string that describes the time to live.","oneOf":[{"$ref":"#/properties/scoped_variables/oneOf/0/items/properties/access/oneOf/0/properties/internal_api/oneOf/0/properties/duration/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecUdpRouterConfig","description":"Additional configuration options for UDP mode routers","type":"object","required":["type","details"],"properties":{"type":{"type":"string","enum":["udp"]},"details":{"oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]}}}]}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"waf":{"anyOf":[{"title":"StackSpecWafConfig","type":"object","description":"Additional configuration options for the web application firewall.","required":["rules"],"properties":{"rules":{"oneOf":[{"type":"array","items":{"oneOf":[{"type":"object","required":["description","skip","type","conditions"],"properties":{"description":{"description":"Some information about the rule.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"skip":{"description":"A boolean that indicates if the rule should be active or skipped.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"type":{"description":"A string that describes if the role should allow or deny traffic based on the conditions.","oneOf":[{"type":"string","enum":["allow","deny"]},{"$ref":"#/properties/about/oneOf/1"}]},"expires":{"description":"The expiration date of the WAF config, if present.","oneOf":[{"type":"string","format":"date-time","examples":["2021-01-30T08:30:00Z"]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"match":{"description":"A string that describes if both attributes need to be true (match all) or if only one of the conditions needs to be true (match any).","oneOf":[{"type":"string","enum":["any","all"]},{"$ref":"#/properties/about/oneOf/1"}]},"conditions":{"description":"An array of the specific conditions for the rule.","oneOf":[{"type":"array","items":{"oneOf":[{"type":"object","required":["type","operator","value"],"properties":{"type":{"description":"A string that describes the match type for the condition.","oneOf":[{"type":"string","enum":["ip-match","geo-match","url-match","method-match","header-match"]},{"$ref":"#/properties/about/oneOf/1"}]},"operator":{"description":"A string that indicates the range of values relative to the value property.","oneOf":[{"type":"string","enum":["==","!=",">","<",">=","<="]},{"$ref":"#/properties/about/oneOf/1"}]},"value":{"description":"The value corresponding to the condition type.","examples":["0.0.0.0/0"],"oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"title":"StackSpecDefaultLbType","type":"object","required":["type","details","ipv4","ipv6"],"properties":{"ipv4":{"type":"boolean","description":"Allow / disallow traffic to be routed via IPv4."},"ipv6":{"type":"boolean","description":"Allow / disallow traffic to be routed via IPv6."},"type":{"type":"string","enum":["default"]},"details":{"oneOf":[{"$ref":"#/properties/services/oneOf/0/properties/loadbalancer/anyOf/0/properties/config/anyOf/0/oneOf/0/properties/details/anyOf/0"},{"$ref":"#/properties/services/oneOf/0/properties/loadbalancer/anyOf/0/properties/config/anyOf/0/oneOf/1/properties/details/oneOf/0"},{"type":"null"}]}}}]},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"scheduler":{"anyOf":[{"title":"StackSpecSchedulerService","description":"Configuration options for the scheduler service.","type":"object","additionalProperties":false,"properties":{"service":{"anyOf":[{"$ref":"#/properties/services/oneOf/0/properties/vpn/anyOf/0/properties/service/anyOf/0"},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"config":{"anyOf":[{"title":"StackSpecSchedulerConfig","description":"Scheduler specific configuration options.","type":["object","null"],"required":["public"],"properties":{"public":{"description":"If true, this scheduler will be accessible over the public internet. It will enable a LINKED record to be pointed to the scheduler container, and inbound requests to trigger function containers.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"access_keys":{"oneOf":[{"type":"array","items":{"title":"StackSpecSchedulerAccessKey","description":"Custom authorization keys for the scheduler service.","type":"object","required":["name","secret"],"properties":{"name":{"description":"The name given to this access key.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"secret":{"description":"The access key secret. This should be submitted with requests to a publicly accessible scheduler service.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"ips":{"description":"Whitelisted IPs that are allowed to make requests to the scheduler service.","oneOf":[{"type":"array","items":{"type":"string"}},{"$ref":"#/properties/about/oneOf/1"}]}}}},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"vpn":{"anyOf":[{"title":"StackSpecVpnService","description":"Configuration options for the VPN service.","type":"object","additionalProperties":false,"properties":{"service":{"anyOf":[{"title":"StackService","description":"Stack spec configuration options common to all environment services. If one of these properties is defined, all must be.","type":"object","properties":{"enable":{"description":"Whether or not this service should be enabled.","type":"boolean"},"high_availability":{"description":"Whether or not Cycle should run multiple instances of this service for high availability.","type":"boolean"},"auto_update":{"description":"Whether or not Cycle should automatically update this service when a new version is released.","type":"boolean"}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]},"config":{"anyOf":[{"title":"StackSpecVpnConfig","description":"VPN specific configuraiton options.","type":"object","required":["auth","allow_internet"],"properties":{"auth":{"oneOf":[{"type":"object","required":["cycle_accounts","vpn_accounts"],"properties":{"webhook":{"description":"The endpoint to hit when attempting to authorize a VPN account. If the endpoint returns a 200 response, access is granted. Otherwise it is denied.","oneOf":[{"type":"string"},{"$ref":"#/properties/about/oneOf/1"}]},"cycle_accounts":{"description":"If true, any account with access to this environment on Cycle can use their Cycle credentials to log in to this VPN.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]},"vpn_accounts":{"description":"If true, Cycle will allow custom accounts to be created for logging into this VPN.","oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"allow_internet":{"oneOf":[{"type":"boolean"},{"$ref":"#/properties/about/oneOf/1"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"},{"type":"null"}]}}},{"$ref":"#/properties/about/oneOf/1"}]},"annotations":{"description":"Additional meta info about the stack.","oneOf":[{"type":"object","additionalProperties":{}},{"$ref":"#/properties/about/oneOf/1"}]}}}
</schema>

[User] Provide a JSON object that satisfies the schema "StackSpec". Here are the required top‑level fields: version, containers. Return only the valid JSON object.

StackSpec

A Cycle stack file is an "environment as code". This allows an environment to be generated consistently based on a fixed specification.
Stack files can describe multiple containers and their configurations, environment service settings, scoped variables, and important metadata.

The version of the Cycle stack file used.

A custom, user-defined version of the stack.

Custom, user-defined details about this stack.

StackVariable

A variable specified in a stack spec.

Describes variables that are assigned to one or more containers at runtime. Can be assigned as an environment variable, written as a file inside the container(s), or accessed over the internal API.

StackSpecScopedVariable

Identifier

A human-readable identifier used to refer to a resource, where using the official ID may be inconvenient.
The identifier is automatically tokenized from the name/relevant field of the resource if one is not provided. For example, a container named "My Container" will
have the identifier of `my-container` and is automatically created by the platform.

The identifier does not have to be unique.

Describes the containers that have access to this scoped variable.

If true, all containers in the environment will have access to this variable.

A list of container IDs that are granted access to this variable.

A list of container identifiers that are granted access to this variable.

Grants access to this variable from within a container as an environment variable.

The environment variable inside the container that stores the value of the variable.

Grants access to this variable over the Internal API.

Sets the duration that this variable can be accessed over the Internal API, after container start. Provides additional security as sensitive data can only be accessed for a limited time.

Duration

A string signifying a duration of time. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h", "d", "w", "y".

Grants access to this variable as a file inside the container.

When true, Cycle will interpret this variable as a base-64 encoded string, and decode it before writing it to the file inside the container.

The absolute path to write the variable to (including file name). If `null`, it will be written to `/var/run/cycle/variables/{variable-identifier}`.

A linux file mode that will be set on the injected file.

The linux UID to set on the file.

The linux GID to set on the file.

Describes the source/value of the variable.
- **raw**: Directly set the value of the variable in the stack. - **url**: Cycle will fetch the variable content from a remote source when the container starts.

StackSpecScopedVariableUrlSource

A variable who's value is fetched from a URL when the container starts.

The type of scoped variable.

The URL to call to fetch the value.

Additional headers that can be attached to the URL request. Useful for adding meta-data to third-party services.

A URL that can be provided to authenticate with a third party secret service. Cycle will make a request to this URL before fetching the secret URL, and use the response as the value of an Authorization header when requesting the secret.

StackSpecScopedVariableRawSource

A variable with a hard-coded value.

The type of scoped variable.

The value of the variable.

A boolean where true represents the text the user is entering will be multi line.

A string describing the IV Hex associated with the encryption of the variable.

A user specified hint that will suggest what the encryption key might be

A mapping of containers that will be deployed as a part of this stack. The key is used as the container's identifier.

StackSpecContainer

A container template defined within a stack.

The human-readable name of this container.

Details about the image used for this container.

StackSpecContainerImage

The human-readable name of this image.

Instructions on how to fetch or build this image.

StackSpecImageOrigin

The origin of the image.

DockerHubOrigin

An image origin where the image is pulled from DockerHub.

The DockerHub target string. ex - `mysql:5.7`

For authentication, a username.

For authentication, a token.

DockerFileOrigin

An image origin where the image is built from a Dockerfile located in a git repository.

RepoSourceType

Information about the repository.

The URL of the repository.

An optional branch arguement.  Default value is `master`.

Authentication information for the repository.

HTTPSourceCredentials

Authentication credentails for the Dockerfile image source type when authenticating over HTTP.

For authentication, the username.

For authentication, the password.

SSHSourceCredentials

Authentication credentials for the Dockerfile image source type when authenticating with SSH.

The username for the repo service, that is used to authenticate an ssh key.

The passphrase used for the key.

A pem encoded private key.

Repository reference information.

The type of reference being used.

The value for the given reference type.

An endpoint that serves the tar file.

The path to the directory to use as the context when building the image.

The path to the Dockerfile to be used for buiding the image.

DockerfileCredentails

An array of credentials objects to be used when authenticating against private images used by the Dockerfile.

Credentials object used for authentication of indirect resources such as private parent images.

The url the resource is located at.

A username for authentication.

A token for authentication.

DockerRegistryOrigin

An image origin where the image is pulled from a private Docker registry.

ExistingSource

In a stack, specifies an image source ID from which Cycle will derive any values not specified in the stack file. This is useful for avoiding direct placement of credentials in a stack file, for example.

The ID of the image source this image should be built from.

The image name on the registry.

The url of the remote registry.

For authentication, a username.

For authentication, a token.

For authentication, a password.

OciRegistryOrigin

An image origin that pulls images fro an OCI-compatible registry. Also used for provider-native registries, such as AWS ECR.

The image name on the registry.

The url of the remote registry.

RegistryAuth

Authentication details for a third party image registry/source.

RegistryAuthUser

User/token based credentials for authentication to a third-party image source.

RegistryAuthProvider

Credentials for authentication to a provider-native image registry, such as AWS ECR.

RegistryAuthProviderCredentials

A base64'd string of additional configuration options.

RegistryAuthWebhook

Webhook-based authentication to the provided URL. This webhook expects to receive a base-64 string that when decoded is in the format `username:password`

CycleSourceOrigin

An image origin that references an image source on Cycle.

This origin will never be embedded in an image source. It is for use in stacks, describing an image which is already a part of an image source on Cycle.

The ID referencing the image source where this image originated.

ID

Additional details applied when building an image.

A map of build arguments applied to the image at build time.

A specific builder to use. By default, Cycle uses its factory service and a standard build command to build images, but this can be enhanced by using an image builder integration.

The ID of the integration to use when building the image. The integration must support image building to be compatible.

Additional user-provided meta data about the container.

Whether or not to mark the container as stateful when deployed. Stateful containers can utilize volumes (stateful data) and are generally used for running databases or other data management applications.

Configuration options for this container that will be applied when deployed as part of the stack.

StackContainerConfig

StackSpecContainerConfigNetwork

Stack configuration options related to the container's network.

The level of public network access this container should have.

The hostname of the container. This is how it can be referenced by other containers in the same environment.

A list of port mappings on this container.

StackSpecContainerConfigDeploy

Stack configuration options related to how the container behaves over its lifecycle (startup, shutdown, health checks, etc).

The number of desired instances to deploy.

The strategy Cycle will apply when deploying instances of this container.

- ** resource-density **: Cycle will distribute instances across servers to maintain balanced resource usage.
- ** high-availability **: Cycle will deploy instances across servers with an emphasis on geographic and physical separation. Requires multiple locations.
- ** distributed **: Cycle will deploy instances across servers with an emphasis on physical separation. Does not require multiple locations.
- ** first-available **: Cycle will deploy one instance to every server that matches the specified criteria. (default)
- ** node **: Cycle will deploy one instance to every server that matches the specified criteria.
- ** edge **: Cycle will prioritize geographic distribution of instances.
- ** function **: Every ingress request/connection receives its own instance.
- ** manual **: Cycle will not make any decisions on where instances are deployed. Instead, instances must be deployed manually using the portal or API.

resource-density manual high-availability first-available node edge function

Configuration options for containers using the 'function' deployment strategy.

The maximum number of instances that Cycle can pre-allocate (includes auto-scaled instances).

For each shard (scheduler), the maximum number of tasks it can run in parallel.

The maximum amount of time a function instance can run before timing out.

The maximum amount of time Cycle will wait for an instance to be available.

Configuration options for stateful containers.

Stateful container options.

When enabled, instances will utilize stateless base hostnames instead of being prefixed with a unique ID.

Configuration options that provide the ability to set restrictions on which nodes instances of this container are able to be deployed to. (i.e. if you have a GPU container, it should only go on nodes with a GPU).

Tags applied to a node. Cycle generates some automatically, but additional, custom tags can be applied on a per-node basis.

If a node has at least one of these tags, it is considered a valid deployment target for this container.

A node must have **ALL** of these tags to be considered a valid deployment target for this container.

Configuration options for how this container behaves during shutdown.

How long the platform will wait for a container to stop gracefully.

Signals that should be sent to the container on shutdown.

ShutdownSignal

Process signals that Cycle can be configured to send to the container on a shutdown event.

SIGTERM SIGINT SIGUSR1 SIGUSR2 SIGHUP SIGQUIT

Configuration options for how this container behaves during startup.

How long the platform will wait before sending the start signal to the given container.

Configurations for how the container behaves during updates.

When set, Cycle will pick a random time from `0 - this duration`, and stagger the instances so they all start at different times (up to the time specified here).

Configuration options for how Cycle should handle restarting this container (i.e. in case the process inside the container dies).

Under what circumstances Cycle should try to restart this container.

How long the platform will wait between restart attempts.

The maximum number of restart attempts Cycle will make.

Configuration options for automated container health checks.

command retries interval timeout restart

The command or script to run to verify the health of the container. This script is run inside the container by Cycle.
This command accepts two types of entries:
- The first is a reference to a script that already lives in the container filesystem. This can be defined by giving the full path to the script as the value.   - The second format is an inline script.  If you need the code to execute within a shell, wrap the commands in escaped quotes like this `"\"curl -s -o /dev/console -w \"%{http_code}\" http://localhost:3000/_health | grep '200'  && exit 0 || exit 1\""`.  Do not use the `/bin/sh -c <commands>` format, this will not be accepted.

The number of times to retry the command before marking an instance unhealthy.

How long to wait between running health checks.

How long before a health check attempt times out.

A boolean where true represents the desire for the container to restart if any instance is unhealthy.

How long to wait after a container start event before running health checks.

Configuration options for how the instance telemetry (CPU usage, etc) is handled.

How long telemetry data should be retained.

The duration between samples.

A URL where Cycle will send telemetry data to. The payload will be an instance resource snapshot.

If true, Cycle will not aggregate telemetry for this container's instances.

Configuration options for auto-scaling.

StackSpecContainerConfigScaling

Stack configuration options for auto-scaling.

autoscale_group instances window thresholds

The identifier of the auto-scaling group assigned to this container. The auto-scale group determines which infrastructure this container can spin up if it needs more resources to meet demand. Setting it to `null` will limit auto-scaling to only instances.

Describes the criteria for deploying new instances when an auto-scale criteria is met.

Maximum additional instances the auto-scaler will run at any time.

Minimum number of instances per server.

Minimum amount of time an instance will live.

Duration in which the auto-scaler will watch for changes.

An array of rules that dictate when a scaling event will be triggered.

StackSpecContainerScaleThreshold

Discriminated union describing the different types of scaling threshold and their respective details

StackSpecContainerScaleThresholdRam

Describes the RAM threshold at which scaling will occur.

The target average RAM usage of all instances of this container. Going above this threshold will trigger a scaling event. This threshold must be greater than 25MB.

StackSpecContainerScaleThresholdCpu

Describes the CPU threshold at which scaling will occur.

StackSpecContainerScaleThresholdNetworkConnections

Describes the network connections threshold at which scaling will occur.

StackSpecContainerScaleThresholdNetworkRequests

Describes the network requests threshold at which scaling will occur.

StackSpecContainerScaleThresholdNetworkThroughput

Describes the network throughput threshold at which scaling will occur.

The limit (maximum) amount of throughput each instance of the given container can use before triggering a scaling event.

StackSpecContainerConfigRuntime

Configuration options related to how the container behaves while it is running (environment variables, command overrides, kernel capabilities, etc. )

The working directory to execute the command in.

The command to execute when this container starts. Will override the default specified in the container.

A map of environment variables that will be injected into the container.

Container namespaces to apply. By default, all are applied. Removing/changing this can have security implications.

Sysctl options to apply.

RLIMIT options to apply.

Configuration options for seccomp. Cycle enables seccomp by default.

Configuration options regarding the underlying host.

If true, Cycle will mount the `/proc` directory into the container, giving it access to the host metrics. This is useful if you're running i.e. a monitoring agent.

If true, Cycle will mount the host's `/sys/fs/cgroups` directory into the container at `/var/run/cycle/host/cgroups`.

If true, Cycle will give the container instances access via internal api to power off or reboot the host server.

If true, the container process will run in fully-privileged mode. **WARNING** This is considered insecure, and should only be done if you know what you're doing.

Additional Linux kernel capabilities to apply to this container process.

Configuration options for the root filesystem.

If true, the container's filesystem will be read-only.

StackSpecContainerConfigResources

Configuration options for container resource limits and reserves.

StackSpecContainerConfigIntegrations

Configuration options for additional integrations/features that Cycle provides.

Enable additional webhooks that Cycle will call out to during the course of a container's lifetime. All webhooks send a payload as an object containing the instance, container, server, and environment IDs.

Webhooks that are triggered during a container event.

Cycle will call this endpoint when the container is deployed.

Cycle will call this endpoint when the container is started.

Cycle will call this endpoint when the container is stopped.

The webhook to hit when the container's configuration is changed.

When enabled, this integration will configure Let's Encrypt certificates that will be injected into the container at runtime. The certificates will be managed by the platform and renewed automatically.

When enabled, Cycle will fetch and inject remote files into the container at the specified destination during runtime.

When enabled, Cycle will automatically manage backups of this container. This is only available for stateful containers.

An identifier of an integration that supports backups. All backups will be sent to this destination.

HybridIdentifier

Either a resource ID (objectid - i.e. 651586fca6078e98982dbd90) or a resource Identifier (human-readable)

Configuration options for how the container should be backed up.

The command to run to capture a backup. The output sent to `STDOUT` will be captured and sent to the specified integration.

How long the backup will attempt to run before timing out.

A cron string describing how often to run the backup command.

Configuration options for how the backup should be restored.

The time in seconds for the restore to attempt to complete before timing out.

How long the platform will keep backups. Default is 1 year.

When enabled, Cycle will mount a shared host directory into this container. The directory will be shared with all other containers that mount it.

The role applied to this container. **Not yet implemented**

A list of configurations for volumes that will be attached to the container. Only applicable if the container is set to `stateful`.

StackSpecContainerVolume

A container volume configuration.

Configuration options for local volumes.

The maximum size this volume can grow to. Container volumes on Cycle are thinly provisioned, meaning this isn't an allocation - the volume will only use the space it needs up to this size.

A boolean where true signifies using the largest drive over 2TB for the target server.

The path this volume should be mounted at inside the container.

If true, the container will be unable to write data to the volume.

Indicates that the volume will be used as unformatted block storage.

Configuration options for setting up remote access to this volume via SFTP.

If true, this volume will be accessible over SFTP.

A list of IPs that SFTP access will be limited to.

If set, Cycle will call out to this URL for authentication. Anything other than a 200 response will be considered a validation failure.

The password used for logging in to this volume via SFTP.

The algorithm the password is encoded with. `raw` means the password is plain-text.

The password string.

If true, the container is marked as `deprecated`, and cannot be started anymore. Deprecated containers also don't count toward resource utilization.

If true, the container is marked as `locked` and cannot be deleted in any way until the lock is lifted.

Monitoring options for containers within this stack.

StackSpecMonitoringConfig

Monitoring options for the stack build & containers within this stack.

StackSpecMonitoringLogs

Log configuration for containers in this stack.

When enabled, log drain allows logs to be exported to a third party service.

The URL to the third party logging service where logs will be sent.

The format Cycle will use to send the logs.

Settings for any auxillary services deployed as part of the environment, such as load balancer and discovery services.

StackSpecServices

StackSpecDiscoveryService

Configuration options for the discovery service.

StackSpecDiscoveryConfig

When enabled, discovery will return both IPv6 and IPv4 when in legacy mode.  Otherwise, only IPv4 will be returned.

A custom mapping of hosts - for forced resolution of specific IPs for a domain.

A list of custom DNS resolver strings.  Can specifify domains or ips.

StackSpecLoadBalancerService

Configuration options for the load balancer service.

StackSpecLoadBalancerConfig

The config object for the loadbalancer service.

StackSpecHaProxyLbType

Allow / disallow traffic to be routed via IPv4.

Allow / disallow traffic to be routed via IPv6.

StackSpecHaProxyConfig

Describes settings that are passed to HAProxy within the load balancer.

Settings that are applied to any port that is not overridden in the following ports section.

StackSpecHAProxyConfigSet

Settings that describe how incoming traffic to the load balancer is handled.

The type of traffic expected by the load balancer for this port. Can be either:
 - tcp: Traffic is forwarded without any parsing or additional manipulation.
 - http: Traffic is treated as web traffic. If a LINKED record is configured for a container exposing this port, the domain will be parsed and it will be forwarded to the proper container. This allows multiple services to run on port 80 in the same environment.

The number of simultaneous connections that can be processed at a time.

Various options for handling timeouts when communicating with the client.

The number of seconds the load balancer will wait for a response from a client before disconnecting.

The number of milliseconds the load balancer will wait for a client to send it data when one direction is already closed. This is particularly useful to avoid keeping connections in a waiting state for too long when clients do not disconnect cleanly.

The number of milliseconds the load balancer will wait for a new HTTP request to start coming after a response was set. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20http-request) for more information. (`http` mode only)

The number of milliseconds the load balancer will wait for a complete HTTP request. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20http-request) for more information. (`http` mode only)

Settings related to how the load balancer routes connections to container instances.

How connections are balanced across your container instances. Can be one of the following:
 - `roundrobin`: Each container instance is used in turns.
 - `static-rr`: Each container instance is used in turns, but is faster than Round Robin at the expense of being less dynamic.
 - `leastconn`: Routes traffic to the instance with the least number of active connections.
 - `first`: Routes traffic to the first available instance.
 - `source`: The same client IP always reaches the same container instance as long as no instance goes down or up.

roundrobin static-rr leastconn first source

Various options for handling timeouts when communicating with a container instance behind the load balancer.

The number of seconds the load balancer will wait for a response from the container instance. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-timeout%20server) for more information.

The number of milliseconds the load balancer will wait for the server to send data when one direction is already closed. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20server-fin) for more information.

The number of milliseconds the load balancer will wait for a successful connection to a container instance. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20connect) for more information.

The number of milliseconds the load balancer will hold connections in a queue when the maximum number of connections has been reached. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20queue) for more information.

The number of milliseconds the load balancer will allow for inactivity on a bidirectional tunnel. See the [HAProxy Docs](https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4-timeout%20tunnel) for more information.

An object that defines how HAProxy will act on a specific port. The key is a custom port, and the value is the same settings object found under `default` above.

StackSpecV1LbType

Allow / disallow traffic to be routed via IPv4.

Allow / disallow traffic to be routed via IPv6.

StackSpecV1LbConfig

A configuration for a specific port.

A human-readable identifier for this controller. It will default to the port, i.e. `port-443`, but can be renamed to anything, such as the service this controller represents.

The port inbound trafic is accepted on.

Defines how traffic comes in to the load balancer, and how the load balancer handles it.

When true, this controller is disabled and will not be used.

The kind of traffic (http/tcp/udp) that will be sent to the load balancer.

Defines how the transport for this controller operates.

Enable/disable performance mode. If enabled, some telemetry will be disabled to dedicate full processing to handling requests.
You will not see per-request breakdowns or URL logging if performance mode is enabled.

Defines how traffic gets into the load balancer.

Enables or disables TLS.

Defines settings for various types of timeouts.

The total amount of time a connection can be idle before being killed.

Verbosity describes the level of logging detail for the controller

Extended configurations for the specified transport mode (http/tcp)

StackSpecTcpTransportConfig

Additional configuration options for the TCP transport mode.

Configuration options for how telemetry is handled on the load balancer.

StackSpecHttpTransportConfig

Additional configuration options for the HTTP transport mode.

Defines extra configuration options connections to the load balancer

Maximum number of simultaneous connections (via http/2) per connection.

Configuration options for how telemetry is handled.

Determines how many URLs the load balancer will track at one time. Defaults to 150.

Whether or not to track invalid requests. An invalid request is a request that came in that no router existed for. Usually this means bot requests. Defaults to false.

An array of paths to exclude from tracking.

StackSpecUdpTransportConfig

Additional configuration options for the UDP transport mode.

Defines where traffic is sent. Many can be defined per controller.

A specific router configuration that describes how traffic matching the rule is handled.

The ruleset for this router to be selected. If both `domains`` and `internal_port` are null, then this match acts as a wildcard and will match all.

The specific domains to match against.

The specific ports to match against.

Match traffic destined (or not destined) for a particular container.

Match any traffic that would be routed to one of these containers.

Match any traffic that would NOT be routed to one of these containers.

How to route the traffic to the destination.
`random`: Pick a valid destination at random.
`round-robin`: Send each request to the 'next' destination on the list, restarting from the beginning when the last destination is used.
`source-ip`: Utilizes a hash function to ensure traffic from an IP will always hit the same destination instance.

If a request comes in from the same origin, ensure it hits the same destination.

If a destination is unavailable, retry up to [x] times, instead of immediately failing with a 503/504 error.

Hints to the load balancer how to prioritize traffic to instances.
**random**: Chooses a random instance. **latency**: Prioritizes lower latency instances. **fixed**: The order of the destinations will be the same regardless of instance or load balancer location.  Used primarily with source IP routing.

TLS termination configuration. If null, the platform will use the default configuration. Port 443 by default has TLS termination enabled.

[Advanced] Change the domain the controller listens on.

If enabled, accept TLS traffic with an invalid certificate. This is usually done for development/testing, and is not recommended for production use.

A PEM encoded string of certificates.

Defines how to validate the connecting TLS certificate.
`none`: Do not require a TLS certificate to be sent
`request`: Asks the client to send a TLS certificate, but does not require nor validate it.
`require`: Requires a certificate be sent for the request to be valid, but does not validate the certificate.
`require-verify`: Requires both that the client send a certificate, and that the certificate is valid. This is required when using https.

Defines how the length of various sorts of timeouts when communicating with the destination.

The duration the load balancer will wait before timing out while attempting to connect to the destination.

Additional configuration options specific to the selected mode (tcp/http).

StackSpecTcpRouterConfig

Additional configuration options for TCP mode routers

StackSpecHttpRouterConfig

Additional configuration options for HTTP mode routers.

Defines a built-in redirect for HTTP mode routers

If enabled and a sibling controller exists for port 443, requests will be auto redirected to it. Essentially sets up automatic TLS redirection for this router.

If true, any request comes in with "www" prefix will be permanently redirected to the same path without www.

The port to redirect traffic to.

The scheme to redirect to. (i.e. `https`)

A specific URL to redirect to.

Allows the load balancer to modify content before it reaches the user.

An array that describes a list of replacement match/value pairs.

The URL to forward the request to.

Given a path match of `^/example/(.*)$`, a route such as `/example/wow.jpg` would be forwarded as /wow.jpg.

The domain that this router will proxy.

The full URL that this router will proxy.

Regex string that describes the files to cache.

Time string that describes the time to live.

StackSpecUdpRouterConfig

Additional configuration options for UDP mode routers

StackSpecWafConfig

Additional configuration options for the web application firewall.

Some information about the rule.

A boolean that indicates if the rule should be active or skipped.

A string that describes if the role should allow or deny traffic based on the conditions.

The expiration date of the WAF config, if present.

A string that describes if both attributes need to be true (match all) or if only one of the conditions needs to be true (match any).

An array of the specific conditions for the rule.

A string that describes the match type for the condition.

ip-match geo-match url-match method-match header-match

A string that indicates the range of values relative to the value property.

The value corresponding to the condition type.

StackSpecDefaultLbType

Allow / disallow traffic to be routed via IPv4.

Allow / disallow traffic to be routed via IPv6.

StackSpecSchedulerService

Configuration options for the scheduler service.

StackSpecSchedulerConfig

Scheduler specific configuration options.

If true, this scheduler will be accessible over the public internet. It will enable a LINKED record to be pointed to the scheduler container, and inbound requests to trigger function containers.

StackSpecSchedulerAccessKey

Custom authorization keys for the scheduler service.

The name given to this access key.

The access key secret. This should be submitted with requests to a publicly accessible scheduler service.

Whitelisted IPs that are allowed to make requests to the scheduler service.

StackSpecVpnService

Configuration options for the VPN service.

StackService

Stack spec configuration options common to all environment services. If one of these properties is defined, all must be.

Whether or not this service should be enabled.

Whether or not Cycle should run multiple instances of this service for high availability.

Whether or not Cycle should automatically update this service when a new version is released.

StackSpecVpnConfig

VPN specific configuraiton options.

The endpoint to hit when attempting to authorize a VPN account. If the endpoint returns a 200 response, access is granted. Otherwise it is denied.

If true, any account with access to this environment on Cycle can use their Cycle credentials to log in to this VPN.

If true, Cycle will allow custom accounts to be created for logging into this VPN.

Additional meta info about the stack.

Provide a JSON object that satisfies the schema "StackSpec". Here are the required top‑level fields: version, containers. Return only the valid JSON object.