0

I'm trying to dockerize an app written in vuejs, nodejs, express and mysql from the tutorial https://github.com/bezkoder/vue-js-node-js-express-mysql. But my node app container encounter db connection issue as below:

Server is running on port 8080. Unhandled rejection SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:3306 at /app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:123:19 at tryCatcher (/app/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/app/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/app/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromise0 (/app/node_modules/bluebird/js/release/promise.js:649:10) at Promise._settlePromises (/app/node_modules/bluebird/js/release/promise.js:725:18) at _drainQueueStep (/app/node_modules/bluebird/js/release/async.js:93:12) at _drainQueue (/app/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/app/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/app/node_modules/bluebird/js/release/async.js:15:14) at processImmediate (node:internal/timers:466:21)

My Dockerfile

FROM node
WORKDIR /app
COPY package.json .
RUN npm install
COPY . ./
ENV PORT 8080
EXPOSE $PORT
CMD ["node", "server.js"]

My docker-compose.yml

version: "3"

services:

  vue-app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - PORT=8080

    volumes:
      - ./:/app
      - /app/node_modules

  mysql:
    platform: linux/x86_64
    image: mysql
    # volumes:
    #   - /db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: testdb
      MYSQL_USER: user
      MYSQL_PASSWORD: 12345678
    ports:
      - "3306:3306"

    

db.config.js

module.exports = {
  HOST: "localhost",
  USER: "user",
  PASSWORD: "12345678",
  DB: "testdb",
  dialect: "mysql",
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};

I did tried changing the HOST from "localhost" to "mysql" - same as the service name in the docker-compose.yml hoping both containers could connect each other turns out getting the same error but with different ip instead.

Server is running on port 8080. Unhandled rejection SequelizeConnectionRefusedError: connect ECONNREFUSED 172.27.0.2:3306 at /app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:123:19 at tryCatcher (/app/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/app/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/app/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromise0 (/app/node_modules/bluebird/js/release/promise.js:649:10) at Promise._settlePromises (/app/node_modules/bluebird/js/release/promise.js:725:18) at _drainQueueStep (/app/node_modules/bluebird/js/release/async.js:93:12) at _drainQueue (/app/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/app/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/app/node_modules/bluebird/js/release/async.js:15:14) at processImmediate (node:internal/timers:466:21)

Here is my repo with dockerfile and docker-compose.yml added to the main project. https://github.com/Alex2Tacy/docker-nodeapp

Docker network inspect result:

[
    {
        "Name": "vuejs_default",
        "Id": "546474b67f9a27cf6a944b7f95d1d2e7617e925a1f6b3b5a6d2ffb2f937039e9",
        "Created": "2022-03-10T12:16:20.641870542Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.27.0.0/16",
                    "Gateway": "172.27.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "a77b8de2e7f0637c9b8c05af97f279e65600aed50321953a0b372ba0c7e591fc": {
                "Name": "vuejs-mysql-1",
                "EndpointID": "d6bb0b17688a784eb10e0cb292a78957071d5bfcb7ef93fb0dda899549825bd8",
                "MacAddress": "02:42:ac:1b:00:02",
                "IPv4Address": "172.27.0.2/16",
                "IPv6Address": ""
            },
            "f57cd86543bfd2da9aaa47c687a8bc79c69d3f5cc6d31b1bc8ccbf975a47212a": {
                "Name": "vuejs-vue-app-1",
                "EndpointID": "8fb044889b1feb5deb9566a5cab7f94896ba0595bae1259fdf8fff1eb3d27f66",
                "MacAddress": "02:42:ac:1b:00:03",
                "IPv4Address": "172.27.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "vuejs",
            "com.docker.compose.version": "2.2.3"
        }
    }
]
A_T
  • 21
  • 1
  • 4
  • You need to put them in the same docker network. Also take a look at `depends_on` – Tvde1 Mar 10 '22 at 12:35
  • Hi @Tvde1, I thought when both the service name "vue-app" and "mysql" within the docker-compose.yml should be considered as same network ? – A_T Mar 10 '22 at 12:38
  • Nope, you have to specify that yourself – Tvde1 Mar 10 '22 at 12:40
  • I see, I did a docker network inspect to it , I have included the result to the last part of the question – A_T Mar 10 '22 at 12:41
  • @Tvde1 Compose creates a `default` network for you and attaches containers to it; see [Networking in Compose](https://docs.docker.com/compose/networking/) in the Docker documentation. Most practical uses should not need to manually specify `networks:` at all. – David Maze Mar 10 '22 at 14:26
  • @A_T In addition to needing to use the Compose service name `mysql` as a host name, you also may need to wait for the database to be ready. It can take 30-60 seconds for a database to start up and `depends_on:` doesn't guarantee the container is functional, only that it exists. See the two questions linked above. – David Maze Mar 10 '22 at 14:27

1 Answers1

0

The database hostname needs to be the service name rather than localhost. In a Docker context, localhost means the container itself, so your Vue app is trying to connect to itself.

Use this instead

module.exports = {
  HOST: "mysql",
  USER: "user",
  PASSWORD: "12345678",
  DB: "testdb",
  dialect: "mysql",
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};
Hans Kilian
  • 18,948
  • 1
  • 26
  • 35
  • 1
    Hi @Hans Kilian, I did tried to change exactly with your suggestion as I've included in my second part of question too. But I'm getting the same result but with different ip stated in the error message – A_T Mar 10 '22 at 13:05