docker-compose → set wildcard domain name for linked container

Viewed 406

I have two containers: application and MINIO service

Let's say docker-compose.yml is:

version: "3"

services:
  s3:
    image: minio/minio:RELEASE.2021-11-09T03-21-45Z
    expose:
     - "9000"
     - "9001"
    container_name: s3
    command: server /data --console-address ":9001"
    environment:
     - MINIO_DOMAIN=s3
     - MINIO_ROOT_USER=some_user
     - MINIO_ROOT_PASSWORD=some_password
    healthcheck:
     test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
     interval: 30s
     timeout: 20s
     retries: 3
    volumes:
     - /tmp/data:/data

  app:
    image: my_image
    container_name: app
    build:
      context: .
      dockerfile: ./Dockerfile
    depends_on:
      - s3

app container connecting to MINIO via http://s3:9000 endpoint URL

When I run

aws --profile myprof --endpoint-url="http://s3:9000" s3 ls  s3://bucketname/path/to/file

all works fine.

But some of third-party libraries needed for my app using virtual-host styled path:

http://bucketname.s3:9000/path/to/file

And of course bucketname.s3 can't be resolved.

I tried to set 172.19.0.4 bucketname.s3 (container local IP) inside /etc/hosts and all works fine. But I can't update /etc/hosts every time for every new bucket.

So is here any way to set wildcard hostname *.s3 in docker?

My application use python:3.7.0-alpine image

Result of cat /etc/resolv.conf is

nameserver 127.0.0.11
options edns0 ndots:0

So looks like it is possible to set domain inside local host resolver service by using Dockerfile, is here some way to do that?

Memo added 2022/01/25

I added network alias to s3 container as temporary solution to be able add exact bucket names at docker-compose up -d timing, but that is not a solution because I still can't create new buckets on the fly without restart containers:

version: "3"

services:
  s3:
    image: minio/minio:RELEASE.2021-11-09T03-21-45Z
    expose:
     - "9000"
     - "9001"
    container_name: s3
    command: server /data --console-address ":9001"
    environment:
     - MINIO_DOMAIN=s3
     - MINIO_ROOT_USER=some_user
     - MINIO_ROOT_PASSWORD=some_password
    healthcheck:
     test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
     interval: 30s
     timeout: 20s
     retries: 3
    volumes:
     - /tmp/data:/data
    networks:
      default:
        aliases:
         - bucketone.s3
         - buckettwo.s3

Also I tried to set record inside external separated DNS server:

*.s3  IN CNAME  s3.

But this way is not working too. Looks like container trying to resolve s3. by using same DNS server instead of use Docker internal DNS resolver (where s3 host exists). So looks like only possible solution is to set DNS server integrated with Docker that can manage container internal dynamic IPs and records

1 Answers

(This might be not the best answer, but probably better than nothing).

I already had a custom DNS server on the host system (in my case, Acrylic). What I did as a quick fix:

  1. from the depending app container: ping anotherservice.loc (to get the service container's IP, in my case it was 172.18.0.7)
  2. on the own DNS server, added an entry 172.18.0.7 *.anotherservice.loc and restarted the DNS
  3. optionally, cleared host system DNS cache: ipconfig /flushdns (this command is for Windows)

In theory:

  • maybe you could hardcode this IP in docker-compose.yml, to avoid the need to edit DNS settings, in case Docker changes it in future. Or,
  • maybe you could find and set up a custom DNS server inside the depending container instead. There is some space for creativity here, I just tried to give the idea.
Related