Docker: Problem using container IP

Asked

Viewed 142 times

2

Hello, All right?

Before long I learned to use Docker and decided to practice the use of mysql and adminer, with the following Docker-Compose I already had the containers standing.

version: '3.5'

services:

  database:
    image: mysql
    ports:
      - '3306:3036'

    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: smartMoft
      MYSQL_USER: root
      MYSQL_PASSWORD: root

    volumes:
      - './data:/var/lib/mysql'

  adminer:
    image: adminer
    ports: 
      - '8080:8080'

When accessing the adminer url I had access to its beautiful interface and mysql databases, and using the docker exec -it ... I could access the mysql

However, when trying to make the connection in the nodejs it only returned an error: timeout.

const connection = mysql.createConnection({
    host: '172.18.0.2',
    port: 3306,
    user: 'root',
    password: 'root',
    database: 'smartMoft',
})

Return:

Error: connect ETIMEDOUT
    at Connection._handleConnectTimeout (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\Connection.js:409:13)
    at Object.onceWrapper (node:events:435:28)
    at Socket.emit (node:events:329:20)
    at Socket._onTimeout (node:net:470:8)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7)
    --------------------
    at Protocol._enqueue (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\protocol\Protocol.js:144:48)
    at Protocol.handshake (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\protocol\Protocol.js:51:23)
    at Connection.connect (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\Connection.js:116:18)
    at execQuery (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\db\configDB.js:12:16) 
    at C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\src\routes.js:10:24
    at Layer.handle [as handle_request] (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\layer.js:95:5)
    at C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\index.js:281:22 {
  errorno: 'ETIMEDOUT',
  code: 'ETIMEDOUT',
  syscall: 'connect',
  fatal: true
}

It is worth mentioning that in the host field the address was taken from a docker inspect ... and which has tested both mysql ips, adminer and "localhost", all unsuccessfully

It is also noteworthy that when using localhost as host, it does not even give timeout, but rather an error

Error: Connection lost: The server closed the connection.
    at Protocol.end (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\protocol\Protocol.js:112:13)
    at Socket.<anonymous> (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\Connection.js:94:28)
    at Socket.<anonymous> (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\Connection.js:526:10)
    at Socket.emit (node:events:341:22)
    at endReadableNT (node:internal/streams/readable:1294:12)
    at processTicksAndRejections (node:internal/process/task_queues:80:21)
    --------------------
    at Protocol._enqueue (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\protocol\Protocol.js:144:48)
    at Protocol.handshake (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\protocol\Protocol.js:51:23)
    at Connection.connect (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\mysql\lib\Connection.js:116:18)
    at execQuery (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\db\configDB.js:12:16) 
    at C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\src\routes.js:10:24
    at Layer.handle [as handle_request] (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\layer.js:95:5)
    at C:\Users\sffmo\Desktop\www\Treinos\estudandoDocker\backend\node_modules\express\lib\router\index.js:281:22 {
  fatal: true,
  code: 'PROTOCOL_CONNECTION_LOST'
}

I still had the idea to use the Beekeeper (Database Manager), only by doubt, and the same error was presented.

What most intrigues me, is the fact that the credentials that work in the adminer, do not work in the Beekeeper or Node.

The same thing happened when I migrated from mysql to mongoDB to test if there was a problem in mysql, I used the following code to make the connection:

mongoose.connect('mongodb://root:[email protected]:27017/smartMoft?authSource=admin', {useNewUrlParser: true}, (err, client) =>{
    if(err) throw err

    console.log(client)
})

And the same returned this error after a few seconds of waiting.

aprendendoRedux\api\node_modules\mongoose\lib\helpers\promiseOrCallback.js:19
            throw error;
            ^

MongoNetworkError: failed to connect to server [172.19.0.2:27017] 
on first connect [MongoNetworkTimeoutError: connection timed out  
    at connectionFailureError (C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\connect.js:342:14)
    at Socket.<anonymous> (C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\connect.js:310:16)
    at Object.onceWrapper (node:events:435:28)
    at Socket.emit (node:events:329:20)
    at Socket._onTimeout (node:net:470:8)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7)]
    at Pool.<anonymous> (C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\topologies\server.js:438:11)
    at Pool.emit (node:events:329:20)
    at C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\pool.js:562:14
    at C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\pool.js:995:11
    at C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\connect.js:32:7
    at callback (C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\connect.js:280:5)  
    at Socket.<anonymous> (C:\Users\sffmo\Desktop\www\Treinos\aprendendoRedux\api\node_modules\mongodb\lib\core\connection\connect.js:310:7)
    at Object.onceWrapper (node:events:435:28)
    at Socket.emit (node:events:329:20)
    at Socket._onTimeout (node:net:470:8)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7)

However, it worked to access Mongo-express and use its credentials to access the database.

Follow Docker-Compose.yml, the same is on the mongodb page on dockerHub.

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: root

Without a doubt it is one of the most "problematic" problems I have ever had in the area, and I’ve even tried to google, but very few results matched my situation and the rest did not solve the problem.

Comments: I am using root in user and password in both mysql and mongodb. I’m using Windows 10. Initially I used dockerfile to create the image and commands like docker run to create the container, but the same error was shown. I’m using the Docker desktop

I ask for your help to solve this boring mistake that does not abandon me

  • "when trying to make the connection in the nodejs it just returned an error: timeout" where is the application in Node, in the same container, other container, or localhost?

2 answers

0

Come on, I don’t think I’m gonna get the right answer... but I do have some suggestions.

Before long I learned to use the Docker and I decided to practice the mysql and adminer usage, with the following Docker-Compose I already had the standing containers.

When you say you already had the containers standing, you’re saying you already had both running, but you wanted to have them running using the Docker-Compose ?.

So let’s say that’s actually the case. What may have happened is door-to-door conflict because you already had a Ngo container running at door 8081 when instantiating another one by Docker-Compose, The use of the 8081 port came into conflict, thus the door remains occupied.

Discarding this first case, because in the notes you say you were already creating the containers with the Dockerfile and using the Docker run to execute them.

Come on, first check if the container remains running after the Docker run, using the command:

docker ps

Sometimes depending on the arguments passed in the command run, the container ends up dying/finishing, I believe it continues running because you can access them using the command exec, but in the case of Docker-Compose you can access them by following the previous steps, let’s check if the right services are running, if yes you can access using the exec command, see below:

docker-compose ps
docker-compose exec nome_do_servico bash

Following for suggestions:

In case you are not specifying a network_mode for both services (Mongo and mongo_express), so the container will have ip proper to the Docker subnet.

Try to climb the containers using the computer’s own network, add the following snippet below each service, for example:

mongo:
    image: mongo
    network_mode: host

remember that setting the containers to use the network "localhost" is not necessary to do port forwarding, because as already said it will not be using the subnet Docker and yes the local network of the computer itself.

What leads to another suggestion, will be that for some reason windows is blocking the container ports, in this sense it would be nice to check the firewall.

0

Docker was not designed for you to handle his IP’s (although it has this feature for very peculiar cases, this is not your scenario).

The IP addresses of the containers were designed to be dynamic, and worse, to be multiple. That is, 2 instances of an application, means 2 ip’s, if it is 100 instances, 100 ip’s...

Thus, the right way to do this, from Ocker’s point of view, is to use the internal name resolution of Ocker. The Docker networks have internal NAME RESOLUTION (DNS). Just 2 containers on the same network for this magic to work. But it does not serve to use the default networks, you have to create a new network (do not ask me the reason, it was never clear), but is in doc.

Then you WILL HAVE to create a network (bridge or overlay), then use this network in the 2 containers. Ready, now they speak by the container name. In Docker Compose the name to be used is the service name.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.