naveen chawla
naveen chawla

Reputation: 33

docker-compose : Scaling containers with distinct host volume map

  1. Here, I deployed 2 containers with --scale flag
docker-compose up -d --scale gitlab-runner=2

2.Two containers are being deployed with names scalecontainer_gitlab-runner_1 and scalecontainer_gitlab-runner_2 resp.

  1. I want to map different volume for each container.
/srv/gitlab-runner/config_${DOCKER_SCALE_NUM}:/etc/gitlab-runner
  1. Getting this error:
WARNING: The DOCKER_SCALE_NUM variable is not set. Defaulting to a blank string.
  1. Is there any way, I can map different volume for separate container .
services:
  gitlab-runner:
    image: "gitlab/gitlab-runner:latest"
    restart: unless-stopped
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - /srv/gitlab-runner/config_${DOCKER_SCALE_NUM}:/etc/gitlab-runner
version: "3.5"

Upvotes: 3

Views: 2371

Answers (1)

kthompso
kthompso

Reputation: 2422

I don't think you can, there's an open request on this here. Here I will try to describe an alternative method for getting what you want.

Try creating a symbolic link from within the container that links to the directory you want. You can determine the "number" of the container after it's constructed by reading the container name from docker API and taking the final segment. To do this you have to mount the docker socket into the container, which has big security implications.

Setup

Here is a simple script to get the number of the container (Credit Tony Guo).

get-name.sh

DOCKERINFO=$(curl -s --unix-socket /run/docker.sock http://docker/containers/$HOSTNAME/json)
ID=$(python3 -c "import sys, json; print(json.loads(sys.argv[1])[\"Name\"].split(\"_\")[-1])" "$DOCKERINFO")
echo "$ID"

Then we have a simple entrypoint file which gets the container number, creates the specific config directory if it doesn't exist, and links its specific config directory to a known location (/etc/config in this example).

entrypoint.sh

#!/bin/sh

# Get the number of this container
NAME=$(get-name)
CONFIG_DIR="/config/config_${NAME}"

# Create a config dir for this container if none exists
mkdir -p "$CONFIG_DIR"
# Create a sym link from a well known location to our individual config dir
ln -s "$CONFIG_DIR" /etc/config

exec "$@"

Next we have a Dockerfile to build our image, we need to set the entrypoint and install curl and python for it to work. Also copy in our get-name.sh script.

Dockerfile

FROM alpine

COPY entrypoint.sh entrypoint.sh
COPY get-name.sh /usr/bin/get-name

RUN apk update && \
    apk add \
        curl \
        python3 \
        && \
    chmod +x entrypoint.sh /usr/bin/get-name

ENTRYPOINT ["/entrypoint.sh"]

Last, a simple compose file that specifies our service. Note that the docker socket is mounted, as well as ./config which is where our different config directories go.

docker-compose.yml

version: '3'

services:
  app:
    build: .
    command: tail -f
    volumes:
      - /run/docker.sock:/run/docker.sock:ro
      - ./config:/config

Example

# Start the stack
$ docker-compose up -d --scale app=3
Starting volume-per-scaled-container_app_1 ... done
Starting volume-per-scaled-container_app_2 ... done
Creating volume-per-scaled-container_app_3 ... done

# Check config directory on our host, 3 new directories were created.
$ ls config/
config_1  config_2  config_3

# Check the /etc/config directory in container 1, see that it links to the config_1 directory
$ docker exec volume-per-scaled-container_app_1 ls -l /etc/config
lrwxrwxrwx    1 root     root            16 Jan 13 00:01 /etc/config -> /config/config_1

# Container 2
$ docker exec volume-per-scaled-container_app_2 ls -l /etc/config
lrwxrwxrwx    1 root     root            16 Jan 13 00:01 /etc/config -> /config/config_2

# Container 3
$ docker exec volume-per-scaled-container_app_3 ls -l /etc/config
lrwxrwxrwx    1 root     root            16 Jan 13 00:01 /etc/config -> /config/config_3

Notes

  • I think gitlab/gitlab-runner has its own entrypoint file so you may need to chain them.
  • You'll need to adapt this example to your specific setup/locations.

Upvotes: 2

Related Questions