Skip to main content

Configure Services

CAP offers a few services that can be deployed or connected with through our config file.

You can always connect to an external service by using environments variables as well. But using CAP simplifies things like framework specific logic and CAP will also handle your migrations when it manages your database connection.

Compatibility

App Deployment Cluster Deployment External Connection Remote Access
MariaDB
PostgreSQL
MySQL
CockroachDB
Dragonfly
RabbitMQ
Mercure
OpenSearch

Any service marked for remote access can be reached with your own client over Cloudbear Mesh; see Remote Access.

MariaDB

To deploy a MariaDB server, define it in your services block. CAP will automatically handle the deployment, including daily backups.

services:
  db:
    type: mariadb
    version: 11.4.5

Options

Property Type Description Default
type string Set to mariadb. None
version string The MariaDB version to run. 11.4.5
replicas integer The number of database nodes. Even numbers are rejected. 3 in production, 1 elsewhere
resources.cpu integer or string CPU allocated to each node. 250m
resources.memory integer or string Memory allocated to each node. 1Gi
resources.storage integer or string Storage allocated to each node. 10Gi
databases string[] Databases created when the service is provisioned. See Predefined databases. []
config string[] Extra server configuration lines, appended to the settings CAP sets. See Server configuration. []
backup.enable boolean Whether backups are taken. See Backups. true
backup.schedule string A cron expression defining when backups run. See YAML Schema Reference. 0 1 * * *
access boolean or object Whether you can reach the service with your own client. See Remote Access. false

Connecting your application

Database connections arrive under the names your framework already reads, so the stock configuration works unchanged. This applies to MariaDB, MySQL, PostgreSQL and CockroachDB alike.

Type Variables
laravel DB_*, plus DB_CONNECTION set to the type of the first database service you defined
symfony DATABASE_URL, including the serverVersion the connection needs
shopware DATABASE_URL, as Symfony
cakephp DATABASE_URL, with the query parameters CakePHP expects appended
whmcs MYSQL_*
others DATABASE_URL

Naming the connection prefixes these variables; see Connections.

CockroachDB is the exception to the credentials part: it accepts connections from your application without a username or password, so its URL carries neither.

Predefined databases

You can create additional databases when the MariaDB service is provisioned.

services:
  db:
    type: mariadb
    databases:
      - my_first_app
      - my_second_app

Server configuration

Every line under config is added to the server's settings, after the ones CAP sets. Use it to override a default or to set an option CAP does not set itself.

services:
  db:
    type: mariadb
    config:
      - max_connections = 2000
      - innodb_lock_wait_timeout = 120

Backups

CAP takes a daily backup of your database services. Set backup.schedule to a cron expression to run them at a different time, or backup.enable to false to turn them off.

Manual setup required. Defining backup in your config.cap.yaml only configures the backup schedule. To ensure your backups are actually stored and restorable, additional manual configuration is required on the Cloudbear platform side. Please contact Cloudbear support to complete the setup for your database backups.

services:
  db:
    type: mariadb
    backup:
      enable: true
      schedule: 0 2 * * *

MySQL

MySQL is not available for deployment directly through CAP, but you can connect to an external MySQL server. See the Connections documentation for more details.

An external MySQL server is declared under connections rather than services, so none of the service options on this page apply to it. Your application receives the same variables as for a MariaDB service; see MariaDB.

CockroachDB and PostgreSQL

To deploy a CockroachDB or PostgreSQL server, define it in your services block.

services:
  pg-database:
    type: postgresql
    version: "17.8"
    backup:
      enable: true
      schedule: "@daily"

PostgreSQL options

Property Type Description Default
type string Set to postgresql. None
version string The PostgreSQL version to run. 17.8
replicas integer The number of database nodes. Even numbers are rejected. 3 in production, 1 elsewhere
resources.cpu integer or string CPU allocated to each node. 250m
resources.memory integer or string Memory allocated to each node. 1Gi
resources.storage integer or string Storage allocated to each node. 10Gi
databases string[] Databases created when the service is provisioned. See Predefined PostgreSQL databases. []
backup.enable boolean Whether backups are taken. See Backups. true
backup.schedule string A cron expression defining when backups run. See YAML Schema Reference. 0 1 * * *
access boolean or object Whether you can reach the service with your own client. See Remote Access. false

CockroachDB options

Property Type Description Default
type string Set to cockroachdb. None
version string The CockroachDB version to run. 24.3.18
replicas integer The number of database nodes. Values below 3, and values that are not a multiple of 3, are rejected. 3
resources.cpu integer or string CPU allocated to each node. 500m
resources.memory integer or string Memory allocated to each node. 2Gi
resources.storage integer or string Storage allocated to each node. 10Gi
backup.enable boolean Whether backups are taken. See Backups. true
backup.schedule string A cron expression defining when backups run. See YAML Schema Reference. 0 1 * * *
access boolean or object Whether you can reach the service with your own client. See Remote Access. false
services:
  crdb:
    type: cockroachdb
    version: 24.3.18
    backup:
      enable: true
      schedule: 0 3 * * *

CockroachDB has no databases option: a database is created for each connection instead.

Predefined PostgreSQL databases

You can create additional databases when the PostgreSQL service is provisioned.

services:
  pg-database:
    type: postgresql
    databases:
      - my_first_app
      - my_second_app

Manual setup required. Like MariaDB, defining backup for PostgreSQL and CockroachDB only configures the backup schedule. Additional manual configuration is required on the Cloudbear platform side to ensure your backups are actually stored and restorable. Please contact Cloudbear support to complete the setup.

Dragonfly

Dragonfly is a modern, in-memory datastore that is compatible with Redis.

services:
  cache:
    type: dragonfly

Options

Property Type Description Default
type string Set to dragonfly. None
version string The Dragonfly version to run. 1.27.1
replicas integer The number of datastore instances. 2 in production, 1 elsewhere
resources.cpu integer or string CPU allocated to each instance. 125m
resources.memory integer or string Memory allocated to each instance. 256Mi
resources.storage integer or string Storage for snapshots. Setting it turns on persistence. See Persistence. None
access boolean or object Whether you can reach the service with your own client. See Remote Access. false

Dragonfly services keep their data in memory only, unless you request storage for them.

Connecting your application

Type Variables
laravel REDIS_URL, plus CACHE_STORE set to redis
cakephp CACHE_DEFAULT_URL for an unnamed connection, CACHE_<name>_URL otherwise
others REDIS_URL

Persistence

By default a Dragonfly service holds its data in memory, and that data is gone when the service restarts. Requesting resources.storage gives each instance storage of its own and Dragonfly starts snapshotting to it: on shutdown, and once an hour while it runs. The snapshot is loaded back on start, so cached data survives restarts and version upgrades.

services:
  cache:
    type: dragonfly
    resources:
      memory: 1Gi
      storage: 2Gi

Size the storage to at least the memory you gave the service, since a snapshot holds the full dataset.

Snapshots are not a backup and not a substitute for replication. A graceful restart loses nothing, but a service that is killed abruptly falls back to its last hourly snapshot. Treat this as a cache that comes back warm, not as a durable store.

RabbitMQ

To deploy a RabbitMQ message broker, define it in your services block. When you connect an application to it, a unique vhost is automatically created for your connection.

services:
  queue:
    type: rabbitmq

Options

Property Type Description Default
type string Set to rabbitmq. None
version string The RabbitMQ version to run. 4.0.7
replicas integer The number of broker nodes. Values other than 1 or a multiple of 3 are rejected. 3 in production, 1 elsewhere
resources.cpu integer or string CPU allocated to each node. 250m
resources.memory integer or string Memory allocated to each node. 2Gi
resources.storage integer or string Storage allocated to each node. 10Gi
vhosts string[] Vhosts created when the service is provisioned. See Predefined vhosts. []
access boolean or object Whether you can reach the service with your own client. See Remote Access. false

Connecting your application

Each connection gets its own vhost, so two applications on one broker stay separate.

Type Variables
laravel RABBITMQ_* as separate values, plus QUEUE_CONNECTION set to rabbitmq
symfony MESSENGER_TRANSPORT_DSN
cakephp RABBITMQ_* as separate values
others RABBITMQ_URL

Predefined vhosts

You can predefine vhosts for your RabbitMQ service.

services:
  queue:
    type: rabbitmq
    vhosts:
      - my_first_vhost
      - my_second_vhost

Mercure

Mercure is a hub for pushing real-time updates to browsers and other clients over Server-Sent Events. Your application publishes an update to the hub, and the hub fans it out to everyone subscribed to that topic.

services:
  hub:
    type: mercure

connections:
  - service: hub

Options

Property Type Description Default
type string Set to mercure. None
version string The hub version to run. 0.24.2
hostname string Serve the hub under your own domain instead of the derived name. See Hostname. derived
replicas integer The number of hub instances. Above 1 requires a transport; see Redundancy. 1
resources.cpu integer or string CPU allocated to each instance. 125m
resources.memory integer or string Memory allocated to each instance. 256Mi
resources.storage integer or string Storage for the update history. See Update history. 1Gi
cors string[] Origins allowed to subscribe from a browser. See Browser subscribers. []
anonymous boolean Allow subscribers without a valid JWT. Only for topics where every subscriber may see every update. false
subscriptions boolean Expose the subscription API and dispatch private updates when a subscription opens or closes. false
transport.service string The name of a dragonfly or postgresql service the instances share. See Redundancy. None

Hostname

Unlike the other services, a hub is reached by browsers, so it gets a public hostname and certificate of its own. By default that is <service>.<environment>.<application>.app.cloudbear.it, which resolves without any DNS work on your side. Set hostname to serve it under your own domain instead, and point a CNAME at the derived name.

services:
  hub:
    type: mercure
    version: 0.24.2
    hostname: mercure.example.com
    resources:
      cpu: 250m
      memory: 512Mi
      storage: 2Gi

Connecting your application

Variable Description
MERCURE_URL Where your application publishes. Private, so updates never leave Cloudbear.
MERCURE_PUBLIC_URL Where browsers subscribe. Use this in anything you send to a client.
MERCURE_PUBLISHER_JWT_KEY Key to sign publisher tokens with.
MERCURE_SUBSCRIBER_JWT_KEY Key to sign subscriber tokens with.

The two keys are generated once and stored for you. They are deliberately different, so a token you hand to a browser to subscribe with cannot also be used to publish.

Type Variables
symfony The above, plus MERCURE_JWT_SECRET, where symfony/mercure reads the publisher key
others The above

Naming the connection prefixes these variables, and you can template the hub's values into names of your own choosing; see Connections.

Browser subscribers

Subscribers connecting from a browser need their origin allowed, otherwise the request is blocked before it reaches the hub:

services:
  hub:
    type: mercure
    cors:
      - https://app.example.com

Update history

A hub keeps recent updates so a client that reconnects can replay what it missed using the Last-Event-ID header. That history is held in the storage sized by resources.storage, 1Gi by default.

Redundancy

By default a hub runs as a single instance, which means a restart briefly interrupts every open connection. Clients reconnect on their own, so this is usually acceptable outside production.

A redundant hub runs several instances that share their updates through a transport, so no single instance is a point of failure and updates published to one reach subscribers on all of them. Point transport.service at a dragonfly or postgresql service to enable it:

services:
  hub:
    type: mercure
    replicas: 3
    transport:
      service: cache

  cache:
    type: dragonfly

Either service type works, and which to pick depends on what the hub is doing:

Transport Update history Subscription API Notes
dragonfly Yes Yes Recommended. Bounded history, lowest overhead.
postgresql Yes No Use when you already run one and want fewer parts.

A postgresql transport gets a database of its own on the service you point it at, separate from any database your application connects to, so it never shares credentials with your application:

services:
  hub:
    type: mercure
    replicas: 3
    transport:
      service: db

  db:
    type: postgresql

No subscription API on PostgreSQL. The subscriptions option needs the transport to track which subscribers are connected, which the PostgreSQL transport does not do. Combining the two leaves subscription events undelivered without reporting an error, so use a dragonfly transport if your application relies on them.

Paid option. Redundancy is only available in the commercial edition of Mercure, so a redundant hub is a paid add-on and has to be enabled by Cloudbear before it will deploy. Contact Cloudbear support to arrange it. Without it, replicas has to stay at 1: a single hub cannot be scaled out, because instances would not see each other's updates.

A redundant hub keeps its update history in the Dragonfly service rather than in its own storage, so resources.storage no longer applies. Note that redundancy covers the hub instances themselves; the Dragonfly service behind them has its own availability.

OpenSearch

OpenSearch is a search and analytics engine. Define it in your services block and CAP deploys it, creates a user for each connection, and grants that user read and write access.

services:
  search:
    type: opensearch

connections:
  - service: search

Options

Property Type Description Default
type string Set to opensearch. None
version string The OpenSearch version to run. 3.7.0
replicas integer The number of nodes in the cluster. Values below 3 are rejected. 3
resources.cpu integer or string CPU allocated to each node. 250m
resources.memory integer or string Memory allocated to each node. 1Gi
resources.storage integer or string Storage allocated to each node. 10Gi
access boolean or object Whether you can reach the service with your own client. See Remote Access. false

The defaults are sized for a small production workload. Override them per service:

services:
  search:
    type: opensearch
    version: 3.7.0
    replicas: 5
    resources:
      cpu: 500m
      memory: 2Gi
      storage: 50Gi

Connecting your application

A connection injects the host, a dedicated user, and an index prefix:

Variable Description
OPENSEARCH_HOST Where to reach OpenSearch. Private to your application.
OPENSEARCH_USERNAME The user created for this connection.
OPENSEARCH_PASSWORD That user's password, read from a secret.
OPENSEARCH_INDEX_PREFIX Prefix your indexes with this to keep them apart from other connections.

Naming the connection prefixes these variables; see Connections.

Some application types get the names their usual client already reads, so the stock configuration works unchanged:

Type Variables
laravel OS_HOSTS, OS_USERNAME, OS_PASSWORD, OS_INDEX_PREFIX
shopware OPENSEARCH_URL, OPENSEARCH_USERNAME, OPENSEARCH_PASSWORD, SHOPWARE_ES_INDEX_PREFIX
cakephp OPENSEARCH_HOST, OPENSEARCH_PORT, OPENSEARCH_USERNAME, OPENSEARCH_PASSWORD, OPENSEARCH_INDEX

Shared services

In some cases, you might want to define a service once and have multiple applications connect to it. This can be achieved using "Shared Services". A shared service is a service that is not tied to a specific application's lifecycle. Unlike regular services, shared services are defined at the project level and do not need to be explicitly declared in your application's config.cap.yaml file to be accessible.

Shared services are defined under the shared.services block in your config.cap.yaml. This separates them from the regular services block, which defines services that are unique to each application deployment.

A shared service takes exactly the same options as the same service under services, so the tables above apply unchanged.

Example

Here's how you might define a shared database that can be used by multiple applications:

shared:
  services:
    shared-db:
      type: mariadb
      version: 11.4.5

To connect to this shared service from your application, you would then use a shared-connection in your connections block, referencing the name of the shared service.

connections:
  - shared: shared-db
    name: db

Learn more about connecting to shared services in the Connections documentation.