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}.envBuilding images
# Build or rebuild services defined in docker-compose.ymldocker-compose build
# Build specific servicedocker-compose build my-serviceDo 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 fileStarting and stopping your services with Docker Compose
# Start services (detached)docker-compose up -d
# Only rebuild 'node' image, not its dependenciesdocker-compose up --no-deps node# Stop and remove servicesdocker-compose down
# Stop but do not remove servicesdocker-compose stop
# Stop and remove services and remove images and volumesdocker-compose down --rmi all --volumes
# Remove servicesdocker-compose rmBy 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 servicesdocker-compose ps
# show all servicesdocker-compose ps -a
# You’ll see the logs from each of the services interleaved into a single streamdocker-compose logs -f
# To see the logs of a single service rundocker-compose logs -f my-serviceWaiting 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.