docker-compose

Container orchestration for noobs developers

What ?

Tool for defining and running multi-container Docker application

Use cases: development, (unit & integration) testing, staging environments and CI workflows

Directly based on fig (now deprecated)

Open source and written in Python

Installation

Two main ways of installing it on your box:

or using your favorite package manager

pip install docker-compose
brew install docker-compose

Application definition

The application is split into services, each service being a container.

All services are defined inside a configuration file, written using YAML, called a "compose file" and generally named docker-compose.yml.


version: "2"

services:

  # Dependencies
  elasticmq:
    build: services/elasticmq
    ports:
      - 9324:9324

  dynamodb:
    build: services/dynamodb
    ports:
      - 8000:8000

  # Application
  tracking-api:
    image: tinyclues/tracking-api
    # build: .
    links:
      - elasticmq
      - dynamodb
    ports:
      - 80:80
      - 5000:5000
    volumes:
      - ./:/app

Application definition

(Concise) compose file reference

 - build : defines configuration option that will be passed at the image's build time. Mostly used to define the location (path to folder or git repository url) of the Dockerfile of the service.

 - image : specifies the image used to start the service's container.

 - links : creates a network link to another service's container. Also expresses dependencies, i.e. if service A is linked to service B, the latter will be automatically started beforehand.

 - ports : exposes ports with the syntax HOST:CONTAINER or just CONTAINER.

 - environmentinjects an environment variable inside the soon-to-be running service.

 - volumes : mounts paths, optionally specifying a path on the host machine (HOST:CONTAINER), or an access mode (H:C:ro).

 - command : overrides the default CMD (i.e. the command that is run when the container is started) from the Dockerfile/image.

 - entrypoint : overrides the default ENTRYPOINT (i.e. the script or command that is run before the main one) from the Dockerfile/image.

(Not so concise) compose file reference

The "classic" `docker run` can receive a lot of arguments that allows for advanced tweaking of your container.

Yes, we all know that you are a Docker nerd that lives for the thrill of launching container with arcane optimizations.

Yes, those options are also available through docker-compose.

Available, but not limited to:

 - restart : policy for how a container should be restarted (or not) if it exits

 - privileged : enable/disable the access to all devices on the host

Launching the application

docker-compose up [-d] [--no-recreate] [<service>,]

Checking the services' behaviour

docker-compose ps

               Name                              Command               State                                      Ports                                    
----------------------------------------------------------------------------------------------------------------------------------------------------------
celeryflask_celery-broker_1           /docker-entrypoint.sh rabb ...   Up      15671/tcp, 0.0.0.0:8080->15672/tcp, 25672/tcp, 4369/tcp, 5671/tcp, 5672/tcp 
celeryflask_celery-result-backend_1   docker-entrypoint.sh redis ...   Up      6379/tcp                                                                    
celeryflask_web_1                     python run_app.py                Up      0.0.0.0:5000->5000/tcp                                                      
celeryflask_worker_1                  celery worker --app applic ...   Up      5000/tcp                                                                    

docker-compose logs [-f] [<service>,]

Attaching to celeryflask_web_1, celeryflask_worker_1, celeryflask_celery-broker_1, celeryflask_celery-result-backend_1
web_1                    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1                    |  * Restarting with stat
web_1                    |  * Debugger is active!
web_1                    |  * Debugger pin disabled.  DEBUGGER UNSECURED!
worker_1                 | /usr/local/lib/python3.5/site-packages/celery/platforms.py:812: RuntimeWarning: You are running the worker with superuser privileges, which is
worker_1                 | absolutely not recommended!
celery-result-backend_1  | 1:C 28 Apr 09:00:24.757 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
worker_1                 | 
worker_1                 | Please specify a different user using the -u option.
worker_1                 | 

Pulling the plug

docker-compose stop [<service>,]

docker-compose kill [<service>,]

Cleaning up

docker-compose rm [-fv] [--all] [<service>,]

More CLI commands !

docker-compose run [--no-deps] <service> <command>

docker-compose exec <service> <command>

docker-compose scale <service>=<number:Int>

docker-compose build [--no-cache] <service>

Demo !

docker-compose

By Cyril Thomas