1

I am trying to set up a multi-container application using the docker-compose concept.

The containers are creating and running successfully using docker compose up -d command

enter image description here

I can log in to MySQL Shell and it is displaying the database (named todos)-

enter image description here

But the node app's logs are showing the connection error with MySQL

enter image description here

Here's my docker-compose.yml file-

services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos
    depends_on:
      - mysql

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:


Nodejs application is using this code to connect with MySQL-

const waitPort = require('wait-port');
const fs = require('fs');
const mysql = require('mysql2');

const {
    MYSQL_HOST: HOST,
    MYSQL_HOST_FILE: HOST_FILE,
    MYSQL_USER: USER,
    MYSQL_USER_FILE: USER_FILE,
    MYSQL_PASSWORD: PASSWORD,
    MYSQL_PASSWORD_FILE: PASSWORD_FILE,
    MYSQL_DB: DB,
    MYSQL_DB_FILE: DB_FILE,
} = process.env;

let pool;
async function init() {
    const host = HOST_FILE ? fs.readFileSync(HOST_FILE) : HOST;
    const user = USER_FILE ? fs.readFileSync(USER_FILE) : USER;
    const password = PASSWORD_FILE ? fs.readFileSync(PASSWORD_FILE) : PASSWORD;
    const database = DB_FILE ? fs.readFileSync(DB_FILE) : DB;

    await waitPort({ 
        host, 
        port: 3306,
        timeout: 10000,
        waitForDns: true,
    });

    pool = mysql.createPool({
        connectionLimit: 5,
        host,
        user,
        password,
        database,
        charset: 'utf8mb4',
    });

    return new Promise((acc, rej) => {
        pool.query(
            'CREATE TABLE IF NOT EXISTS todo_items (id varchar(36), name varchar(255), completed boolean) DEFAULT CHARSET utf8mb4',
            err => {
                if (err) return rej(err);

                console.log(`Connected to mysql db at host ${HOST}`);
                acc();
            },
        );
    });
}

What am I doing wrong? Can someone please help debug that?

NOTE-

If anyone wants to set up this demo, I am following the docker documentation example.

Neha Soni
  • 3,935
  • 2
  • 10
  • 32
  • Looks like you simply need `depends_on: [mysql]`. See https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on – Phil May 31 '23 at 08:00
  • Does this answer your question? [Docker Compose wait for container X before starting Y](https://stackoverflow.com/questions/31746182/docker-compose-wait-for-container-x-before-starting-y) – Phil May 31 '23 at 08:01
  • Hey, Thanks for the response. I added the depends_on: - mysql but it is still not working. – Neha Soni May 31 '23 at 08:09
  • It's done, edited. – Neha Soni May 31 '23 at 08:12
  • Are you sure it's all there this time? I noticed you added in the `command` just now. Have you specified any `networks` by any chance? – Phil May 31 '23 at 08:15
  • What MySQL Node.js library are you using (name and version)? – Phil May 31 '23 at 08:16
  • I didn't add the network in the docker file. Docker is using the default network, "app_default" while creating the container. I inspect using docker commands and both containers are using the same network. I am adding the screenshots for more information. – Neha Soni May 31 '23 at 08:17
  • Please [edit] your question to also show the connection code. – Phil May 31 '23 at 08:26
  • _"I am using mysql2"_... and the **version** is? – Phil May 31 '23 at 08:28
  • It's "mysql2": "^2.3.3", – Neha Soni May 31 '23 at 08:29
  • I added the connection code as well. – Neha Soni May 31 '23 at 08:31
  • That's an entire major version behind. I suggest you bump that up to 3.3.3 – Phil May 31 '23 at 08:32
  • Try it without `waitPort` since that seems to be the cause of the issue – Phil May 31 '23 at 08:34
  • I tried running this application using proper docker commands (without docker-compose) and that worked well. (https://docs.docker.com/get-started/07_multi_container/) If version is an issue then it should happen with that case also. Please let me know if I am not correct. – Neha Soni May 31 '23 at 08:34
  • "Try it without waitPort since that seems to be the cause of the issue" - It's still not working. If you can please setup this demo repository mentioned in the doc, (would hardly take less time if docker is installed). It would be great in debugging. – Neha Soni May 31 '23 at 08:38
  • I have no problem. It says _"Waiting for mysql:3306..."_ then _"Connected!"_. Docker Compose version v2.17.2, Docker version 20.10.24, build 297e128 on MacOS 13.4 – Phil May 31 '23 at 08:51
  • Oops!! Mines are- Docker version 23.0.5, build bc4487a, and Docker Compose version v2.17.3 on macOS Monetrey version 12.6.5. – Neha Soni May 31 '23 at 08:57
  • I noticed a very strange thing. I made some changes in the connection code (just log the host and port), the server restarted and it got connected. It means the error was because of a timeout. What could be the fix to this problem? – Neha Soni May 31 '23 at 09:17
  • 1
    Nothing. You already have redundancies to wait for the MySQL service to become available, `depends_on` and `waitFor` – Phil May 31 '23 at 09:21

0 Answers0