Compose
Deploy multiple containers on a single host
A YAML file defining version (DEPRECATED), services (REQUIRED), networks, volumes, configs and secrets
Default path is compose.yaml (or compose.yml, docker-compose.yaml, docker-compose.yml) in working directory
Build and Compose
1. Build an image from local
2. Compose containers
- version: "3.9" # version of Docker Compose
- services:
- webapp: # container
- image: lchenlangley/count # image name [domain/image:tag]
- build: . # search local, if image does not exist, build image from local
- ports:
- - 8000:5000 # host port : container port
- environment:
- - MYREDIS_HOST=redisserver # environment variable
- redisserver: # container
- image: redis:alpine # if image exist in local, use the local image
- # a bridge network is created by default
-
Fetch and Compose
1. Fetch images from repositories
2. Compose containers
- version: "3.9"
- services:
- webapp:
- image: lchenlangley/count # fetch image from Docker Hub
- ports:
- - 8000:5000
- environment:
- - MYREDIS_HOST=redisserver
- redisserver:
- image: "redis:alpine" # fetch image from Docker Hub
-
Multiple Compose Files
- # compose_1.yaml
- version: "3.9"
- services:
- webapp: # container
- image: lchenlangley/count
- #build: .
- volumes:
- - type: volume
- source: voltemp
- target: /code
- volumes:
- voltemp:
-
- # compose_2.yaml
- version: "3.9"
- services:
- webapp: # container
- ports:
- - target: 5000
- published: 8000
- protocol: tcp
- mode: host
- environment:
- MYREDIS_HOST: redisserver
- redisserver: # container
- image: redis:alpine
-
- docker-compose -f compose_1.yaml -f compose_2.yaml up
- docker-compose -f compose_1.yaml -f compose_2.yaml down
-
Configuration Extension
re-use a common configuration
- # compose.yaml
- version: "3.9"
- services:
- webapp: # container
- extends:
- file: common.yaml
- service: template
- image: lchenlangley/count
- #build: .
- volumes:
- - type: volume
- source: voltemp
- target: /code
- redisserver: # container
- image: redis:alpine
- volumes:
- voltemp:
-
- # common.yaml, contains a common configuration
- version: "3.9"
- services:
- template: # container
- ports:
- - target: 5000
- published: 8000
- protocol: tcp
- mode: host
- environment:
- MYREDIS_HOST: redisserver
-
- docker-compose up
- docker-compose down
-
Services
Abstract concept implementing docker run
image
- Specifies the image to start the container from
- image: redis # [domainName/imageName:tag]
-
ports
- Expose ports from container to host
- ports:
- - 8000:5000 # host_port:container_port
-
build
- Build image from local source code, allow to miss the image attribute
- services:
- webapp:
- image: awesome/webapp # image name
- build: . # path for source code and Dockerfile
-
- services:
- webapp:
- image: awesome/database # image name
- build:
- context: . # source code path
- dockerfile: ../Dockerfile # Dockerfile path
-
- services:
- webapp:
- build: . # source code path
-
environment
- Add environment variables
- services:
- webapp:
- ...
- environment:
- MYREDIS_HOST: redisserver
-
- services:
- webapp:
- ...
- environment:
- - MYREDIS_HOST=redisserver
-
networks
- Specify the networks to join
- services:
- webapp:
- ...
- networks:
- - frontend-network
- - backend-network
-
restart
- restart containers when restarting the docker daemon, rebooting your server, using a CMD inside a container and running an exit, etc.
- restart policy is ignored when containers are stopped manually, such as stop and kill by docker-compose
- restart: always
-
env_file
- Add environment variables from a file, not really work in the test
- # .env, default environment file
- MYREDIS_HOST=redisserver
-
- # compose.yml
- services:
- webapp:
- ...
- environment:
- - MYREDIS_HOST=${MYREDIS_HOST}
-
- # env/webapp.env
- MYREDIS_HOST=redisserver
-
- # compose.yml
- services:
- webapp:
- ...
- environment:
- - MYREDIS_HOST=${MYREDIS_HOST}
-
- # compose
- docker-compose --env-file env/webapp.env up
-
- # turn off compose
- docker-compose --env-file env/webapp.env down
-
profiles and depends_on
- Selectively enable services
- If unassigned, the service is always started
- If assigned, the service is only started if the profile is activated
- services:
- foo:
- image: foo
- bar:
- image: bar
- profiles:
- - test
- baz:
- image: baz
- depends_on:
- - bar
- profiles:
- - test
- zot:
- image: zot
- depends_on:
- - bar
- profiles:
- - debug
-
- # enable test (bar, baz) and foo
- docker-compose --profile test up
-
- # invalid, profile debug (zot) is enabled, but zot depends on bar which is in the profile test
- docker-compose --profile debug up
-
- # enable test(bar, baz), debug(zot) and foo
- docker-compose --profile debug --profile test up
-
- # enable bar, profile test is active, but baz is not enabled
- docker-compose up bar
-
- # enable baz, profile test is active, bar is enabled by depends_on constraint
- docker-compose up baz
-
- # enable zot and test, bar is enabled by depends_on constraint
- docker-compose --profile test up zot
-
command
- Override the default command of a container
- command: python app.py
-
expose
- Specify the port number exposed from container
- Same as expose in Dockerfile, it functions as a type of documentation
- By default, make the access port number in app, the expose number in dockerfile, and the expose port number in compose file match
- expose:
- - "5000"
-
container_name
- Specify container name instead of using default name
- container_name: redis-container
-
hostname
- Specify host name inside a container
- hostname: redis-host
-
Networks
Capability abstraction to establish an IP route between containers, analogous to docker network create
By default, docker-compose sets up a single network, containers join the network for communication
- [directory]_default, network name
- version: "3.9"
- services:
- webapp: # container
- image: lchenlangley/count
- #build: .
- volumes:
- - type: volume
- source: voltemp
- target: /code
- ports:
- - target: 5000
- published: 8000
- protocol: tcp
- mode: host
- environment:
- MYREDIS_HOST: ${MYREDIS_HOST}
- networks:
- - app-net
- redisserver: # container
- image: redis:alpine
- networks:
- - app-net
- volumes:
- voltemp:
- networks:
- app-net: # create a network named [directory]_app-net
-
Volumes
Configs
Grant access to configs on a per-service basis
-
Secret
Grant access to secrets on a per-service basis
-
Example
2 services, backed by Docker images: webapp and database
1 secret (HTTPS certificate), injected into the frontend
1 configuration (HTTP), injected into the frontend
1 persistent volume, attached to the backend
2 networks: front-tier and back-tier
- services:
- frontend:
- image: awesome/webapp
- ports:
- - "443:8043"
- networks:
- - front-tier
- - back-tier
- configs:
- - httpd-config
- secrets:
- - server-certificate
-
- backend:
- image: awesome/database
- volumes:
- - db-data:/etc/data
- networks:
- - back-tier
-
- volumes:
- db-data:
- driver: flocker
- driver_opts:
- size: "10GiB"
-
- configs:
- httpd-config:
- external: true
-
- secrets:
- server-certificate:
- external: true
-
- networks:
- # The presence of these objects is sufficient to define them
- front-tier: {}
- back-tier: {}
-
docker-compose
- # get command help
- docker-compose --help
-
- # start services
- # --build, build images from source code instead of loading built images before starting containers
- # -d, detached
- # docker-compose up [service list]
-
- docker-compose up # start all services
- docker-compose up webapp # start service webapp
- docker-compose -f [composeFileName] up # specify compose file
-
- # turn off and remove services
- docker-compose down
-
- # build images in compose file
- docker-compose build
-
- # list images of the current compose
- docker-compose images
-
- # list service of the current compose
- docker-compose ps
-
- # stop services of the current compose
- docker-compose stop [serviceName] # stop a specific service
- docker-compose stop # stop services in the current compose
-
- # start services
- docker-compose start [serviceName] # start a specific service
- docker-compose start # start services in the current compose
-
- # one-off command
- # docker-compose run [serviceName] [command]
- docker-compose run webapp env
-
- # view the compose file
- docker-compose config
-
Reference