Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Docker Cluster based on Raspberry Pi

Peter Rossbach
September 07, 2015

Docker Cluster based on Raspberry Pi

**Docker Cluster based on Raspberry Pi talk**

Here you can find my docker slide container decks from my docker Raspberry PI talk:

- [IOT Berlin 2015 - Docker-Cluster auf der Basis von Raspberry Pis ][1].

Feedback welcome

[Peter Rossbach][2]

[1]: https://iotcon.de/2015/sessions/docker-cluster-auf-der-basis-von-raspberry-pis
[2]: http://twitter.com/PRossbach

Peter Rossbach

September 07, 2015
Tweet

More Decks by Peter Rossbach

Other Decks in Technology

Transcript

  1. 23 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ wget http://downloads.hypriot.com/hypriot-rpi-20150416-201537.img.zip $ unzip hypriot-rpi-20150416-201537.img.zip # insert SD CARD $ diskutil list ... /dev/disk3 #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *31.9 GB disk3 1: Windows_FAT_32 NO NAME 31.9 GB disk3s1 $ diskutil unmountdisk /dev/disk3 $ sudo dd if=hypriot-rpi-20150416-201537.img of=/dev/rdisk3 bs=1M 1220+1 records in 1220+1 records out 1280000000 bytes (1,3 GB) copied, 81,6065 s, 15,7 MB/s # 1,3 GB warten... 80 Sec $ diskutil unmountdisk /dev/disk3 # eject SD card, insert at your pi and boot your pi...
  2. 24 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    wget https://raw.githubusercontent.com/hypriot/flash/master/$(uname -s)/flas chmod +x flash sudo mv flash /usr/local/bin/flash brew install pv brew install awscli $ flash help ... --config|-c Copy this config file to /boot/occidentalis.txt --hostname|-n Set hostname for this SD image --ssid|-s Set WiFi SSID for this SD image --password|-p Set WiFI password for this SD image ... $ flash --hostname rpi-001 \ http://downloads.hypriot.com/hypriot-rpi-20150416-201537.img.zip
  3. 25 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ ssh root@rpi-001 > mkdir -f .ssh > chmod 700 .ssh > exit $ scp ${HOME}/.ssh/id_rsa.pub root@rpi-001:/root/.ssh/authorized_keys $ ssh root@rpi-001 > chmod 600 .ssh/authorized_keys
  4. 26 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    # update to current docker version $ wget http://downloads.hypriot.com/docker-hypriot_1.8.1-1_armhf.deb $ dpkg -i docker-hypriot_1.8.1-1_armhf.deb $ service docker restart $ docker version Client: Version: 1.8.1 API version: 1.20 Go version: go1.4.2 Git commit: d12ea79-dirty Built: Thu Aug 13 07:53:24 UTC 2015 OS/Arch: linux/arm Server: Version: 1.8.1 API version: 1.20 Go version: go1.4.2 Git commit: d12ea79-dirty Built: Thu Aug 13 07:53:24 UTC 2015 OS/Arch: linux/arm
  5. 27 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker info Containers: 2 Images: 84 Storage Driver: overlay Backing Filesystem: extfs Execution Driver: native-0.2 Logging Driver: json-file Kernel Version: 3.18.11-hypriotos-v7+ Operating System: Raspbian GNU/Linux 7 (wheezy) CPUs: 4 Total Memory: 925.1 MiB Name: black-pearl ID: V57A:JOG4:5GRL:WKXF:BL2H:ZCFS:MGIF:6M3V:XD2I:FS6M:TXGU:6HRF Labels: provider=hypriot
  6. 28 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker pull resin/rpi-raspbian:jessie $ docker run --rm -ti resin/rpi-raspbian > cat /etc/os-release PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)" NAME="Raspbian GNU/Linux" VERSION_ID="8" VERSION="8 (jessie)" ID=raspbian ID_LIKE=debian HOME_URL="http://www.raspbian.org/" SUPPORT_URL="http://www.raspbian.org/RaspbianForums" BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
  7. 29 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker search hypriot hypriot/rpi-node RPi-compatible Docker Image with Node.js hypriot/rpi-iojs RPi-compatible Docker Image with io.js hypriot/rpi-java RPi-compatible Docker Image with Java hypriot/rpi-python RPi-compatible Docker Image with Python hypriot/rpi-golang hypriot/rpi-busybox-httpd Raspberry Pi compatible Docker Image with ... hypriot/rpi-gpio Dockerized gpio binary of wiringPi for the ... hypriot/rpi-ruby RPi-compatible Docker Image with Ruby hypriot/rpi-hugo Raspberry Pi compatible Docker Image with ... hypriot/rpi-crate RPi-compatible Docker Image with Crate.io hypriot/rpi-drone Raspberry Pi compatible Docker Image with ... hypriot/rpi-alpine-scratch Raspberry Pi compatible Docker Image with ... hypriot/rpi-haproxy Haproxy Dockerfile hypriot/rpi-gogs-raspbian Raspberry Pi compatible Docker Image with ... hypriot/rpi-swarm Raspberry Pi compatible Docker image with ... hypriot/rpi-mysql RPi-compatible Docker Image with Mysql hypriot/rpi-gogs-alpine Raspberry Pi compatible Docker Image with ... gdelpu/rpi-hypriot-node-hapi NodeJs with HapiJs framework hypriot/rpi-nano-httpd Raspberry Pi nano sized HTTP server hypriot/skydns hypriot/rpi-redis hypriot/rpi-skydns
  8. 38 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    aptitude install python python-pip git clone https://github.com/docker/compose.git cd compose git checkout 1.4.0 pip install . $ cd /etc/bash-completion.d $ rm docker $ URL_BASE=https://raw.githubusercontent.com/docker $ wget $(URL_BASE)/docker/master/contrib/completion/bash/docker $ wget $(URL_BASE)/compose/master/contrib/completion/bash/docker-compose # login again! $ exit $ ssh root@rpi-001
  9. 39 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    FROM hypriot/rpi-java MAINTAINER Peter Rossbach <[email protected]> @PRossbach ENV TOMCAT_MINOR_VERSION=8.0.26 \ CATALINA_HOME=/opt/tomcat \ TOMCAT_URL=http://archive.apache.org/dist/tomcat/tomcat-8 RUN DEBIAN_FRONTEND=noninteractive apt-get update \ && apt-get install -y \ curl \ --no-install-recommends \ && rm -rf /var/lib/{apt,dpkg,cache,log}/ ...
  10. 40 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    ... RUN curl -O ${TOMCAT_URL}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-\ ${TOMCAT_MINOR_VERSION}.tar.gz \ && curl ${TOMCAT_URL}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-\ ${TOMCAT_MINOR_VERSION}.tar.gz.md5 | md5sum -c - \ && tar xzf apache-tomcat-*.tar.gz \ && rm apache-tomcat-*.tar.gz* && mv apache-tomcat* ${CATALINA_HOME} \ && rm -rf ${CATALINA_HOME}/webapps/* \ ${CATALINA_HOME}/RELEASE-NOTES ${CATALINA_HOME}/RUNNING.txt \ ${CATALINA_HOME}/bin/*.bat ${CATALINA_HOME}/bin/*.tar.gz WORKDIR /opt/tomcat EXPOSE 8080 EXPOSE 8009 ENTRYPOINT [ "/opt/tomcat/bin/catalina.sh" ] CMD ["run"]
  11. 41 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    tomcat: build: . volumes: - "./status:/opt/tomcat/webapps/status" docker-compose build docker-compose up -d
  12. 42 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ IP=$(docker inspect --format \ "{{ .NetworkSettings.IPAddress }}" tomcat_tomcat_1) $ curl -sL http://${IP}:8080/status hello Mon Aug 31 09:58:37 UTC 2015 $ docker exec -ti tomcat_tomcat_1 java -version java version "1.7.0_65" OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-2~deb7u1+rpi1) OpenJDK Zero VM (build 24.65-b04, mixed mode) $ sudo ntpdate -u ptbtime2.ptb.de docker pull infrabricks/tomcat:rpi-8.0.24
  13. 43 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    FROM resin/rpi-raspbian:jessie MAINTAINER Peter Rossbach <[email protected]> @PRossbach RUN DEBIAN_FRONTEND=noninteractive apt-get update \ && apt-get install -y \ wget pwgen curl openjdk-8-jre \ --no-install-recommends \ && apt-get clean autoclean \ && apt-get autoremove -y \ && rm -rf /var/lib/{apt,dpkg,cache,log}/ WORKDIR /data ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-armhf ENTRYPOINT [ "/usr/bin/java" ] CMD ["-version"]
  14. 44 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    FROM resin/rpi-raspbian:jessie MAINTAINER Peter Rossbach <[email protected]> @PRossbach RUN DEBIAN_FRONTEND=noninteractive \ echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" \ | tee -a /etc/apt/sources.list \ && echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" \ | tee -a /etc/apt/sources.list \ && apt-key adv --keyserver keyserver.ubuntu.com \ --recv-keys EEA14886 && apt-get update \ && echo oracle-java8-installer shared/accepted-oracle-license-v1-1 \ select true | debconf-set-selections \ && apt-get install -y oracle-java8-installer wget pwgen curl oracle-java8-installer \ --no-install-recommends \ && rm /usr/lib/jvm/java-8-oracle/src.zip \ && apt-get clean autoclean \ && apt-get autoremove -y \ && rm -rf /var/lib/{apt,dpkg,cache,log}/ RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LC_CTYPE en_US.UTF-8 WORKDIR /data ENV JAVA_HOME /usr/lib/jvm/java-8-oracle ENTRYPOINT [ "/usr/bin/java" ] CMD ["-version"]
  15. 45 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker run --cap-add SYS_RAWIO --device /dev/mem # or more ... $ docker run --privileged
  16. 46 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    tomcat1: image: tomcat_tomcat volumes: - "./status:/opt/tomcat/webapps/status" tomcat2: image: tomcat_tomcat volumes: - "./status:/opt/tomcat/webapps/status" haproxy: image: hypriot/rpi-haproxy volumes: - "./haproxy:/haproxy-override" links: - tomcat1 - tomcat2 ports: - "8080:80" - "7070:70"
  17. 47 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    global log 127.0.0.1 local0 log 127.0.0.1 local1 notice defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 10000 timeout server 10000 listen stats :70 stats enable stats uri / ...
  18. 48 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    ... frontend balancer bind 0.0.0.0:80 mode http default_backend tc_backends backend tc_backends mode http option forwardfor # http-request set-header X-Forwarded-Port %[dst_port] balance roundrobin server tomcat1 tomcat1:8080 check server tomcat2 tomcat2:8080 check # option httpchk OPTIONS * HTTP/1.1\r\nHost:\ localhost option httpchk GET /status/index.jsp http-check expect status 200
  19. 55 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ wget http://downloads.hypriot.com/docker-machine_0.4.0-dev_darwin-amd64 $ chmod +x docker-machine_0.4.0-dev_darwin-amd64 $ ln -sf docker-machine_0.4.0-dev_darwin-amd64 docker-machine $ export PATH=$(pwd):$PATH
  20. 56 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker-machine create -d hypriot \ --hypriot-ip-address=192.168.178.109 \ rpi-001 # Update to newest docker engine! $ ssh [email protected] > wget http://downloads.hypriot.com/docker-hypriot_1.8.1-1_armhf.deb > dpkg -i docker-hypriot_1.8.1-1_armhf.deb > service docker restart > exit
  21. 57 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ cd ~/bin $ docker-machine ls INFO[0000] Creating CA: /Users/peter/.docker/machine/certs/ca.pem INFO[0001] Creating client certificate: /Users/peter/.docker/machine/certs/c NAME ACTIVE DRIVER STATE URL $ ls -a .docker/machine/certs ca-key.pem ca.pem cert.pem key.pem server-key.pem server.pem
  22. 58 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker-machine ls NAME ACTIVE DRIVER STATE URL rpi-master virtualbox Running tcp://192.168.99.100:2376 (master) rpi-001 * hypriot Running tcp://192.168.99.109:2376 $ docker-machine config rpi-001 --tlsverify --tlscacert="/Users/peter/.docker/machine/machines/rpi-001/ca.pem" --tlscert="/Users/peter/.docke $ docker $(docker-machine config rpi-001) ps $ docker $(docker-machine config rpi-001) run \ --rm hypriot/rpi-alpine-scratch /bin/sh -c "echo hello machine \$(hostname)" Unable to find image 'hypriot/rpi-alpine-scratch:latest' locally hypriot/rpi-alpine-scratch:latest: The image you are pulling has been verified 511136ea3c5a: Pull complete df7546f9f060: Pull complete ea13149945cb: Pull complete 4986bf8c1536: Pull complete Status: Downloaded newer image for busybox:latest hello machine 117ade53e1d6 $ docker $(docker-machine config rpi-001) images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE hypriot/rpi-alpine-scratch latest 9566b98023b5 8 weeks ago 4.971 MB
  23. 59 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker-machine ssh rpi-001 Linux rpi-001 3.18.11-hypriotos-v7+ #2 SMP PREEMPT Sun Apr 12 16:34:20 UTC 2 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Mon Aug 31 12:47:02 2015 from heisenberg-2.fritz.box HypriotOS: root@rpi-001 in ~
  24. 66 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker pull swarm # docker pull hypriot/rpi-swarm $ docker run --rm swarm create <SWARM_TOKEN> $ docker run -d -p 3376:2376 swarm manage \ <TLS CONFIG> token://<SWARM_TOKEN> $ docker run -d swarm join \ --addr=<node_ip:2376> token://<cluster_id>
  25. 67 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    # TOKEN=$(docker run --rm -ti swarm create) $ docker-machine create -d hypriot \ --hypriot-ip-address=192.168.178.94 \ --swarm \ --swarm-image "hypriot/rpi-swarm" \ --swarm-discovery token://${TOKEN} \ rpi-master $ ssh [email protected] > wget http://downloads.hypriot.com/docker-hypriot_1.8.1-1_armhf.deb > dpkg -i docker-hypriot_1.8.1-1_armhf.deb > service docker restart > exit
  26. 68 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ ssh root@rpi-001 $ docker pull hypriot/rpi-golang $ mkdir -p swarm $ docker run -ti -v $(pwd)/swarm:/app hypriot/rpi-golang $ go get -d github.com/docker/swarm $ go get github.com/tools/godep $ cd $GOPATH/src/github.com/docker/swarm $ CGO_ENABLED=0 GOOS=linux godep go build -a -tags netgo -ldflags '-w' . $ cp swarm /app/swarm # if work.. $ exit
  27. 69 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ cat >Dockerfile <<EOF FROM hypriot/rpi-alpine-scratch MAINTAINER Peter Rossbach [email protected] COPY swarm /swarm RUN apk update \ && apk add ca-certificates \ && rm -rf /var/cache/apk/* \ && ln -s /lib/ld-musl-armhf.so.1 /lib/ld-linux-armhf.so.3 ENV SWARM_HOST :2375 EXPOSE 2375 VOLUME /.swarm ENTRYPOINT ["/swarm"] CMD ["--help"] EOF $ docker build -t infrabricks/rpi-swarm:0.4.0 . $ docker run -ti --rm infrabricks/rpi-swarm:0.4.0
  28. 72 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    docker run -m 256m ... docker run -c 1 ... docker run -p 80:80 ...
  29. 73 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ eval $(docker-machine env rpi-master) $ docker run -c 1 -p 9082:8080 -d infrabricks/tomcat:rpi-8.0.24 35d50a29ed0fde780c0826ef16ff24d2582609f877ee092c780d9aeb6f27fc75 $ docker ps CONTAINER ID IMAGE COMMAND CREATED \ STATUS PORTS NAMES 35d50a29ed0f infrabricks/tomcat:rpi-8.0.24 "catalina.sh run" 16 minutes ago\ Up Less than a second 192.168.33.89:9082->8080/tcp \ rpi-001/insane_brattain $ docker run -c 1 -p 9083:8080 -d infrabricks/tomcat:rpi-8.0.24 f5bc6a274e82426df98eaca5e88fb01f43e03455dfebdb9ee4a3b00a7eab202e $ docker ps CONTAINER ID IMAGE COMMAND CREATED\ STATUS PORTS NAMES f5bc6a274e82 infrabricks/tomcat:rpi-8.0.24 "catalina.sh run" 16 minutes ago\ Up Less than a second 192.168.33.90:9083->8080/tcp \ rpi-002/stupefied_albattani 35d50a29ed0f infrabricks/tomcat:rpi-8.0.24 "catalina.sh run" 17 minutes ago\ Up Less than a second 192.168.33.89:9082->8080/tcp \ rpi-001/insane_brattain ...
  30. 74 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    lsb_release -a DOCKER_OPTS="--label region=de-berlin \ --label storage=ssd-vdi \ --label role=loadbalancer" docker -d ${DOCKER_OPTS} --label stage=prod docker run -e "constraint:provider==hypriot" ... docker run -e "constraint:storagedriver==aufs" ... docker run -e "constraint:region==de-berlin" ... docker run -e "constraint:node!=rpi-master" ... constraint:node==/rpi-00[12]/ constraint:node!=app* constraint:node==/(?i)rpi-001/
  31. 75 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    docker run -d -p 80:80 --name front nginx docker run -e "affinity:container==front" logger docker run -e "affinity:image==redis" redis docker run -d -p 80:80 --label com.example.type=frontend nginx docker run -d -e affinity:com.example.type==frontend logger docker run -d --name redis1 -e affinity:image==~redis redis docker run -d --name redis2 -e constraint:region==~us* redis docker run -d --name redis5 -e affinity:container!=~redis* redis
  32. 76 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    --volumes-from=dependency --link=dependency:alias network stack: --net=container:dependency
  33. 77 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    DOT=XYZ docker pull swarm SWARM_TOKEN=$(docker run --rm swarm create) echo $SWARM_TOKEN >token.txt docker-machine create \ --driver digitalocean \ --digitalocean-region fra1 \ --digitalocean-size 1gb \ --digitalocean-access-token $DOT \ --digitalocean-private-networking \ --swarm \ --swarm-master \ --swarm-discovery token://$SWARM_TOKEN \ --engine-label zone=prod \ --engine-label swarm=master \ swarm-master
  34. 78 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    docker-machine create \ --driver digitalocean \ --digitalocean-region fra1 \ --digitalocean-size 1gb \ --digitalocean-access-token $DOT \ --digitalocean-private-networking \ --swarm \ --swarm-discovery token://$SWARM_TOKEN \ --engine-label zone=prod \ --engine-label swarm=node \ swarm-node-001
  35. 81 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ ssh root@rpi-master $ git clone https://github.com/hypriot/rpi-consul $ cd rpi-consul $ make $ cd .. $ mkdir -p orchestration $ cat >docker-compose.yml <<EOF consul: image: hypriot/rpi-consul ports: - "8400:8400" - "8500:8500" - "8600:53/udp" volumes: - "./config:/config" - "./data:/data" environment: GOMAXPROCS: 2 command: agent -server -config-dir=/config -data-dir=/data -client=0.0.0.0 -ui-dir=/web EOF
  36. 82 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    mkdir -p config cat >config/consul.json <<EOF { "datacenter": "rpi", "data_dir": "/data", "ui_dir": "/web-ui", "client_addr": "0.0.0.0", "ports": { "dns": 53 }, "recursor": "8.8.8.8", "disable_update_check": true, "check_update_interval": "0s" } EOF docker-compose up -d
  37. 84 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    FROM hypriot/rpi-alpine-scratch ENTRYPOINT ["/bin/registrator"] RUN apk update \ && apk add build-base go git mercurial \ && mkdir -p /go/src/github.com/gliderlabs && cd /go/src/github.com/glide && git clone https://github.com/gliderlabs/registrator \ && cd registrator \ && export GOPATH=/go \ && go get \ && go build -ldflags "-X main.Version $(cat VERSION)" -o /bin/registrato && rm -rf /go \ && apk del --purge build-base go git mercurial
  38. 86 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    tomcat: image: infrabricks/tomcat:rpi-8.0.24 ports: - "8080" volumes: - tomcat-users.xml:/opt/tomcat/conf/tomcat-users.xml environment: - constraint:zone==dev - constraint:swarm==node SERVICE_8080_NAME: status-http SERVICE_REGION: bee42.1 SERVICE_8080_CHECK_HTTP: /status/ping.jsp SERVICE_8080_CHECK_INTERVAL: 30s
  39. 87 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    status: image: infrabricks/status tomcatblue: extends: file: common.yml service: tomcat volumes_from: - status environment: SERVICE_TAGS: tomcat,blue
  40. 88 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    status: image: infrabricks/status tomcatgreen: extends: file: common.yml service: tomcat volumes_from: - status environment: SERVICE_TAGS: tomcat,green
  41. 99 / 107 © 2015 <[email protected]>, @PRossbach, IOT Berlin 2015

    $ docker run -d -p 8000:80 rossbachp/docker-rpi:iot-2015 $ open http://<docker host>:8000/docker-rpi