Docker Compose is a powerful tool for defining and running multi-container applications. Traditionally, the tool focuses on development and testing workflows. For production deployments, especially at scale, more robust orchestration tools like Kubernetes are often preferred due to their advanced features for managing large-scale containerized applications. Compose can be used for single-host deployments in production, but it may not be suitable for complex, distributed systems. This is where Compose Bridge comes into the picture.
What is Compose Bridge?
Compose Bridge, an experimental feature in Docker Desktop, offers a powerful solution for transforming Docker Compose configurations into Kubernetes manifests, bridging the gap between local development and production-ready orchestration. This tool significantly simplifies the transition from Docker Compose to Kubernetes, allowing developers to leverage the simplicity of Compose while harnessing the scalability and robustness of Kubernetes deployments.
Understanding Compose Bridge
At its core, Compose Bridge operates by utilizing transformations packaged as Docker images. These transformations receive a fully resolved Compose model as input (/in/compose.yaml) and produce target format files as output (/out). The default transformation provided by Compose Bridge focuses on generating Kubernetes manifests and a Kustomize overlay, specifically designed for deployment on Docker Desktop with Kubernetes enabled.
The transformation process leverages Go templates, which allows for easy customization and extension. This templating system enables developers to insert logic and data dynamically, making the generated Kubernetes manifests adaptable to various project requirements. The use of Go templates also provides access to a set of YAML helper functions, such as seconds for converting durations, uppercase for string manipulation, and base64 for encoding secrets.
Key Benefits
Key benefits of using Compose Bridge include:
Simplified Migration: It significantly reduces the complexity of transitioning from Docker Compose to Kubernetes, allowing developers to maintain the simplicity of Compose while leveraging Kubernetes' orchestration capabilities.
Customizability: The templating system allows for extensive customization, enabling organizations to tailor the transformation process to their specific infrastructure needs and preferences.
Consistency: By automating the conversion process, Compose Bridge helps maintain consistency between development and production environments, reducing potential discrepancies and deployment issues.
Resource Optimization: The generated Kubernetes manifests include advanced features like resource limits, health checks, and network policies, which can lead to more efficient resource utilization in Kubernetes clusters.
Rapid Prototyping: Developers can quickly prototype and test Kubernetes deployments based on their existing Docker Compose files, accelerating the development and deployment cycle.
Learning Tool: For teams transitioning to Kubernetes, Compose Bridge serves as an educational tool, providing insights into how Docker Compose concepts map to Kubernetes resources.
While Compose Bridge offers significant advantages, it's important to note that as an experimental feature, it may undergo changes in future releases. Additionally, complex applications might still require manual adjustments to fully optimize for Kubernetes deployments. Despite these considerations, Compose Bridge represents a valuable tool in the Docker ecosystem, streamlining the containerization workflow from development to production.
Setting Up Compose Bridge
Prerequisites
Before setting up Compose Bridge, ensure:
- Install Docker Desktop
- Enabled Kubernetes in Docker Desktop
Once the appropriate Docker Desktop version is installed,you need to follow these steps to enable Compose Bridge:
Step 1:
- Sign in to your Docker account within Docker Desktop
- Navigate to the "Features in development" tab in Settings
- Select the "Experimental features" tab
- Enable the "Compose Bridge" option
After enabling the feature, Compose Bridge becomes available for use.
The Default Transformation
Overview of the Default Kubernetes Transformation
The default transformation simplifies initial migrations, converting Compose files to Kubernetes-ready configurations. This transformation is intended to quickly generate Kubernetes YAML manifests that map closely to the original Docker Compose settings.
What it works
Compose bridge uses transformations to let you convert a Compose model into another form.
A transformation is packaged as a Docker image that receives the fully-resolved Compose model as /in/compose.yaml and can produce any target format file under /out.
Compose Bridge provides its transformation for Kubernetes using Go templates, so that it is easy to extend for customization by just replacing or appending your own templates.
The default Compose Bridge transformation generates Kubernetes resources that include:
Pods: representing containers for each service.
Services: creating a network interface for each container.
ConfigMaps and Secrets: managing environment variables and sensitive data.
How to Use the Default Transformation
Navigate to your project directory containing the Compose file.
Run the command:
$ compose-bridge convert
If you want to convert a compose.yaml file that is located in another directory, you can run:
compose-bridge convert -f <path-to-file>/compose.yaml
- Compose Bridge will generate and apply Kubernetes manifests based on the Compose file, deploying the application on your Kubernetes cluster.
Learn more about the default transformation on the official Docker docs
Sample Application: From Compose to Kubernetes
We’ll use a basic example featuring a web server and database service for this demonstration.
Writing the Docker Compose File
Create a docker-compose.yml with the following configuration:
services:
web:
image: nginx
ports:
- "80:80"
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
Using Compose Bridge to Transform the Compose File
Compose Bridge will convert docker-compose.yml into Kubernetes manifests and apply them.
compose-bridge convert
latest: Pulling from library/postgres
5ecbc93de950: Download complete
ba6e84deecdb: Download complete
425a818d8223: Download complete
159c4494c279: Download complete
b0dd2bf7a180: Download complete
f7fdac227b96: Download complete
3dc01759541c: Download complete
c0a40d31bfac: Download complete
90646cadd7e6: Download complete
e868621ffb41: Download complete
f6ce5b6f352e: Download complete
e1dbef7dcaa1: Download complete
6b732c95d024: Download complete
Digest: sha256:8d3be35b184e70d81e54cbcbd3df3c0b47f37d06482c0dd1c140db5dbcc6a808
Status: Downloaded newer image for postgres:latest
latest: Pulling from library/nginx
2c1384c86539: Download complete
51635e63ab0c: Download complete
805908969407: Download complete
b9a670e7a7f3: Download complete
6c29a458e7d5: Download complete
1f62b39dc401: Download complete
Digest: sha256:28402db69fec7c17e179ea87882667f1e054391138f77ffaf0c3eb388efc3ffb
Status: Downloaded newer image for nginx:latest
latest: Pulling from docker/compose-bridge-kubernetes
af80f65e8b88: Download complete
062101437435: Download complete
99d8bc75d872: Download complete
Digest: sha256:698ecbaaf8abf299cddcf1f9de08509858a9e9199cc6d2f19ba5bf650b72c334
Status: Downloaded newer image for docker/compose-bridge-kubernetes:latest
Kubernetes resource db-deployment.yaml created
Kubernetes resource web-deployment.yaml created
Kubernetes resource db-expose.yaml created
Kubernetes resource web-expose.yaml created
Kubernetes resource 0-10nov-namespace.yaml created
Kubernetes resource default-network-policy.yaml created
Kubernetes resource web-service.yaml created
Kubernetes resource kustomization.yaml created
Kubernetes resource web-service.yaml created
Kubernetes resource kustomization.yaml created
Analyzing the Generated Kubernetes Manifests
The above command creates manifests that represent each service as a Kubernetes pod. These files are then stored within your project in the /out folder.
tree out
out
├── base
│ ├── 0-10nov-namespace.yaml
│ ├── db-deployment.yaml
│ ├── db-expose.yaml
│ ├── default-network-policy.yaml
│ ├── kustomization.yaml
│ ├── web-deployment.yaml
│ ├── web-expose.yaml
│ └── web-service.yaml
└── overlays
└── desktop
├── kustomization.yaml
└── web-service.yaml
4 directories, 10 files
The Kubernetes manifests can then be used to run the application on Kubernetes using the standard deployment command kubectl apply -k out/overlays/desktop/.
kubectl apply -k out/overlays/desktop/
namespace/10nov created
service/db created
service/web created
service/web-published created
deployment.apps/db created
deployment.apps/web created
networkpolicy.networking.k8s.io/default-network-policy created
You can verify this by running:
kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
10nov db-7c7d8ffc7f-c6k2p 1/1 Running 0 27s
10nov web-b7c76985f-bn5lc 1/1 Running 0 27s
kube-system coredns-7db6d8ff4d-5g8ph 1/1 Running 0 4m20s
kube-system coredns-7db6d8ff4d-vn95x 1/1 Running 0 4m20s
kube-system etcd-docker-desktop 1/1 Running 2 4m26s
kube-system kube-apiserver-docker-desktop 1/1 Running 2 4m21s
kube-system kube-controller-manager-docker-desktop 1/1 Running 2 4m17s
kube-system kube-proxy-bt6pf 1/1 Running 0 4m21s
kube-system kube-scheduler-docker-desktop 1/1 Running 2 4m19s
kube-system storage-provisioner 1/1 Running 0 4m18s
kube-system vpnkit-controller 1/1 Running 0 4m18s
Examining the YAML files
cd out/overlays/desktop/
cat kustomization.yaml
#! kustomization.yaml
# Generated code, do not edit
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
- path: web-service.yaml
cat web-service.yaml
# check if there is at least one published port
#! web-service.yaml
# Generated code, do not edit
apiVersion: v1
kind: Service
metadata:
name: web-published
namespace: 10nov
spec:
type: LoadBalancer
