Today we’re very happy to announce the second release of Docker Compose, a tool for easily defining and running multi-container apps. Head straight to the install docs if you can’t wait to download and use it.
Since we announced Docker Compose back in February, there’s been lots of attention and love from the community. We’ve got users in lots of cool places – including Yelp, where Compose is used for acceptance testing to facilitate continuous delivery.
Since the beginning of the project, we have consistently received two requests:
- Make it easier to configure the same app for multiple environments
- Make it easier to share configuration between apps
With Compose 1.2 we’re introducing a new feature which solves both requirements by letting you share configuration between services with the keyword “
extends, you can refer to a service defined elsewhere and include its configuration in a locally-defined service, while also adding or overriding configuration as necessary.
Let’s go through an example. Suppose we have a simple web-and-database app, and we want to use Compose to both develop it locally and deploy it to production. Both environments are similar, but there are some differences:
- In development, we want to mount our app code as a volume so that it can pick up changes – but when we deploy to production, we want the code to be immutable from the outside, so we can be sure it’s not accidentally changed.
- In development, we want to run a local PostgreSQL container as our database – but in production, our database is managed by another team who’ve given us a URL to connect to.
We won’t go into the details of the webapp – we’ll just suppose that it’s built from a Dockerfile in the current directory, and uses a
DATABASE_URL environment variable to locate its PostgreSQL service.
We’re going to write three files to get a multi-environment setup working.
First, since our web service appears in both environments, we should put it in an auxiliary file – let’s call it
common.yml, although we can give it any name:
web: build: . ports: - "80:8000" # ...any extra configuration...
Above, we’ve defined our “web” service, just as we would normally in a Compose file. (Our example doesn’t have much config, but we know from experience that as real-world apps grow, so do the particulars of their setup.)
Second, we define our development environment in
web: extends: file: common.yml service: web volumes: - .:/code links: - db environment: - DATABASE_URL=postgres://db:5432 db: image: postgres
Above, we’ve defined a “web” service which uses extends to fetch the configuration for “web” out of
common.yml, adds volumes and links configuration to it, and finally sets the
DATABASE_URL environment variable to point to the linked “db” container (which just uses a stock PostgreSQL image from Docker Hub).
When we run docker-compose up, both a web and a db container will be created, linked together and started, and our code will be mounted inside the web container.
Finally, let’s write a production config in production.yml:
web: extends: file: common.yml service: web environment: - DATABASE_URL=postgres://production-db.example.com:12345
Again we’ve defined a “web” service that uses extends to fetch configuration out of common.yml, but this time we’ve not defined a “db” service – instead, we point DATABASE_URL at the PostgreSQL instance that our DB team has prepared for us. We’ve also omitted the volumes configuration, so that our app code isn’t visible from outside the container.
If we run Compose on our production server with docker-compose -f production.yml up, it will start just the web container and point it at the production DB.
Now we’ve got a setup that’ll run the same app in development and production, with the necessary config adjustments made in each environment. We can keep working on our web app, updating its config in common.yml when necessary, and we don’t have to copy-and-paste it into two different files.
That’s a simple example of how extends lets you configure an app for multiple environments. You can read more in the documentation.
Head over to the install docs to download Compose 1.2 and check out the quick start guide to take it for a spin. If you have any questions, drop in to #docker-compose on IRC and report any bugs on GitHub.
As always, Compose is as great as it is because of the work of many contributors. Special thanks for this release go out to abesto, albers, alunduil, dnephin, funkyfuture, gilclark, IanVS, KingsleyKelly, knutwalker, moysesb, thaJeztah and vmalloc.