1

I'm trying to connect my FASTAPI app container to a MySQL database container using the docker-compose file. In the Docker documentation it says that docker creates a default network for both containers. However, I would like to use a pre-existing network that I've created(app-net). This is my docker-compose file:

version: '3.4'
services:
  mysql:
    image: mysql:latest
    command: mysqld --default-authentication-plugin=mysql_native_password
    container_name: mysql
    restart: always
    ports:
      - 3307:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes: 
      - mysql-data:/var/lib/mysql
  app:
    build: .
    image: app:1.0
    container_name: app
    ports:
      - 8000:8000
    environment:
      PASSWORD: password
      USERNAME: root
networks:
  default:
    external: true
    name: app-net
volumes:
    mysql-data:
        driver: local

this is the output I get when i run docker inspect mysql -f "{{json .NetworkSettings.Networks }}":

{"app-net":{"IPAMConfig":null,"Links":null,"Aliases":["mysql","5e998f9fb646"],"NetworkID":"7f60c83e4c88d25e674461521446ec9fa98baca8639c782c79671c4fcb77ba88","EndpointID":"","Gateway":"","IPAddress":"","IPPrefixLen":0,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"","DriverOpts":null}}

However, when I run each container individually using CMD with the --network app-net the output is different:

{"app-net":{"IPAMConfig":null,"Links":null,"Aliases":["46157e588c87"],"NetworkID":"7f60c83e4c88d25e674461521446ec9fa98baca8639c782c79671c4fcb77ba88","EndpointID":"6a6922a9a6ea8f9d113447decbbb927cb93ddffd3b9563ee882fa2e44970cde5","Gateway":"172.20.0.1","IPAddress":"172.20.0.2","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:14:00:02","DriverOpts":null}}

In my app code in order to connect the mysql server, I specified the container name as the hostname since they are supposed to share the same network. But, as I mentioned it seems both containers can't talk to each other. I'm pretty sure that is the reason I can't connect the database through my app and get that error when I run:

docker-compose -f docker-compose.yml up

I get this error:

sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (2005, "Unknown MySQL server host 'mysql' (0)")

What am I missing?

Shay Barak
  • 61
  • 1
  • 4
  • What happen if you exclude the `network` block entirely? You should not need to create the `default` network (since it will already exist) and be used by default. – DazWilkin Jul 19 '21 at 22:57
  • In case it's unclear `ports: - 3307:3306` maps the container port (`3306`) to the host machine's port (`3307`). Conventionally, these are the same (i.e. `3306:3306`) and you should only need to use a different value if e.g. you have multiple SQL containers and need to expose more than one of them on the host. The host only has one `3306`, and so you may then map the next to e.g. `3307`, `3308` ... – DazWilkin Jul 19 '21 at 22:59
  • There's a very useful MySQL tool called Adminer (see: https://hub.docker.com/_/adminer) that has a container image can be included in Docker Compose scripts. I tend to always include it because it's easy to check database connections with it. – DazWilkin Jul 19 '21 at 23:01
  • In the `docker-compose` logs, is the database actually starting up, or does it exit? If you specify `depends_on: [mysql]` do you get a different error? – David Maze Jul 19 '21 at 23:05
  • @DazWilkin when I exclude the network block it does create a default network but still both containers can't talk to each other and I get the same error. – Shay Barak Jul 20 '21 at 15:28
  • @DazWilkin I did ` ports: - 3307:3306 ` since I already have a mysql server running on port 3306 on my host so when I tried to execute 3306:3306 I got an error that says port 3306 is not available. – Shay Barak Jul 20 '21 at 15:32
  • Yes, OK. That's another time when you'll want to ensure there's no collision ;-) But, back to your `docker-compose.yml`, if you drop the `networks` and stick to the default network, your app should be able to access the containerized (`mysql`) service on `mysql:3306`. – DazWilkin Jul 20 '21 at 15:41
  • @DavidMaze when I specified the "depends_on: [mysql]" there are no errors and it works properly. what does it mean acutely and how did it make the containers to run smoothly? – Shay Barak Jul 21 '21 at 17:35

2 Answers2

0

If the error you're getting is specifically "unknown host" or something similar, this can happen if your application container starts before the database container exists. You can work around this situation by telling Compose about the dependency:

version: '3.8'
services:
  mysql: { ... }
  app:
    depends_on:
      - mysql

This has two key effects. If you try to start only the application container docker-compose up app, it will also start the mysql container, following the depends_on: chain. When Compose does start containers, it at least creates the mysql container before creating the app container.

Note that this doesn't guarantee the database will actually be running by the time your application starts up. If you do encounter this, you will get a different error like "connection refused". You can work around this by embedding a script in your image that waits for the database to be available, or by using a version 2 Compose file with health-check support; see Docker Compose wait for container X before starting Y for more details on this specific problem.

David Maze
  • 130,717
  • 29
  • 175
  • 215
-1

You could add the key networks to both containers, this way:

version: '3.4'
services:
mysql:
 image: mysql:latest
 command: mysqld --default-authentication-plugin=mysql_native_password
 container_name: mysql
 restart: always
ports:
  - 3307:3306
environment:
  MYSQL_ROOT_PASSWORD: password
volumes: 
  - mysql-data:/var/lib/mysql
networks:
  - app-net
app:
 build: .
 image: app:1.0
 container_name: app
 ports:
  - 8000:8000
 environment:
  PASSWORD: password
  USERNAME: root
 networks:
  - app-net
networks:
 default:
  external: true
  name: app-net
volumes:
mysql-data:
    driver: local
HLX Studios
  • 213
  • 1
  • 3