Toadicus Rex
Toadicus Rex

Reputation: 45

Sharing a core docker container between solutions

I am building several microservices that will be communicating with each other via rabbitmq and ocelot. Each microservice's codebase is in a separate git repository and code is shared only via an internal nuget server, with nugets being built by each solution (exposed DTOs and a sample .NET client for each API). What I am trying to do is set it up so all of the microservices can be started and run from visual studio 2019 with the least amount of tweaking - and all of them are trying to use a single rabbitmq container.

NOTE: the fact that this is rabbitmq is incidental. I could interchange that with any other type of public container with the same result.

What I'd like to do is have the ability to specify the named rabbitmq container in a docker-compose file that is part of each solution; if the rabbitmq container exists, I'd hope that the VS instance would just use it, rather than trying to create a new container.

After having created the docker-compose and adding the rabbitmq instance, I find if I try to debug into the solution that one (the second one to be built) won't build or run because the named rabbitmq instance already exists - so I can't run both solutions, and that prevents me from testing the interaction between them over the rabbit instance... etc.

I'm simply declaring the rabbit instance like so:

mycompany.mydomain.rabbitmq: ports: - "15672:15672" - "5672:5672"

So the expected result is that I can just use the rabbitmq instance. One solution would be to simply run the container from the command line or whatever, I'm just hoping for a simple plug'n'play approach. Any ideas, docker gods? I'm not using kubernetes yet but plan to, just using docker compose to bootstrap.

Upvotes: 1

Views: 157

Answers (1)

atline
atline

Reputation: 31654

What I suggest is to use a wrapper service in all your different projects to control just use one same rabbitmq instance. Example as next:

File structure:

shubuntu1@shubuntu1:~/mic$ tree
.
├── prj1
│   └── docker-compose.yaml
├── prj2
│   └── docker-compose.yaml
└── wrapper
    ├── docker-entrypoint.sh
    └── Dockerfile

3 directories, 4 files

wrapper/Dockerfile:

FROM alpine

# install docker client in wrapper container
RUN wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.0.tgz && \
    tar zxvf docker-19.03.0.tgz && \
    cp -rf docker/docker /bin && \
    rm -fr docker-19.03.0.tgz docker

COPY . /
RUN chmod +x /docker-entrypoint.sh

CMD ["shared-rabbitmq"]
ENTRYPOINT ["/docker-entrypoint.sh"]

wrapper/docker-entrypoint.sh:

#!/bin/sh
shared_rabbitmq_name=$1

docker inspect $shared_rabbitmq_name > /dev/null 2>&1
if [ $? -ne 0 ]; then
    docker run -d --name $shared_rabbitmq_name rabbitmq
fi

prj1/docker-compose.yaml:

version: '3'

services:
  rabbitmq_wrapper:
    build: ../wrapper
    image: rabbitmq_wrapper
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  nginx:
    image: nginx

prj2/docker-compose.yaml:

version: '3'

services:
  rabbitmq_wrapper:
    build: ../wrapper
    image: rabbitmq_wrapper
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

  nginx:
    image: nginx

With above, in any project folder, prj1 or prj2 to execute docker-compose up -d, it will launch 2 different nginx container(This simulated your different applications/solutions). But they will just start one rabbitmq container with the name shared-rabbitmq, if prj1 already start this container, the prj2 will just use this container not start a new container as it has did a detect in docker-entrypoint.sh to see if the one rabbitmq container already start, the unique rabbitmq container only start when no one available there.

Final sample output:

shubuntu1@shubuntu1:~/mic/prj1$ docker-compose up -d
Creating prj1_nginx_1            ... done
Creating prj1_rabbitmq_wrapper_1 ... done
shubuntu1@shubuntu1:~/mic/prj1$ cd ..
shubuntu1@shubuntu1:~/mic$ cd prj2
shubuntu1@shubuntu1:~/mic/prj2$ docker-compose up -d
Creating prj2_rabbitmq_wrapper_1 ... done
Creating prj2_nginx_1            ... done
shubuntu1@shubuntu1:~/mic/prj2$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
fb8739a4fe4d        nginx               "nginx -g 'daemon of…"   6 seconds ago       Up 2 seconds        80/tcp                               prj2_nginx_1
a98346ecb6f2        rabbitmq            "docker-entrypoint.s…"   14 seconds ago      Up 11 seconds       4369/tcp, 5671-5672/tcp, 25672/tcp   shared-rabbitmq
238973fd85f1        nginx               "nginx -g 'daemon of…"   17 seconds ago      Up 12 seconds       80/tcp                               prj1_nginx_1

Upvotes: 1

Related Questions