skip to Main Content

I build a website using Strapi and Gatsby, everythings works well when I try to connect to a remote database, but I’m trying to create a db inside a container and so far no luck.
Essentially, what I did is create the following docker-compose:

version: '3'
services:
  backend:
    container_name: myapp_backend
    build: ./backend/
    ports:
      - '3002:3002'
    volumes:
      - ./backend:/usr/src/myapp/backend
      - /usr/src/myapp/backend/node_modules
    environment:
      - APP_NAME=myapp_backend
      - DATABASE_CLIENT=mysql
      - DATABASE_HOST=db
      - DATABASE_PORT=3307
      - DATABASE_NAME=myapp_db
      - DATABASE_USERNAME=johnny
      - DATABASE_PASSWORD=stecchino
      - DATABASE_SSL=false
      - DATABASE_AUTHENTICATION_DATABASE=myapp_db
      - HOST=localhost
    depends_on:
      - db
    restart: always

  db:
    container_name: myapp_mysql
    image: mysql:5.7
    volumes:
      - ./db.sql:/docker-entrypoint-initdb.d/db.sql
    restart: always
    ports:
      - 3307:3307
    environment:
      MYSQL_ROOT_PASSWORD: 5!JF6!FgAkvt
      MYSQL_DATABASE: myapp_db
      MYSQL_USER: johnny
      MYSQL_PASSWORD: stecchino
    command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --init-connect='SET NAMES UTF8;' --innodb-flush-log-at-trx-commit=0

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: 'myapp_phpmyadmin'
    links:
      - db
    environment:
      PMA_HOST: db
      PMA_PORT: 3307
    ports:
      - '8081:80'
    volumes:
      - /sessions
    depends_on:
      - db

  frontend:
    container_name: myapp_frontend
    build: ./frontend/
    ports:
      - '3001:3001'
    depends_on:
      - backend
    volumes:


      - ./frontend:/usr/src/myapp/frontend

the backend service contains the Strapi application, the db service contains the mysql instance which runs on the port 3307 ’cause 3306 is already in use.

Then I have also installed phpmyadmin, and last but not least the Gastby site. When I run using docker-compose up --build, and try to access to phpmyadmin using:

http://localhost:8081/index.php

with the following credentials:

user: johnny
pwd: stecchino

I get:

MySQL mysqli::real_connect():(HY000/2002): Connection refused

now, what I did for fix that situation is pass the port 3306 instead of 3307 to backend and phpmyadmin service. And magically, everything works. But why? I have mapped container and host to 3307…

3

Answers


  1. Because 3306 is the exposed port by the official Dockerfile.

    What you can do is to map the port that is running MySQL to another port on your host: 3307:3306 for instance (always host:container)

    Login or Signup to reply.
  2. There are 2 things happening here.

    1. Mysql is running on port 3306.

    This is because you never told the mysql container to run on port 3307. The default configuration is running on 3306.

    1. phpadmin can connect to mysql at port 3306.

    Of course it can. This is because when you define multiple services within the same docker-compose file, they start on the same network. This means that they can see and connect to each other’s internal ports without the need for external port binding like 3306:3306

    I would suggest to keep port bindings only for services that you want access outside the docker environment (like the UI), and for internal components just expose the port like this

    expose:
           - 3306
    
    Login or Signup to reply.
  3. Both answers are useful, I am particularly fond of Manish’s answer

    I wanted to add some additional wording:

    There are the internal docker networks which nothing from the outside can gain access to. From inside any given service (or container), you can reach every other service (or container) via:

    <service-name>:<port>/path/of/resources
    <container-name>:<port>/path/of/resources
    

    In order to access resources inside the docker network from outside of docker, whether that is from your host environment, or farther upstream on the internet, the docker daemon needs to bind to host ports, and then forward information received on those ports to a docker service (and ultimately a docker container).

    In your docker-compose.yml when you do the 3307:3307 you are telling the docker daemon to listen on port 3307, and forward to your db service internally on it’s port 3307.

    However, from what we can all see, mysql is still internally (that is, inside the container) listening for traffic on port 3306. Any containers or services on the same docker networks as your db service (mysql running container(s)) would be able to access mysql via something like:

    <driver>:mysql://db:3306/<dbname>
    

    If you wanted all host traffic and docker network traffic to access mysql on port 3307, you would also need to configure mysql to listen on port 3307 instead of 3306. That tidbit of information does not appear to be in your question at the time of writing.

    I hope the additional information helps! It’s a topic I chat often about when talking docker with folks.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search