Skip to content

Latest commit

 

History

History
250 lines (192 loc) · 9.84 KB

companions.md

File metadata and controls

250 lines (192 loc) · 9.84 KB

Companion Configuration

For better understanding, take a look at Companions section to grasp what a companion is. The following sections provide example configurations for these use cases.

A simple, but limited configuration of companions can be done via the config.toml file for application companions and service companions. More complex companions can be created via bootstrapping.

Static Configuration

Application Wide

If you want to include an OpenID provider for every application, you could use the following configuration:

[companions.openid]
type = 'application'
image = 'private.example.com/library/openid:latest'
env = [ 'KEY=VALUE' ]

The provided values of serviceName and env can include the handlebars syntax in order to access dynamic values.

Additionally, you could mount files that are generated from handlebars templates (example contains a properties generation):

[companions.openid.volumes]
"/path/to/volume.properties" = """
remote.services={{#each services~}}
  {{~#if (eq type 'instance')~}}
    {{name}}:{{port}},
  {{~/if~}}
{{~/each~}}
"""

Furthermore, you can provide labels through handlebars templating:

[companions.openid.labels]
"com.github.prevant" = "bar-{{application.name}}"

Routing

If you need to customize the routing behaviour of companions you can adjust it for companions. For example, Adminer needs some adjustments to accept logins running behind a reverse proxy (which is Traefik).

[companions.adminer]
type = 'application'
image = 'adminer:4.8.1'

[companions.adminer.routing.additionalMiddlewares]
headers = { 'customRequestHeaders' = { 'X-Forwarded-Prefix' =  '/{{application.name}}/adminer' } }

In addition, you can overwrite the whole routing of the companion. For example, if you want to make the Adminer available under /{{application.name}}/adminer/sub-path/ you can provide following configuration.

[companions.adminer]
type = 'application'
image = 'adminer:4.8.1'

[companions.adminer.routing]
rule = 'PathPrefix(`/{{application.name}}/adminer/sub-path`)'

[companions.adminer.routing.additionalMiddlewares]
headers = { 'customRequestHeaders' = { 'X-Forwarded-Prefix' =  '/{{application.name}}/adminer/sub-path' } }
stripPrefix = { 'prefixes' = [ '/{{application.name}}/adminer/sub-path' ] }

Please, note that PREvant in the latter case does not set the StripPrefix Middleware and it needs to be recreated.

Template Variables

The list of available handlebars variables:

  • application: The companion's application information
    • name: The application name
    • baseUrl: The URL that all services in the application share (only available on K8s at the moment)
  • services: An array of the services of the application. Each element has the following structure:
    • name: The service name which is equivalent to the network alias
    • port: The exposed port of the service
    • type: The type of service. For example, instance, replica, app-companion, or service-companion.

Handlebar Helpers

PREvant provides some handlebars helpers which can be used to generate more complex configuration files. See Handlebar's block helper documentation for more details.

  • {{#isCompanion <type>}} A conditional handlerbars block helper that checks if the given service type matches any companion type.
  • isNotCompanion <type> A conditional handlerbars block helper that checks if the given service type does not match any companion type.

Additionally, check out the builtin extra helpers PREvant offers via the Handlebars Rust library.

Service Based

The service-based companions work in the same way as the application-based services. Ensure that the serviceName is unique by using handlebars templating.

[companions.service-name]
serviceName = '{{service.name}}-db'
image = 'postgres:11'
env = [ 'KEY=VALUE' ]

[companions.service-name.postgres.volumes]
"/path/to/volume.properties" == "…"
[companions.openid.labels]
"com.github.prevant" = "bar-{{application.name}}"

Template Variables

The list of available handlebars variables:

  • application: The companion's application information
    • name: The application name
    • baseUrl: The URL that all services in the application share (only available on K8s at the moment)
  • service: The companion's service containing the following fields:
    • name: The service name which is equivalent to the network alias
    • port: The exposed port of the service
    • type: The type of service. For example, instance, replica, app-companion, or service-companion.

Deployment Strategy

Companions offer different deployment strategies, enabling a companion to be restarted or remain running based on specific conditions. Therefore, PREvant offers following configuration flags:

[companions.openid]
type = 'application'
image = 'private.example.com/library/openid:latest'
deploymentStrategy = 'redeploy-on-image-update'

deploymentStrategy offers the following values and if a companion exists for an app, following strategy will be applied:

  • redeploy-always (default): Re-deploys the companion every time there is a new deployment request.
  • redeploy-on-image-update: Re-deploys the companion if there is a newer image version available.
  • redeploy-never: Even if there is a new deployment request the companion won't be redeployed and stays running.

Storage Strategy

Companions may have varying storage requirements and storage strategies cater to these by offering the below configuration flags:

[companions.postgres]
type = 'application'
image = 'postgres:latest'
storageStrategy = 'mount-declared-image-volumes'

storageStrategy offers the following values to determine how storage is managed for a companion:

  • none (default): Companion is deployed without persistent storage.
  • mount-declared-image-volumes: Mounts the volume paths declared within the image, providing persistent storage for the companion.

Bootstrapping From the Infrastructure Backend

When the static configuration is insufficient for your use case, then PREvant can utilize the underlying infrastructure to bootstrap the companion configuration from the stdout of containers that are run once within the infrastructure (depicted by the following image). PREvant's static companion configuration might be insufficient if services of the application rely on volume sharing among services (see #123) or when operations are required to be run at the application's start up, e.g. importing test data.

In the depicted images PREvant will start one or more containers on the infrastructure backend that are expected to generate output on standard out (stdout) that will be parsed by PREvant that needs to be native to the underlying infrastructure.

  • When PREvant uses Kubernetes as the infrastructure runtime, the bootstrap containers need to output Kubernetes manifests.

    Make sure to output YAML that is compatible with 1.1 and 1.2 (For example, bitnami helm charts have been adjusted in part in that regard, see here and here)

  • Docker: not yet implemented but the aim is to support Docker compose files.

Then before deploying these bootstrapped companions PREvant merges them with the objects generated from the HTTP request payload (all bootstrapped companions will be considered as application companions). Thus you can add or overwrite configurations. For example, you can change the image used or an environment variable. If you overwrite any configuration the companion will be turned into an instance.

The following configuration block depicts that an image registry.example.com/user/bootstrap-helm-chart:lastet is based on a Helm chart that generates an OpenID provider for your application with Keycloak. Additionally, it is possible to pass additional arguments to the container than can be templated with Handlebars.

[[companions.bootstrapping.containers]]
image = "registry.example.com/user/bootstrap-helm-chart:latest"
args = [
   "--set", "keycloak.httpRelativePath=/{{application.name}}/keycloak/",
   "--set", "keycloak.redirectUris[0]={{application.baseUrl}}oauth_redir"
]

The list of available handlebars variables for bootstrap container arguments and the container image:

  • application: The companion's application information
    • name: The application name
    • baseUrl: The URL that all services in the application share
  • infrastructure: Holds information that are specific to the underlying infrastructure.
    • 'namespace' (Kubernetes): the name of the namespace where the application will be installed in.

Additionally, check out the builtin extra helpers PREvant offers via the Handlebars Rust library.