The basic idea behind Docker Compose is to save you a lot of typing when creating, configuring, stopping, rebuilding or inspecting your containers. We create a docker-compose,yml file to define our docker resources, such as containers (called services in this context), networks and volumes. Then we use a single command to spin everything up or tear it all down.
Using Docker Compose is good for development or maybe staging, but for production there are better alternatives.
Installing Docker Compose
If you installed Docker Desktop/Toolbox for either Windows or Mac, you already have Docker Compose. If you are on a Linux machine, you will need to install Docker Compose using the instructions here.
Creating docker-compose.yml
You can define all kinds of configurations for your services, such as builds, environments, images, networks, ports, volumes.
At the root of the app project, create a file named docker-compose.yml
.
version: "3.8" services: # aka containers app: # name of your container image: node:12-alpine command: sh -c "yarn install && yarn run dev" ports: - 3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql # we can use mysql as hostname here because we defined 'mysql' as a service MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos mysql: image: mysql:5.7 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos volumes: todo-mysql-data:
We can pick any name for the service. The name will automatically become a network alias, which will be useful when defining our MySQL service: See how we use mysql
as a value for MYSQL_HOST
? That’s possible because we defined mysql
as service name.
By default, Docker Compose automatically creates a network specifically for the application stack, which is why we didn’t define one in the compose file explicitly.
You can use environment variables in docker-compose.yml and forward a environment file to your containers/services: If your are using Linux then you first have to export APP_ENV=development
and then:
myservice: env_file: - ./path/to/app.${APP_ENV}.env
Building images
# Build or rebuild services defined in docker-compose.yml docker-compose build # Build specific service docker-compose build my-service
Do I need a Dockerfile when I use docker-compose.yml?
Docker Compose lets you choose between the two options:
- build the container from a specified image (without the need of a Dockerfile):
services: example: image: your/imagename
- build the container out of a Dockerfile:
services: example: build: context: path/to/Dockerfile/dir dockerfile: Dockerfile #here you specify the name of your Dockerfile file
Starting and stopping your services with Docker Compose
# Start services (detached) docker-compose up -d # Only rebuild 'node' image, not its dependencies docker-compose up --no-deps node
# Stop and remove services docker-compose down # Stop but do not remove services docker-compose stop # Stop and remove services and remove images and volumes docker-compose down --rmi all --volumes # Remove services docker-compose rm
By default, named volumes in your compose file are NOT removed when running docker-compose down
. If you want to remove the volumes, you will need to add the --volumes
flag.
Inspecting services
# show running services docker-compose ps # show all services docker-compose ps -a # You’ll see the logs from each of the services interleaved into a single stream docker-compose logs -f # To see the logs of a single service run docker-compose logs -f my-service
Waiting for other containers to start up
When the app is starting up, it actually sits and waits for MySQL to be up and ready before trying to connect to it. Docker doesn’t have any built-in support to wait for another container to be fully up, running, and ready before starting another container. For Node-based projects, you can use the wait-port dependency. Similar projects exist for other languages/frameworks.
Migrating from Docker Compose to Kubernetes
Two options: Compose on Kubernetes (Part of Docker Desktop) and Kompose. After installation of Kompose you can simply run kompose convert
in your project root folder and it will create Kubernetes YAML files for you.