Error database connect is not a function Nodejs with Mysql in docker - mysql

I have deployed my docker application (to DigitalOcean). Everything work's, but I can't connect mysql with nodejs.
When I run docker-compose up I get error database.connect is not a function.
My server.js file is look like this
const mysql = require("mysql");
const database = mysql.createPool({
host: process.env.MYSQL_HOST_IP,
user: "db_user",
password: "db_user_pass",
database: "guess-game",
port: 3306,
});
database.connect((err) => {
if (err) {
console.error("error connecting: " + err.stack);
return;
}
console.log("connected as id " + db.threadId);
});
module.exports = db;
I don't know what I need to write this line to make it work.
host: process.env.MYSQL_HOST_IP,
I tried to add droplet IP as host, but this is also don't work.
host: "http://46.101.162.111/",
Also, I try this.
host: "46.101.162.111",
My docker-compose.yml file
version: "3"
networks:
dbnet:
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin1
environment:
- PMA_ARBITRARY=1
- PMA_HOST=db
restart: always
links:
- db
ports:
- 8899:80
depends_on:
- db
networks:
- dbnet
api:
build: ./api
container_name: api1
command: npm run start
restart: unless-stopped
ports:
- "3005:3005"
environment:
- PORT=3005
- MYSQL_HOST_IP=172.18.0.2
depends_on:
- phpmyadmin
networks:
- dbnet
db:
image: mysql:latest
container_name: db
command: --default-authentication-plugin=mysql_native_password
environment:
- MYSQL_ROOT_PASSWORD=my_secret_password
- MYSQL_DATABASE=guess-game
- MYSQL_USER=db_user
- MYSQL_PASSWORD=db_user_pass
restart: always
ports:
- 6033:3306
networks:
- dbnet
Struggling almost 3 days. 😣

You just need to indicate a DB container name instead of IP like this:
MYSQL_HOST_IP=db

Related

trying to connect typeorm to mysql container in docker-compose but got this error Error: Access denied for user ''#'172.29.0.3' (using password: YES)

I am running node and mysql containers with docker compose and try to connect typeorm with mysql container but I got the same error over and over
this my docker-compose file
version: '3.8'
services:
db:
image: mysql
restart: always
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: password
app:
build: .
command: npm start
volumes:
- .:/usr/app/
ports:
- '8000:8000'
depends_on:
- db
environment:
MYSQL_HOST: db
MYSQL_NAME: test
MYSQL_PASSWORD: password
this is my typeorm config file
import {DataSource} from 'typeorm';
import * as dotenv from 'dotenv';
dotenv.config();
export const appDataSource = new DataSource({
type: 'mysql',
host: process.env.MYSQL_HOST,
port: 3306,
password: process.env.MYSQL_PASSWORD,
entities:[
'src/entities/*.js'
],
synchronize: true,
logging: true
});
and this is my .env file
MYSQL_USER = root
MYSQL_PASSWORD = password
MYSQL_NAME = test
MYSQL_HOST = db
MYSQL_PASSWORD = password
Your MySQL and application container seems to be in two different networks.
Try with following docker-compose :
version: '3.8'
services:
db:
image: mysql
restart: always
network_mode: "host"
ports:
- '3306:3306'
environment:
MYSQL_ROOT_PASSWORD: password
app:
build: .
command: npm start
network_mode: "host"
volumes:
- .:/usr/app/
ports:
- '8000:8000'
depends_on:
- db
environment:
MYSQL_HOST: db
MYSQL_NAME: test
MYSQL_PASSWORD: password
here both containers will run on host.
For fixing : > Error: getaddrinfo EAI_AGAIN
Try adding following to /etc/hosts file. (If you are on Linux destro)
0.0.0.0 db
0.0.0.0 app

Node.js able to connect to MySQL container when app is ran locally but unable to connect when app is ran in a container

Docker-Compose file:
version: '3.8'
networks:
app-tier:
driver: bridge
services:
mysql_node:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'sample_db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- mysql_db:/var/lib/mysql
app:
depends_on:
- mysql_node
build: .
ports:
- 3000:3000
environment:
- MYSQL_HOST=mysql_node
- MYSQL_USER=root
- MYSQL_PASSWORD=password
- MYSQL_NAME=sample_db
- MYSQL_PORT=3306
- MYSQL_HOST_IP=mysql_node
networks:
- app-tier
volumes:
- .:/app
volumes:
mysql_db:
docker file:
FROM node:latest
RUN mkdir app
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "app.js"]
Sourcecode:
const http = require('http')
var mysql = require('mysql');
const hostname = '0.0.0.0'
const port = 3000
console.log(process.env.MYSQL_HOST_IP)
console.log(process.env.MYSQL_PORT)
var con = mysql.createConnection({
host: "process.env.MYSQL_HOST_IP",
user: "user",
password: "password",
port: 3306
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
When I run docker-compose up the MySQL container successfully launches. But the app exits, with error code Error: connect ETIMEDOUT.
When I run the app locally via node app.js I end up getting a successful "Connected!" message output to my console.
I'm able to connect to the database via MySQLWorkbench as well. It's just the app is unable to connect to the db when the app is ran as a container.
You've specified that the app should be on a named network and the database shouldn't. Then the database service goes on the default network and the two containers can't talk to each other.
I'd remove the named network from the app, since it's probably not needed.
app:
depends_on:
- mysql_node
build: .
ports:
- 3000:3000
environment:
- MYSQL_HOST=mysql_node
- MYSQL_USER=root
- MYSQL_PASSWORD=password
- MYSQL_NAME=sample_db
- MYSQL_PORT=3306
- MYSQL_HOST_IP=mysql_node
volumes:
- .:/app

Mysql connection refused in docker-compose

I have a problem connecting to MySQL from my golang app in docker-compose. I can connect to db from console: mysql -u user -D data -h 0.0.0.0 -P3306 -p
But, I can't connect when using docker-compose.
My docker-compose.yml
version: '3'
services:
app:
build: ./
volumes:
- ./internal/app:/app
- ./logs:/var/log/parser
links:
- db
db:
image: mysql:8
container_name: mysqldb
ports:
- "3306:3306"
volumes:
- ./docker/mysql/conf:/etc/mysql/conf/conf.d
- ./docker/mysql/logs/:/var/log/mysql
- ./docker/mysql/init:/docker-entrypoint-initdb.d
- ./docker/mysql/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: data
MYSQL_USER: user
MYSQL_PASSWORD: pass
In my app main.go
dbConfig := mysql.NewConfig()
dbConfig.User = "user"
dbConfig.Passwd = "pass"
dbConfig.Addr = "mysqldb"
dbConfig.DBName = "data"
dbConfig.Net = "tcp"
db, err := sql.Open("mysql", dbConfig.FormatDSN())
if err != nil {
panic(err.Error())
}
defer db.Close()
But I get this error:
panic: dial tcp 172.20.0.2:3306: connect: connection refused
I think your golang service starts before the MySQL service. so you have to start MySQL service first then golang service so, use depends_on to achieve that.
new docker-compose.yml with depends_on
version: '3'
services:
app:
build: ./
volumes:
- ./internal/app:/app
- ./logs:/var/log/parser
depends_on:
- mysqldb
links:
- db
db:
image: mysql:8
container_name: mysqldb
ports:
- "3306:3306"
volumes:
- ./docker/mysql/conf:/etc/mysql/conf/conf.d
- ./docker/mysql/logs/:/var/log/mysql
- ./docker/mysql/init:/docker-entrypoint-initdb.d
- ./docker/mysql/data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: data
MYSQL_USER: user
MYSQL_PASSWORD: pass

Connect JavaScript running in docker container to MySQL database running on another docker container

I'm currently running a local instance of RocketChat and the RocketBot using docker-compose and a corresponding docker-compose.yaml file:
I use the standard mysql module like this:
var con = mysql.createConnection({
host: '<placeholder>',
user: 'root',
port: '3306',
password: '<placeholder>',
});
The host, user, port and password are gathered from running the inspect command on the container containing the MySQL server. The MySQL does work as I can run it and make changes to it and even connect to it using MySQL workbench. I get this error:
rosbot_1 | [Tue Jun 18 2019 18:42:06 GMT+0000 (UTC)] ERROR Error: connect ETIMEDOUT
rosbot_1 | at Connection._handleConnectTimeout (/home/hubot/node_modules/mysql/lib/Connection.js:412:13)
I have no idea how to proceed now, how can I connect from the bot served by docker-compose to the MySQL container using JavaScript?
EDIT:
docker-compose.yaml:
version: '2.1'
services:
mongo:
image: mongo:3.2
hostname: 'mongo'
volumes:
- ./db/data:/data/db
- ./db/dump:/dump
command: mongod --smallfiles --oplogSize 128 --replSet rs0
mongo-init-replica:
image: mongo:3.2
command: 'mongo mongo/rocketchat --eval "rs.initiate({ _id: ''rs0'', members: [ { _id: 0, host: ''localhost:27017'' } ]})"'
links:
- mongo:mongo
rocketchat:
image: rocketchat/rocket.chat:latest
hostname: 'rocketchat'
volumes:
- ./rocketchat/uploads:/app/uploads
environment:
- PORT=3000
- ROOT_URL=http://localhost:3000
- MONGO_URL=<placeholder>
- MONGO_OPLOG_URL=<placeholder>
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 30s
timeout: 10s
retries: 5
links:
- mongo:mongo
ports:
- 3000:3000
<placeholder>:
image: <placeholder>
hostname: "<placeholder>"
environment:
- ROCKETCHAT_URL=<placeholder>
- ROCKETCHAT_ROOM=""
- ROCKETCHAT_USER=<placeholder>
- ROCKETCHAT_PASSWORD=<placeholder>
- ROCKETCHAT_AUTH=<placeholder>
- BOT_NAME=<placeholder>
- LISTEN_ON_ALL_PUBLIC=true
- EXTERNAL_SCRIPTS=hubot-help,hubot-seen,hubot-links,hubot-diagnostics,hubot-pugme,hubot-reload
- PENTEXT_PATH=/home/hubot/pentext
- ADDITIONAL_PACKAGES=mysql,lodash
- RESPOND_TO_LIVECHAT=true
- RESPOND_TO_DM=true
depends_on:
rocketchat:
condition: service_healthy
links:
- rocketchat:rocketchat
volumes:
- <placeholder>
ports:
- 3001:3001
Normally, you can connect to another container using the container name as hostname:
If you have a container with mysql, the container name (in this example 'db') is the host name to access the mysql container (also, you can use a hostname: 'mysqlhostname' to specify a different name):
db:
image: mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: mypass
MYSQL_DATABASE: mydb
In your rocketchat container you should add some environment variables for mysq root password and database to make it available to your container
rocketchat:
image: rocketchat/rocket.chat:latest
hostname: 'rocketchat'
volumes:
- ./rocketchat/uploads:/app/uploads
environment:
- PORT=3000
- ROOT_URL=http://localhost:3000
- MONGO_URL=<placeholder>
- MONGO_OPLOG_URL=<placeholder>
- MYSQL_ROOT_PASSWORD: mypass
- MYSQL_DATABASE: mydb
- MYSQL_HOSTNAME: db
...
links:
- rocketchat:rocketchat
- db : db
And then, use the host name and the environment variables to create your connection:
var con = mysql.createConnection({
host: 'db', // or process.env.MYSQL_HOSTNAME
user: 'root',
port: '3306',
password: 'mypass', // or process.env.MYSQL_ROOT_PASSWORD
});

TCPConnectWrap.afterConnect - node can't get data from mysql when are in docker compose

I'm trying to connect node with mysql through dokcer-compose. I can access mysql with workbench but when I try to connect with node I get the error:
Error: connect ECONNREFUSED 127.0.0.1:3306
     at TCPConnectWrap.afterConnect [as oncomplete] (net.js: 1054: 14))
Does anyone know what is going on?
docker-compose.yml
version: '3'
services:
#App Service
app:
image: "node:alpine"
container_name: cms-node
restart: unless-stopped
tty: true
working_dir: /app
environment:
- NODE_ENV=production
ports:
- 1234:1234
volumes:
- ./:/app
links:
- db
depends_on:
- db
#Mysql Service
db:
image: mysql:latest
container_name: cms-mysql
restart: unless-stopped
# command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_DATABASE: CMS
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
ports:
- 3306:3306
node create connection
const db: Connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'CMS',
});
export default db;
node try to connect
db.connect((err) => {
if (err) {
throw err;
}
console.log('Connected!');
});
You should use the link name (by default, the name of the linked service) as the hostname to connect to. See the docker-compose.yml documentation for details.
So just use host: 'db' instead of host: 'localhost'
Yes, we have to use service name from docker-compose.yml. I faced a similar issue when there was a custom front end API Gateway server (working as proxy) written in node.js connecting to other two services. So replacing localhost:3001 with serviceName:30001 fixed the issue.
Example code:
...
const proxy = require('express-http-proxy');
...
app.use('/json-parser', proxy('json_parsing_api:3001'));
app.get('/json-parser/json-to-person', proxy('json-to-person'));