|
| 1 | +# About |
| 2 | + |
| 3 | +The Compose application model defines `service` as an abstraction for a computing unit managing (a subset of) |
| 4 | +application needs, which can interact with other service by relying on network(s). Docker Compose is designed |
| 5 | +to use the Docker Engine ("Moby") API to manage services as containers, but the abstraction _could_ also cover |
| 6 | +many other runtimes, typically cloud services or services natively provided by host. |
| 7 | + |
| 8 | +The Compose extensibility model has been designed to extend the `service` support to runtimes accessible through |
| 9 | +third-party tooling. |
| 10 | + |
| 11 | +# Architecture |
| 12 | + |
| 13 | +Compose extensibility relies on the `provider` attribute to select the actual binary responsible for managing |
| 14 | +the resource(s) needed to run a service. |
| 15 | + |
| 16 | +```yaml |
| 17 | + database: |
| 18 | + provider: |
| 19 | + type: awesomecloud |
| 20 | + options: |
| 21 | + type: mysql |
| 22 | + size: 256 |
| 23 | +``` |
| 24 | +
|
| 25 | +`provider.type` tells Compose the binary to run, which can be either: |
| 26 | +- Another Docker CLI plugin (typically, `model` to run `docker-model`) |
| 27 | +- An executable in user's `PATH` |
| 28 | + |
| 29 | +To be a valid Compose extension, provider command *MUST* accept subcommand `compose` (which can be hidden) |
| 30 | +with subcommands `up` and `down`. |
| 31 | + |
| 32 | +## Up lifecycle |
| 33 | + |
| 34 | +To execute an application's `up` lifecycle, Compose executes the provider's `compose up` command, passing |
| 35 | +the project name, service name and additional options. The `provider.options` are translated |
| 36 | +into command line flags. For example: |
| 37 | +```console |
| 38 | +awesomecloud compose --project-name <NAME> up --type=mysql --size=256 "database" |
| 39 | +``` |
| 40 | + |
| 41 | +> __Note:__ `project-name` _should_ be used by the provider to tag resources |
| 42 | +> set for project, so that later execution with `down` subcommand releases |
| 43 | +> all allocated resources set for the project. |
| 44 | + |
| 45 | +## Communication with Compose |
| 46 | + |
| 47 | +Providers can interact with Compose using `stdout` as a channel, sending JSON line delimited messages. |
| 48 | +JSON messages MUST include a `type` and a `message` attribute. |
| 49 | +```json |
| 50 | +{ "type": "info", "message": "preparing mysql ..." } |
| 51 | +``` |
| 52 | + |
| 53 | +`type` can be either: |
| 54 | +- `info`: Reports status updates to the user. Compose will render message as the service state in the progress UI |
| 55 | +- `error`: Lest the user know something went wrong with details about the error. Compose will render the message as the reason for the service failure. |
| 56 | +- `setenv`: Let's the plugin tell Compose how dependent services can access the created resource. See next section for further details. |
| 57 | + |
| 58 | +```mermaid |
| 59 | +sequenceDiagram |
| 60 | + Shell->>Compose: docker compose up |
| 61 | + Compose->>Provider: compose up --project-name=xx --foo=bar "database" |
| 62 | + Provider--)Compose: json { "info": "pulling 25%" } |
| 63 | + Compose-)Shell: pulling 25% |
| 64 | + Provider--)Compose: json { "info": "pulling 50%" } |
| 65 | + Compose-)Shell: pulling 50% |
| 66 | + Provider--)Compose: json { "info": "pulling 75%" } |
| 67 | + Compose-)Shell: pulling 75% |
| 68 | + Provider--)Compose: json { "setenv": "URL=http://cloud.com/abcd:1234" } |
| 69 | + Compose-)Compose: set DATABASE_URL |
| 70 | + Provider-)Compose: EOF (command complete) exit 0 |
| 71 | + Compose-)Shell: service started |
| 72 | +``` |
| 73 | + |
| 74 | +## Connection to a service managed by a provider |
| 75 | + |
| 76 | +A service in the Compose application can declare dependency on a service managed by an external provider: |
| 77 | + |
| 78 | +```yaml |
| 79 | +services: |
| 80 | + app: |
| 81 | + image: myapp |
| 82 | + depends_on: |
| 83 | + - database |
| 84 | +
|
| 85 | + database: |
| 86 | + provider: |
| 87 | + type: awesomecloud |
| 88 | +``` |
| 89 | + |
| 90 | +When the provider command sends a `setenv` JSON message, Compose injects the specified variable into any dependent service, |
| 91 | +automatically prefixing it with the service name. For example, if `awesomecloud compose up` returns: |
| 92 | +```json |
| 93 | +{"type": "setenv", "message": "URL=https://awesomecloud.com/db:1234"} |
| 94 | +``` |
| 95 | +Then the `app` service, which depends on the service managed by the provider, will receive a `DATABASE_URL` environment variable injected |
| 96 | +into its runtime environment. |
| 97 | + |
| 98 | +> __Note:__ The `compose up` provider command _MUST_ be idempotent. If resource is already running, the command _MUST_ set |
| 99 | +> the same environment variables to ensure consistent configuration of dependent services. |
| 100 | + |
| 101 | +## Down lifecycle |
| 102 | + |
| 103 | +`down` lifecycle is equivalent to `up` with the `<provider> compose --project-name <NAME> down <SERVICE>` command. |
| 104 | +The provider is responsible for releasing all resources associated with the service. |
0 commit comments