Docker Community Forums

Share and learn in the Docker community.

Networking problem in compose file

I need 2 networks in my compose file, 1 for main service to connect to mysql and another for main service to connect to proxy.
Proxy is common to many other compose files so I don’t want mysql on that network.
In my case I need to connect to mysql using monica_backend and to the proxy using proxy-proxy-tier.
If I comment out the proxy network in the mysql service monica can’t connect to mysql.

So here’s the file:

"version: "3.4"

  services:
  app:
    image: monica
    depends_on:
      - db
    environment:
      - APP_KEY=xxx
      - DB_HOST=db
      - VIRTUAL_HOST=xxx.xxx.com
      - LETSENCRYPT_HOST=xxx.xxx.com
      - LETSENCRYPT_EMAIL=xxxxxx
 
    volumes:
      - ./data:/var/www/html/storage
    restart: always
    networks:
      monica_backend:
      proxy_proxy-tier:


  db:
    image: mysql:5.7
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=true
      - MYSQL_DATABASE=xxx
      - MYSQL_USER=xxx
      - MYSQL_PASSWORD=xxx
    volumes:
      - ./mysql:/var/lib/mysql
    restart: always
    networks:
      monica_backend:
commented out     proxy_proxy-tier:  (not sure how to make # come out in markdown)

networks:
  monica_backend:
    driver: bridge  
  proxy_proxy-tier:
    external: true"


When I do a docker-compose up and look at the scrolling logs it says “can’t connect to mysql:3306”. If I remove the comment before the proxy network in the db service monica can connect.

Help much appreciated.

It is cumbersom to read compose file declarations without indentions - I don’t read them because of that.
Please repost your docker-compose,yml, but this time as “Preformated text </>”. Leave on empty line before your preformated text, in order to get proper formating.

Meanwhile, wanted to add few points-

How are you running your compose?
Any error you get while running the compose?

I think I understand what’s going on but don’t quite have the solution.

I forgot that compose creates the network by prefixing it with the name of the directory to the compose file.

In my case it’s in a directory named “monica”, so the backend networks when I do docker-compose up becomes “monica_monica_backend” instead of “monica_backend”.

But if at the end of the file I define the network as “backend” and in the services leave it as “monica_backend” then at launch of course compose tells me undefined network “monica_backend”.

If on the other hand I define it as “monica_backend” at run time it creates “monica_monica_backend” and the services that were supposed to connect at “monica_backend” can’t find each others because they’re on the wrong network.

There must be something extremely obvious I’m missing here.

Ok problem solved but not understood.

From what I can see it doesn’t really matter in a compose file what network you tell it to connect to. Turns out I had another compose file with a completely different app but also running a mysql db called “db” so it seems that monica was trying to connect to that other one.

I renamed “db” in this file to “monica_db” and problem solved.

But as said still don’t understand how the networks are supposed to work if IN the compose file we cannot define them with the name they’ll have at runtime i.e. the defined name prefixed by the directory name. (“monica_backend” becomes “monica_monica_backend” at runtime).

Again must be missing something very obvious to everyone else.

docker-compose objects are named {project name}_{object name}. If you don’t provide the option --project {project name}, as a fallback the folder name will be used as {project name}

To address objects like networks, volumes, services inside the same docker-compose.yml, only the {object name} needs to be used. Actualy you could deploy the very same docker-compose.yml with different project names and end up with n distinct stacks without any hickup, except for services attached to an external network, which will be ambigous becaose the same service name will be registered multiple times. In order to bypass this limitation a service have one or more aliases per network.

A non external network will always be private to the project of a docker-compose.yml deployment and not mix and mingle with other project’s services.

@ meyay thank you for your answer.

So let me make sure I understand correctly. To rehash my specific case, what I understand from what you write is that I can address the network as “monica_backend” inside the compose file, although this same network is going to show up as “monica_monica_backend” if I do a docker network ls once I’ve done a docker-compose up -d.
And by way of consequence if I wanted to use that same network in another compose file I would have to declare it as “monica_monica_backend”. Is that correct?

Yep, the project prefix is only relevant to docker network, docker container and docker volume commands. It is completly irrelvant if you want to address other objects within the same docker-compose file, as they will implicitly belong to the same project.

Seems like you missed this detail:

If you want to share a custom network amongst docker-compose projects, you will need to create external networks, like you did with your proxy_proxy-tiernetwork.

Yes that’s what I understood just didn’t think it was necessary to mention again the “external: true” declaration.
So at least I understood correctly and am very thankful for your explanation and patience.

But, if I may abuse of your time some more, I still don’t understand why in this case monica couldn’t connect to mysql as they were both part of the same network (monica_backend) but could connect when I joined them with the external proxy network.
As already said I solved the problem in another way, by renaming the db service, but I still don’t understand why they couldn’t connect to start with.

The app service uses the env DB_HOST=db. The db service is called like this, so this should have worked if the DB_HOST variable is in fact used by the application in app service. Though the error message indicates something else: it indicates that instead of db:3306, mysql:3306 was used.

Since your app service seem not be an official image, it is completly unclear what the entrypoint script looks like and what application actualy is run.