I have to connect to both localhost as well as docker.
const db = new Sequelize({
host : 'host.docker.internal'| process.env.DB_HOST,
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASS,
dialect: 'mysql'
})
In the following code , when I run
node app.js it runs on the machine. But when I run docker run -p 3000:3000 [imagehash] it throws the following error
ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
and when I run
const db = new Sequelize({
host : 'host.docker.internal',
database: process.env.DB_NAME,
username: process.env.DB_USER,
password: process.env.DB_PASS,
dialect: 'mysql'
})
it runs perfectly on docker run -p 3000:3000 [imagehash]
How to run on both perfectly
NOTE : process.env.DB_HOST = localhost
When you construct the database connection information, check the environment variable first. It's often useful to set the fallback value to what you'd want this to be in your everyday development environment.
const db = new Sequelize({
host: process.env.DB_HOST || 'localhost',
...
});
Then when you do run it in Docker, you need to provide the value of that environment variable.
# If the database isn't in a container
docker run -e DB_HOST=host.docker.internal -p 3000:3000 myapp
# If the database is in a container; typical Compose setup
version: '3.8'
services:
app:
build: .
environment:
- DB_HOST=db # matching the name of the service below
ports:
- 3000:3000
db:
image: mysql
volumes:
mysql_data: /var/lib/mysql/data
volumes:
mysql_data:
I think you try to connect to a mysql db who run on the host,
To make it work just add --network host argument to your run command.
related documentation
After that, the best pratice is to create a mysql db inside container and link it with your application
Related
Well, I am making a discord bot and I want to implement a mysql database on it.
I've researched how to connect an online database on my bot that use Node.js, but I've failed.
I want to know whether I have to install MySQL on my computer or there is a way to connect it online. I'm very confuse.
One more thing: If I have to install it on my PC, is there a way to upload the bot and the database together?
Help me, please.
(I'm Brazilian, so some words or sentences may be wrong)
You can use the NodeJS MySQL client for connecting to your database:
const { createConnection } = require('mysql');
const database = createConnection({
host: 'localhost',
user: 'user',
password: 'password',
database: 'db',
});
database.connect();
As for installing and setting up MySQL, between a local install and a containerized install, I'd recommend containerizing it with Docker.
This can get you started via docker-compose: docker-compose up.
# docker-compose.yml
version: '3'
services:
db:
image: mysql:8.0
restart: always
environment:
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- '3306:3306'
expose:
- '3306'
volumes:
- database:/var/lib/mysql
volumes:
database:
I'm trying to use NodeJS+Express, MySQL, phpmyadmin altogether. phpmyadmin itself resolving the address by port 8183 in my situation. But whenever I'm going to connect it through with mysql js package of NodeJS. it is not working and throwing error
Error: connect ECONNREFUSED 127.0.0.1:3306
Note: I tried with few variations as host anyone didn't work for me!
example: mysql, my_machine_ip, localhost, 0.0.0.0
nothing worked for me.
Here's my yml file.
version : '3'
services:
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: node_pa
links:
- mysql
depends_on:
- mysql
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_ARBITRARY: 1
restart: always
ports:
- 8183:80
node_backend:
container_name: node_with_pa_msql
build: ./backend_app
# volumes:
# - ./backend_app:/usr/src/app
links:
- mysql
depends_on:
- mysql
restart: on-failure
ports:
- 3004:4006
mysql:
image: mysql:latest
container_name: node_mysql
# volumes:
# - backend_app/db_sample:/docker-entrypoint-initdb.d
environment:
MYSQL_USER: user
MYSQL_PASSWORD: user
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: default_schema
And mysqlJS connection details
// environment variables
const PORT = process.env.PORT || 4006;
const HOST = process.env.HOST || 'localhost';
// // mysql credentials
const connection = mysql.createConnection({
host: HOST,
user: process.env.MYSQL_USER || 'root',
password: process.env.MYSQL_PASSWORD || 'root',
connectTimeout: 20000
});
So, phpmyadmin is working and i can access databases/create/delete/edit by that so this assure that mysql itself also working, But right now I'm unable to connect it with mysqlJS of my nodejs app.
here's the sample project with the problem if you would like to try on your machine project GitHub link with YAML file
Note: Check answer added a complete solution of this issue.
I'm assuming the phpMyAdmin instance is working since you are actually passing the env var PMA_HOST and PMA_PORT correctly to the container.
You will need to do the same for the JS application, so your docker-compose config will look like the following:
node_backend:
container_name: node_with_pa_msql
build: ./backend_app
# volumes:
# - ./backend_app:/usr/src/app
environment:
MYSQL_HOST: mysql
MYSQL_PORT: 3306
links:
- mysql
depends_on:
- mysql
restart: on-failure
ports:
- 3004:4006
Then in your JS code you need to get the connection information from your env variables:
// environment variables
const PORT = process.env.MYSQL_PORT || 4006;
const HOST = process.env.MYSQL_HOST || 'localhost';
// // mysql credentials
const connection = mysql.createConnection({
host: HOST,
port: PORT,
user: process.env.MYSQL_USER || 'root',
password: process.env.MYSQL_PASSWORD || 'root',
connectTimeout: 20000
});
This works because when you link the mysql container, a hosts entry is added to your js container which makes the hostname mysql point to the (docker internal) ip address of the mysql container.
Finally after a big mess, solved this issue!
With stated above YAML file. everything is almost OK, But the main problem is order of image.
That means I have total 3 image from them node is dependent to mysql. So first mysql must has to start so then you can get the connection of mysql and use it with your application (nodeJS). This is the reason why any host were not resolving with my implementation.
I followd this article: https://docs.docker.com/compose/startup-order/
and for implementation example this: https://dev.to/hugodias/wait-for-mongodb-to-start-on-docker-3h8b
You are done! now use your desired driver
Now
this is node (mysqlJS) package specific. the package by itself doesn't support latest mysql and if you use latest tagged mysql mysql:latest then you may face this issue.
Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client docker mysql node
quick solution downgrade it to lower until it works. I'm not sure about minimum version but mysql:5.6 works!
If you want a quick starter with everything phpmyadmin,mysql,nodejs app
then you can use this repo: Here
I am running into this error with my Rails + MySQL Docker setup:
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)
/usr/local/bundle/gems/mysql2-0.5.2/lib/mysql2/client.rb:90:in `connect'
/usr/local/bundle/gems/mysql2-0.5.2/lib/mysql2/client.rb:90:in `initialize'
my docker-compose.yml:
version: '3.7'
services:
db:
# https://github.com/passbolt/passbolt_docker/issues/103
image: mysql:5.7
restart: always
healthcheck:
test: ["CMD-SHELL", 'mysql --database=$$MYSQL_DATABASE --password=$$MYSQL_ROOT_PASSWORD --execute="SELECT count(table_name) > 0 FROM information_schema.tables;" --skip-column-names -B']
interval: 30s
timeout: 10s
retries: 4
environment:
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "3305:3306"
expose:
- '3305'
volumes:
- my-db:/var/lib/mysql
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- '.:/app'
ports:
- '3000:3000'
environment:
DB_PORT: 3306
DB_HOST: db
DATABASE_URL: mysql2://user:password#db:3306
depends_on:
- db
volumes:
my-db:
and my database.yml:
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: user
password: password
host: localhost
url: <%= ENV['DATABASE_URL'] %>
port: 3305
According to this, I'm supposed to wait for MySQL to start? However I added a health check in the healthcheck section of the docker-compose file and it didn't work.
I also tried to use netcat to check the port but it also didn't work. How come I can't connect to the host db from my Docker web container? What am I doing wrong?
Turns out for my problem, I needed to clear out my docker volumes and recreate everything. MySQL was experiencing an error while booting up.
Basically ran this:
docker-compose down
docker system prune --force --volumes
And then restarted everything, ensuring that MySQL ("db") was running successfully before trying to connect to db.
This message is complaining about a missing "MYSQL host" called 'db'
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)
According to your docker-compose file
environment:
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
You should choose here a valid parameters (use ENV variables even better).
Also make sure
you can access MYSQL from console with the specified credintials.
The specified MYSQL user has access from external host ( docker is will not be on the same network )
When I try to connect two docker containers on the same machine, one running a node.js server and the other running mysql dbms
I get the following error:
(node:32) UnhandledPromiseRejectionWarning: Error: getaddrinfo ENOTFOUND jdbc:mysql://localhost:3306 jdbc:mysql://localhost:3306:3306
mysql driver connection config
const connection= mysql.createConnection({
host: 'jdbc:mysql://topsectiondb:3306',
user: 'root',
password: 'rootpass'
})
docker-compose.yml
version: '3'
services:
topsection:
container_name: topsection-server
restart: always
build: .
ports:
- '7777:7777'
depends_on:
- topsectiondb
environment:
- PORT=7777
topsectiondb:
container_name: topsectiondb
image: mysql:8.0.3
ports:
- '3306:3306'
environment:
- MYSQL_ROOT_PASSWORD=rootpass
Dockerfile
FROM node:10
RUN mkdir serviceFolder
WORKDIR /usr/app/
COPY . .
RUN npm install
EXPOSE 7777
CMD ["npm", "start"]
for a more complete stack trace
https://gist.github.com/armouti/877a8b4405330c44e4009ebae3df822c
First of all there are a couple of problems here.
Firstly you need to look at networking your docker containers in your docker-compose file together. Basically each container doesn't know of the other until you specify which network they are in. Each container can be in multiple but if you want two containers to connect they need to be in the same network. https://docs.docker.com/compose/networking/#configure-the-default-network
Then Secondly you can't use localhost as a url. Basically a docker container is an isolated environment so it has it's own "localhost" so when you use that address it's actually trying to connect to the mysql on the nodejs container. So when networked properly you will be able to connect to the mysql container using their names you gave them in the docker-compose something like topsectiondb:3306 or something like this. This tells docker your using networking to connect one docker container to another and will allow you to make the initial connection. Connect to another container using Docker compose
===================================================
Actual Answer:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
Basically the mysql library requires a hostname, which in most cases is localhost, but as your linking containers with docker-compose you use the alias of the container. The port number is 3306 by default
So:
host: "topsectiondb" will suffice!
I have a rails app that I'm running in Docker. I want to run MySQL in a separate container and connect the two.
My docker-compose.yml file looks like this:
# docker-compose.yml
db:
image: "mysql:5.6"
ports:
- 3306
environment:
MYSQL_ROOT_PASSWORD: pass
MYSQL_DATABASE: dbname
MYSQL_USER: user
MYSQL_PASSWORD: pass
web:
build: .
ports:
- "80:80"
env_file:
- .env.development
links:
- db
volumes:
- "/webapp:/home/app/webapp"
When I run docker-machine ip default I get 192.168.99.100.
When I run docker ps I see mysql is running on PORT: 3306/tcp, 0.0.0.0:32782->32781/tcp Edit: After removing the mysql container and restarting it, the port is actually 0.0.0.0:32784->3306/tcp
I'm using the Sequel gem, and using the following params to connect to my db:
Sequel::Model.db = Sequel.connect(adapter: 'mysql2',
database: 'dbname',
user: 'user',
password: 'pass',
host: '192.168.99.100',
port: '3306',
loggers: [logger] )
When I run my app, I get:
rake aborted!
Sequel::DatabaseConnectionError: Mysql2::Error: Can't connect to MySQL server on '192.168.99.100' (111)
/var/lib/gems/2.0.0/gems/mysql2-0.3.18/lib/mysql2/client.rb:70:in `connect'
/var/lib/gems/2.0.0/gems/mysql2-0.3.18/lib/mysql2/client.rb:70:in `initialize'
/var/lib/gems/2.0.0/gems/sequel-4.23.0/lib/sequel/adapters/mysql2.rb:36:in `new'
/var/lib/gems/2.0.0/gems/sequel-4.23.0/lib/sequel/adapters/mysql2.rb:36:in `connect'
/var/lib/gems/2.0.0/gems/sequel-4.23.0/lib/sequel/connection_pool.rb:101:in `make_new'
// Lots more traces
Any ideas what I'm doing wrong here?
Try using the link name as "host" in your connection settings. Change the IP address to "db".