{"id":2220,"date":"2025-07-09T16:14:46","date_gmt":"2025-07-09T16:14:46","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/07\/09\/compose-your-way-with-provider-services\/"},"modified":"2025-07-09T16:14:46","modified_gmt":"2025-07-09T16:14:46","slug":"compose-your-way-with-provider-services","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/07\/09\/compose-your-way-with-provider-services\/","title":{"rendered":"Compose your way with Provider services!"},"content":{"rendered":"<p>With the release of Docker Compose v2.36.0, we\u2019re excited to introduce a powerful new feature: <strong>provider services<\/strong>. This extension point opens up Docker Compose to interact not only with containers but also with any kind of external system, all while keeping the familiar Compose file at the center of the workflow.<\/p>\n<p>In this blog post, we\u2019ll walk through what provider services are, how developers can use them to streamline their workflows, how the provider system works behind the scenes, and how you can build your own provider to extend Compose for your platform needs.<\/p>\n\n<p><strong>Why Provider Services Are a Game-Changer<\/strong><\/p>\n\n<p>Docker Compose has long been a favorite among developers for orchestrating multi-container applications in a simple and declarative way. But as development environments have become more complex, the need to integrate non-container dependencies has become a common challenge. Applications often rely on managed databases, SaaS APIs, cloud-hosted message queues, VPN tunnels, or LLM inference engines \u2014 all of which traditionally sit outside the scope of Compose.<\/p>\n<p>Developers have had to resort to shell scripts, Makefiles, or wrapper CLIs to manage these external components, fragmenting the developer experience and making it harder to onboard new contributors or maintain consistent workflows across teams.<\/p>\n<p><strong>Provider services change that<\/strong>. By introducing a native extension point into the Compose, developers can now define and manage external resources directly in their compose.yaml. Compose delegates their lifecycle to the provider binary, coordinating with it as part of its own service lifecycle.<\/p>\n\n<p>This makes Docker Compose a more complete solution for full-stack, platform-aware development \u2014 from local environments to hybrid or remote setups.<\/p>\n\n<p><strong>Using a Provider Service in Your Compose File<\/strong><\/p>\n\n<p>Provider services are declared like any other Compose service, but instead of specifying an image, you specify a provider with a type, and optionally some options. The type must correspond to the name of a binary available in your $PATH that implements the Compose provider specification.<\/p>\n\n<p>As an example we will use the <a href=\"https:\/\/github.com\/glours\/compose-telepresence-plugin\" target=\"_blank\">Telepresence provider plugin<\/a>, which routes Kubernetes traffic to a local service for live cloud debugging. This is especially useful for testing how a local service behaves when integrated into a real cluster:<\/p>\n<div class=\"wp-block-ponyo-image\">\n<\/div>\n<p>In this setup, when you run docker compose up, Compose will call the compose-telepresence plugin binary. The plugin performs the following actions:<\/p>\n\n<p><strong>Up Action<\/strong>:<\/p>\n<p>Check if the Telepresence traffic manager is installed in the Kubernetes cluster, and install it if needed.<\/p>\n<p>Establish an intercept to re-route traffic from the specified Kubernetes service to the local service.<\/p>\n<p><strong>Down Action<\/strong>:<\/p>\n<p>Remove the previously established intercept.<\/p>\n<p>Uninstall the Telepresence traffic manager from the cluster.<\/p>\n<p>Quit the active Telepresence session.<\/p>\n<p> The structure and content of the options field are specific to each provider. It is up to the plugin author to define and document the expected keys and values.<\/p>\n<p>If you\u2019re unsure how to properly configure your provider service in your Compose file, the Compose Language Server (LSP) can guide you step by step with inline suggestions and validation.<\/p>\n\n<p>You can find more usage examples and supported workflows in the official documentation:<a href=\"https:\/\/docs.docker.com\/compose\/how-tos\/provider-services\/\" target=\"_blank\"> https:\/\/docs.docker.com\/compose\/how-tos\/provider-services\/<\/a><\/p>\n\n<p><strong>How Provider Services Work Behind the Scenes<\/strong><\/p>\n\n<p>Under the hood, when Compose encounters a service using the provider key, it looks for an executable in the user\u2019s $PATH matching the provider type name (e.g. docker-model cli plugin or compose-telepresence). Compose then spawns the binary and passes the service options as flags, allowing the provider to receive all required configuration via command-line arguments.<\/p>\n\n<p>The binary must respond to JSON-formatted requests on stdin and return structured JSON responses on stdout.<\/p>\n\n<p>Here\u2019s a diagram illustrating the interaction:<\/p>\n<div class=\"wp-block-ponyo-image\">\n<\/div>\n<p><strong>Communication with Compose<\/strong><\/p>\n\n<p>Compose send all the necessary information to the provider binary by transforming all the options attributes as flags. It also passes the project and the service name. If we look at the compose-telepresence provider example, on the up command Compose will execute the following command:<\/p>\n<p>$ compose-telepresence compose &#8211;project-name my-project up &#8211;name api &#8211;port 5732:api-80 &#8211;namespace avatars &#8211;service api dev-api<\/p>\n<p>On the other side, providers can also send runtime messages to Compose:<\/p>\n<p>info: Reports status updates. Displayed in Compose\u2019s logs.<\/p>\n<p>error: Reports an error. Displayed as the failure reason.<\/p>\n<p>setenv: Exposes environment variables to dependent services.<\/p>\n<p>debug: Debug messages displayed only when running Compose with -verbose.<\/p>\n<p>This flexible protocol makes it easy to add new types and build rich provider integrations.<\/p>\n\n<p>Refer to the<a href=\"https:\/\/github.com\/docker\/compose\/blob\/main\/docs\/extension.md\" target=\"_blank\"> official protocol spec<\/a> for detailed structure and examples.<\/p>\n\n<p><strong>Building Your Own Provider Plugin<\/strong><\/p>\n\n<p>The real power of provider services lies in their extensibility. You can write your own plugin, in any language, as long as it adheres to the protocol.<\/p>\n\n<p>A typical provider binary implements logic to handle a compose command with up and down subcommands.<\/p>\n\n<p>The source code of<a href=\"https:\/\/github.com\/glours\/compose-telepresence-plugin\" target=\"_blank\"> compose-telepresence-plugin<\/a> will be a good starting point. This plugin is implemented in Go and wraps the Telepresence CLI to bridge a local dev container with a remote Kubernetes service.<\/p>\n\n<p>Here\u2019s a snippet from its up implementation:<\/p>\n<div class=\"wp-block-ponyo-image\">\n<\/div>\n<div class=\"wp-block-ponyo-image\">\n<\/div>\n<p>This method is triggered when docker compose up is run, and it starts the service by calling the Telepresence CLI based on the received options.<\/p>\n\n<p>To build your own provider:<\/p>\n<p>Read the full<a href=\"https:\/\/github.com\/docker\/compose\/blob\/main\/docs\/extension.md\" target=\"_blank\"> extension protocol spec<\/a><\/p>\n<p>Parse all the options as flags to collect the whole configuration needed by the provider<\/p>\n<p>Implement the expected JSON response handling over \/stdout<\/p>\n<p>Don\u2019t forget to add debug messages to have as many details as possible during your implementation phase.<\/p>\n<p>Compile your binary and place it in your $PATH<\/p>\n<p>Reference it in your Compose file using provider.type<\/p>\n<p>You can build anything from service emulators to remote cloud service starters. Compose will automatically invoke your binary as needed.<\/p>\n\n<p><strong>What\u2019s Next?<\/strong><\/p>\n\n<p>Provider services will continue to evolve, future enhancements will be guided by real-world feedback from users to ensure provider services grow in the most useful and impactful directions.<\/p>\n\n<p>Looking forward, we envision a future where Compose can serve as a declarative hub for full-stack dev environments,\u00a0 including containers, local tooling, remote services, and AI runtimes.<\/p>\n\n<p>Whether you\u2019re connecting to a cloud-hosted database, launching a tunnel, or orchestrating machine learning inference, Compose provider services give you a native way to extend your dev environment, no wrappers, no hacks.<\/p>\n\n<p>Let us know what kind of providers you\u2019d like to build or see added. We can\u2019t wait to see how the community takes this further.<\/p>\n\n<p>Stay tuned and happy coding! <\/p>","protected":false},"excerpt":{"rendered":"<p>With the release of Docker Compose v2.36.0, we\u2019re excited to introduce a powerful new feature: provider services. This extension point [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[4],"tags":[],"class_list":["post-2220","post","type-post","status-publish","format-standard","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2220","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=2220"}],"version-history":[{"count":0,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2220\/revisions"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=2220"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=2220"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=2220"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}