docker compose

Version 2

version: '2'
services:
  postgis:
    build: ./postgis
    volumes:
      - ./data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=gis
    ports:
      - "5432:5432"
  renderer:
    build: ./renderer
    volumes:
      - ./renderer/map_data:/map_data
      - ./renderer/scripts:/scripts
    volumes_from:
      - postgis:ro
    ports:
      - "8080:8080"
      - "9090:9090"
    depends_on:
      - postgis
  web:
    build: ./web
    volumes:
      - ./web:/usr/share/nginx/html
    ports:
      - "8888:80"

Version 3

version: "3"
services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        constraints: [node.role == manager]

  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

networks:
  frontend:
  backend:

volumes:
  db-data:

3.5

Better networking ... syntax slightly changed also.

The Container that creates the network looks like this

Proxy-container

version: "3.5"
services:

        proxy:
                build: ./docker-apt-cacher
                volumes:
                  - ./proxydata:/var/cache/apt-cacher
                ports:
                  - "3142"
                #This has a network of proxy_default
                networks:
                  - my-network-name

networks:
  my-network-name:
   name: my-global-net

Another project that uses this network would look like this

Using the Proxy....

version: '3.5'
services:
  test:
    build: ./test
    networks:
      - my-network-name

    stdin_open: true
    tty: true

networks:
  my-network-name:
   name: my-global-net

3.5 Volumes and Networks

The syntax is a little different. We are sharing data via a Volume. The Volume is called pgdata. It is used in 2 containers at the same time

  • postgis
  • renderer

Renderer still using a local volume being mounted into the other machine.

I had to build these containers individually as the --network my-global-net seemed to cause an issue in the docker-compose. Not sure why this is.

version: '3.5'
services:
  postgis:
    build: ./postgis
    volumes:
      - type: volume
        source: pgdata
        target: /var/lib/postgresql/data
        volume:
          nocopy: true
    environment:
      - POSTGRES_DB=gis
    ports:
      - "5432:5432"
    networks:
      - my-network-name
  renderer:
    build: ./renderer
    volumes:
      - ./renderer/map_data:/map_data
      - ./renderer/scripts:/scripts
      - pgdata:/var/lib/postgresql/data
    ports:
      - "8080:8080"
      - "9090:9090"
    depends_on:
      - postgis
    networks:
      - my-network-name
  web:
    build: ./web
    volumes:
      - ./web:/usr/share/nginx/html
    ports:
      - "8888:80"
    depends_on:
      - postgis
    networks:
      - my-network-name

volumes:
  pgdata:

networks:
  my-network-name:
   name: my-global-net

Showing more config options for the machines

version: "3"
services:
  web:
    image: webserver
    deploy:
      replicas: 2
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 5
        window: 20s
      resources:
        limits:
          cpus: "0.2"
          memory: 50M
    depends_on:
      - memcached-server
      - visualizer
    ports:
      - "5000:5000"
    networks:
      - webnet
    hostname: webserver
  memcached:
    image: memcached
    deploy:
      resources:
        limits:
          memory: 100M
    ports:
      - "11211:11211"
    networks:
      - webnet
    hostname: memcached
networks:
  webnet:

3.5 Two Containers - shared storage and network

A Simple framework for 2 containers which work (somehow) together.

They share a Volume on /mnt/data and share a network using the network-name of

version: "3.3"
services:

  server1:
    build: ./server1
    volumes:
      - type: "volume"
        source: shareddrive1
        target: /mnt/data
    ports:
      # External:Internal
      - "1234:80"
    networks:
       - net

#    deploy:
#      replicas: 2
#      update_config:
#        parallelism: 2
#      restart_policy:
#        condition: on-failure

  server2:
    build: ./server2
    volumes:
     - type: volume
       source: shareddrive1
       target: /mnt/data
    ports:
      # External:Internal
      #Needs to be different as CONTAINER will have same IP Address
      - "1235:80"
    networks:
       - net
#    deploy:
#      replicas: 2
#      update_config:
#        parallelism: 2
#      restart_policy:
#        condition: on-failure

volumes:
    shareddrive1:

networks:
  net:

The docker file (for both) is

from UBUNTU:16.04
maintainer tim@sy-edm.com

And the run file looks like

#!/bin/bash

#This is a run file - which should be used to add things you want your 
#container to do when you start it up
#
#If you do not have this then ...
#  docker-compose up ---- simply exists as there is nothing for the container to do.



trap cleanup 1 2 3 6 9 15

cleanup()
{
  echo "Caught Signal ... cleaning up."
  sleep 1s
  echo "Done  ... quitting."
  exit 1
}

# wait forever
while true
do
  tail -f /dev/null & wait ${!}
done

Docker DXCC Flask Project

I was playing on the plane with running Flask (Python Framework) - to render DXCC Beacons.

The Flask part is not really the issue - the Docker was more tricky

Dockerimage

This is my build file - for the docker Image. It is more painful that you think as I was running this on a Plane with no Internet.

Else a requirements.txt and a pip install -r would have sorted 90% of this out.

The run.sh is a my usual script except it run the app.py flask startup.

from frolvlad/alpine-python3
maintainer tim@sy-edm.com

run mkdir /dxcc_server
copy dxcc_web.tar.gz /dxcc_server
copy server.py /dxcc_server
copy client.py /dxcc_server

run cd /dxcc_server && \
    tar -zxvf dxcc_web.tar.gz && \
    mkdir /mypypi

# We need to add some Python Modules now
# I am writing this on a plane !! so no Internet access so I am adding modules
# from my Private PyPi cache
WORKDIR /mypypi
copy *.whl /mypypi/
copy *.gz /mypypi/
#My Custom Module
copy Ham-1.0.0.13.tar.gz /mypypi/
copy run.sh /usr/local/bin/
run pip3 install --no-index --find-links /mypypi Flask-0.12.2-py2.py3-none-any.whl &&\
    pip3 install --no-index --find-links /mypypi Flask-Bootstrap-3.3.7.1.tar.gz   &&\
    pip3 install --no-index --find-links /mypypi serial   &&\
    pip3 install --no-index --find-links /mypypi Ham-1.0.0.13.tar.gz   &&\
    chmod +x /usr/local/bin/run.sh

CMD /usr/local/bin/run.sh

Docker-Compose.yml

This is my Docker-Compose.yml file

version: "3"
services:
  dxcc:
    build: ./dxcc
    ports:
      - "50:5000"
      - "51:5001"

    hostname: dxcc
    networks:
      - dxcc

networks:
  dxcc:

Please note:

I On the HOST Machine I have 2 Ports 50,51 which get mapped to the Docker Container on 5000,5001

The Flask Web Server is running on 5000 - the other port was a custom Python Network Client/Server process that I wrote in order to debug this process.

On the Host Machine this is accessed from 127.0.0.1:50 and 127.0.0.1:51 - not the 0.0.0.0 As I had been doing earlier.

Processes inside the Docker Container.

All Network Interfaces which you wish to accept outside connections to/from should listen on '0.0.0.0' not '127.0.0.0'

Why ? the 127.0.0.1 is only the loopback interface, where as the 0.0.0.0 are all interfaces on the Docker container.

Neat Trip

docker-composer up --build

Does it all in 1 go .... good for the lazy programmer.