search by tags

for the user

adventures into the land of the command line

docker compose... so i only need to type one command

So I started using docker not too long ago, and I was started to encounter a pretty repetitive workflow… docker build.. docker run.. docker stop.. docker rm.. docker rmi.. docker build.. oh my god..

So I guess this is the entire purpose for the existence of docker compose? So here’s how to do exactly the same thing as in my last post

Let’s assume the docker daemon is already installed.

Install docker-compose.

$ curl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.15.0, build e12f3b9
$ docker-compose version
docker-compose version 1.15.0, build e12f3b9
docker-py version: 2.4.2
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

Put a docker-compose.yml into your working directory:

$ tree
.
├── Vagrantfile
├── app
│   ├── Dockerfile
│   ├── index.py
│   └── pewpew.wsgi
├── db
│   └── Dockerfile
├── docker-compose.yml
└── rp
    ├── Dockerfile
    └── site.conf


version: '2'
services:

  reverseproxy:
    build: /srv/rp
    ports:
      - "80:80"
    links:
      - flaskapp:flaskapp
    depends_on:
      - flaskapp

  flaskapp:
    build: /srv/app
    ports:
      - "5000:5000"
    links:
      - mongodb:mongodb
    depends_on:
      - mongodb

  mongodb:
    build: /srv/db
    ports:
      - "27017:27017"

Build those images & run those containers

$ docker-compose up -d

.
.
.
Creating mongodb ...
Creating mongodb ... done
Creating flaskapp ...
Creating flaskapp ... done
Creating reverseproxy ...
Creating reverseproxy ... done

Check what’s going on

$ docker-compose ps
    Name                  Command               State              Ports
-----------------------------------------------------------------------------------
flaskapp       gunicorn -k eventlet -b 0. ...   Up      0.0.0.0:5000->5000/tcp
mongodb        docker-entrypoint.sh mongod      Up      0.0.0.0:27017->27017/tcp
reverseproxy   nginx -g daemon off;             Up      443/tcp, 0.0.0.0:80->80/tcp

Send a request to the reverse proxy

$ curl http://127.0.0.1
Pew Pew!
{u'storageEngines': [u'devnull', u'ephemeralForTest', u'mmapv1', u'wiredTiger'], u'maxBsonObjectSize': 16777216, u'ok': 1.0, u'bits': 64, u'modules': [], u'openssl': {u'compiled': u'OpenSSL 1.0.1t  3 May 2016', u'running': u'OpenSSL 1.0.1t  3 May 2016'}, u'javascriptEngine': u'mozjs', u'version': u'3.4.6', u'gitVersion': u'c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5', u'versionArray': [3, 4, 6, 0], u'debug': False, u'buildEnvironment': {u'cxxflags': u'-Woverloaded-virtual -Wno-maybe-uninitialized -std=c++11', u'cc': u'/opt/mongodbtoolchain/v2/bin/gcc: gcc (GCC) 5.4.0', u'linkflags': u'-pthread -Wl,-z,now -rdynamic -Wl,--fatal-warnings -fstack-protector-strong -fuse-ld=gold -Wl,--build-id -Wl,-z,noexecstack -Wl,--warn-execstack -Wl,-z,relro', u'distarch': u'x86_64', u'cxx': u'/opt/mongodbtoolchain/v2/bin/g++: g++ (GCC) 5.4.0', u'ccflags': u'-fno-omit-frame-pointer -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-missing-braces -fstack-protector-strong -fno-builtin-memcmp', u'target_arch': u'x86_64', u'distmod': u'debian81', u'target_os': u'linux'}, u'sysInfo': u'deprecated', u'allocator': u'tcmalloc'}
[u'admin', u'local']

What do the containers look like now?

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
774ad38c93d7        srv_reverseproxy    "nginx -g 'daemon ..."   3 minutes ago       Up 3 minutes        0.0.0.0:80->80/tcp, 443/tcp   reverseproxy
1094581a5a17        srv_flaskapp        "gunicorn -k event..."   3 minutes ago       Up 3 minutes        0.0.0.0:5000->5000/tcp        flaskapp
0f4c7f0d7175        srv_mongodb         "docker-entrypoint..."   3 minutes ago       Up 3 minutes        0.0.0.0:27017->27017/tcp      mongodb

$ docker-compose ps
    Name                  Command               State              Ports
-----------------------------------------------------------------------------------
flaskapp       gunicorn -k eventlet -b 0. ...   Up      0.0.0.0:5000->5000/tcp
mongodb        docker-entrypoint.sh mongod      Up      0.0.0.0:27017->27017/tcp
reverseproxy   nginx -g daemon off;             Up      443/tcp, 0.0.0.0:80->80/tcp

And the images?

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
srv_reverseproxy    latest              9283f67c41fb        3 minutes ago       107MB
srv_flaskapp        latest              e3b9a8003c5d        3 minutes ago       683MB
srv_mongodb         latest              397be1d78005        4 minutes ago       359MB
nginx               latest              b8efb18f159b        13 days ago         107MB
mongo               latest              6833171fe0ad        13 days ago         359MB
python              2.7                 fa8e55b2235d        2 weeks ago         673MB

$ docker-compose images
 Container        Repository       Tag       Image Id      Size
----------------------------------------------------------------
flaskapp       srv_flaskapp       latest   e3b9a8003c5d   651 MB
mongodb        srv_mongodb        latest   397be1d78005   342 MB
reverseproxy   srv_reverseproxy   latest   9283f67c41fb   102 MB

Now previously… say you want to change something in one of the containers, you’d have to like, docker stop.. docker rm.. docker rmi.. docker build.. docker run.. blah blah blah.

Say I’ve changed the app output from Pew Pew! to Peow Peow Lazor Beams!!

With docker-compose:

$ docker-compose build flaskapp
.
.
Removing intermediate container 05f624a8c37b
Successfully built 0e44b2dee5fa
Successfully tagged srv_flaskapp:latest

$ docker-compose up --no-deps -d flaskapp
Recreating flaskapp ...
Recreating flaskapp ... done

$ docker-compose ps
    Name                  Command               State              Ports
-----------------------------------------------------------------------------------
flaskapp       gunicorn -k eventlet -b 0. ...   Up      0.0.0.0:5000->5000/tcp
mongodb        docker-entrypoint.sh mongod      Up      0.0.0.0:27017->27017/tcp
reverseproxy   nginx -g daemon off;             Up      443/tcp, 0.0.0.0:80->80/tcp

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
2b4e890d5dcf        srv_flaskapp        "gunicorn -k event..."   3 minutes ago       Up 3 minutes        0.0.0.0:5000->5000/tcp        flaskapp
774ad38c93d7        srv_reverseproxy    "nginx -g 'daemon ..."   2 hours ago         Up About an hour    0.0.0.0:80->80/tcp, 443/tcp   reverseproxy
0f4c7f0d7175        srv_mongodb         "docker-entrypoint..."   2 hours ago         Up About an hour    0.0.0.0:27017->27017/tcp      mongodb

And the changes?

$ curl http://127.0.0.1
Peow Peow Lazor Beams!!
{u'storageEngines': [u'devnull', u'ephemeralForTest', u'mmapv1', u'wiredTiger'], u'maxBsonObjectSize': 16777216, u'ok': 1.0, u'bits': 64, u'modules': [], u'openssl': {u'compiled': u'OpenSSL 1.0.1t  3 May 2016', u'running': u'OpenSSL 1.0.1t  3 May 2016'}, u'javascriptEngine': u'mozjs', u'version': u'3.4.6', u'gitVersion': u'c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5', u'versionArray': [3, 4, 6, 0], u'debug': False, u'buildEnvironment': {u'cxxflags': u'-Woverloaded-virtual -Wno-maybe-uninitialized -std=c++11', u'cc': u'/opt/mongodbtoolchain/v2/bin/gcc: gcc (GCC) 5.4.0', u'linkflags': u'-pthread -Wl,-z,now -rdynamic -Wl,--fatal-warnings -fstack-protector-strong -fuse-ld=gold -Wl,--build-id -Wl,-z,noexecstack -Wl,--warn-execstack -Wl,-z,relro', u'distarch': u'x86_64', u'cxx': u'/opt/mongodbtoolchain/v2/bin/g++: g++ (GCC) 5.4.0', u'ccflags': u'-fno-omit-frame-pointer -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-missing-braces -fstack-protector-strong -fno-builtin-memcmp', u'target_arch': u'x86_64', u'distmod': u'debian81', u'target_os': u'linux'}, u'sysInfo': u'deprecated', u'allocator': u'tcmalloc'}
[u'admin', u'local']

Noice.