docker-compose
Workshop
Created by
Andreas Grohmann
/
andreas.grohmann@gmx.de
/
twitter.com/grohmeo
# docker-compose * [motivation](#/2) * [overview](#/3) * [versions](#/4) * [getting started](#/5)
## motivation * how to handle multiple container applications? * how to easy manage docker commands, volumes, env vars ... ?
### what is docker-compose? * tool for defining and running multiple container applications * single file to configure services * single command for create and start all services
### facts * oldest commit: 03.01.2014 * current version: 1.17.0 * first seperated tool, later integrated in docker * file formats: 1.0 / 2.0 - 2.2 / 3.0 - 3.2
## overview ### general process 1. define app's environment in a Dockerfile 2. define app services in a docker-compose.yml file 3. run docker-compose up ``` all containers will start in a capsulated environment ```
### features * multiple isolated environments on a single host * project name used, change default -p * preserve volume data * rescue data from old containers to new ones * no data loss * recreate only changed containers * cache configuration * reuse existing containers * variables * customize composition for different environments/users
## versions diverse syntax over time, see links below * [Version 3](https://docs.docker.com/compose/compose-file/) * [Version 2](https://docs.docker.com/compose/compose-file/compose-file-v2/) * [Version 1](https://docs.docker.com/compose/compose-file/compose-file-v1/)
### docker-compose file (version 2) * YAML file * defining services, networks, volumes * default path "./docker-compose.yml" * configuration is applied to each container
#### image * use existing image, instead of build * can be a repository / tag / partial image ID e.g. ``` image: redis image: ubuntu:14.04 image: tutum/influxdb image: example-registry.com:4000/postgresql image: a4bc65fd ```
#### build * applied at build time * contains context, dockerfile (optinal), args (optional) ``` build: ./dir ``` or ``` build: context: ./dir dockerfile: Dockerfile-alternate args: buildno: 1 ```
#### context * directory to Dockerfile or url to git repository ``` build: context: ./dir ``` #### dockerfile * alternate Dockerfile for build ``` build: context: . dockerfile: Dockerfile-alternate ```
#### args * env variables only accessible during build process define ``` ARG buildno ARG password RUN echo "Build number: $buildno" RUN script-requiring-password.sh "$password" ``` use ``` build: context: . args: buildno: 1 password: secret ``` use host env's ``` args: - buildno - password ```
#### environment variables * accessible during container runtime ``` environment: RACK_ENV: development SHOW: 'true' SESSION_SECRET: ``` or ``` environment: - RACK_ENV=development - SHOW=true - SESSION_SECRET ```
#### env_file * env variables can be defined in a file * relative path to compose file ``` env_file: .env ``` or use multiple files ``` env_file: - ./common.env - ./apps/web.env - /opt/secrets.env ``` env file syntax ``` # Set Rails/Rack environment RACK_ENV=development ```
#### links * link container to an other services * syntax SERVICE:ALIAS ``` web: links: - db - db:database - redis ```
#### volumes * mount path or named volumes into container * syntax HOST:CONTAINER ``` volumes: # Just specify a path and let the Engine create a volume - /var/lib/mysql # Specify an absolute path mapping - /opt/data:/var/lib/mysql # Path on the host, relative to the Compose file - ./cache:/tmp/cache # User-relative path - ~/configs:/etc/configs/:ro # Named volume - datavolume:/var/lib/mysql ```
#### expose * expose ports to linked services * not visible to host ``` expose: - "3000" - "8000" ``` #### ports * expose ports to host and linked services * syntax HOST:CONTAINER ``` ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp" ```
#### restart * restart policy * default no ``` - restart: no - restart: always - restart: on-failure ``` #### depends on * dependencies between services ``` version: '2' services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres ```
## getting started ### install on coreos * docker-compose included in most docker installations install on core os (always take the latest version) ``` $ sudo su - $ mkdir /opt/ $ mkdir /opt/bin $ curl -L \ https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` \ > /opt/bin/docker-compose $ chmod +x /opt/bin/docker-compose $ exit ``` check version ``` $ docker-compose --version ```
### installation on centos 7 install on centos (always take the latest version) ``` $ curl -L \ https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` \ > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose ``` check version ``` $ docker-compose --version ```
### start project login ``` $ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: YOUR-ACCOUNT Password: Login Succeeded ``` create file ``` $ mkdir workshop_test2 $ cd workshop_test2 $ touch docker-compose.yml $ vi docker-compose.yml ```
add file content ``` # ./docker-compose.yml version: '2' services: db: image: mysql:5.7 volumes: - db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress volumes: db_data: ``` start project ``` docker-compose up ```
### TODO !!! ``` * add version 1 example from above * add version 3 example from above ```
check local wordpress server
http://localhost:8000
play around
http://localhost:8000
play around
http://localhost:8000
play around
http://localhost:8000
play around
http://localhost:8000
start containers ``` $ docker-compose up -d Starting workshoptest2_db_1 Starting workshoptest2_wordpress_1 ``` stop containers ``` $ docker-compose stop Stopping workshoptest2_wordpress_1 ... done Stopping workshoptest2_db_1 ... done ``` remove containers ``` $ docker-compose rm Going to remove workshoptest2_wordpress_1, workshoptest2_db_1 Are you sure? [yN] y Removing workshoptest2_wordpress_1 ... done Removing workshoptest2_db_1 ... done ```
### remove unused containers ( > Docker 1.13.x) show all containers ``` $ docker ps -a ``` prune containers ``` $ docker container prune ``` output ``` $ docker container prune WARNING! This will remove all stopped containers. Are you sure you want to continue? [y/N] y Deleted Containers: 36db3e614c82f24cf7774fb80aeced15d89f5f2daa9e2214a3f8416899e31116 303a198f1d038513aa9befcf438beb25a5edc543a98c53321171f7fdd1574930 cc281d90db872836b0cf82548336f167b4fc89969b83cd12309ad80f9d79f10d ``` check ``` $ docker ps -a ```
### remove unused images ( > Docker 1.13.x) ``` $ docker images ``` prune dangling images ``` $ docker system prune ``` prune images without containers ``` $ docker system prune -a ``` output ``` $ docker system prune -a WARNING! This will remove: - all stopped containers - all volumes not used by at least one container - all networks not used by at least one container - all images without at least one container associated to them Are you sure you want to continue? [y/N] y Deleted Volumes: 0f32fcf5576c207f548cd06c3a316d2fca306fdb54eaf349f1e326518aac7840 ``` ``` $ docker images ```
### remove unused images ( < Docker 1.13.x) ``` $ docker images ``` remove unused images ``` $ docker rmi $(docker images --filter "dangling=true" -q --no-trunc) ``` check ``` $ docker images ```
more trainings
training.play-with-docker.com
Questions?