using environment variables in docker-compose mounted files for initializing mysql - mysql

I am having trouble initializing mysql via docker-compose with the use of /docker-entrypoint-initdb.d whenever my initializing scripts requires environment variables.
I have the following docker-compose.yml file.
version: '3'
services:
mysql:
image: mysql
container_name: mysql
restart: always
env_file: .env
environment:
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASS
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASS
- MYSQL_DB=$MYSQL_DB
volumes:
- db-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- $MYSQL_PORT:3306
volumes:
db-data:
This is my ./init.sql
CREATE DATABASE IF NOT EXISTS ${MYSQL_DB};
GRANT ALL PRIVILEGES ON ${MYSQL_DB}.* TO '${MYSQL_USER}'#'%';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
When I run docker-compose up, I get an error with my ./init.sql and here's what it says:
mysql | 2021-07-16 14:53:17+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
mysql | ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{MYSQL_DB}' at line 1
Everything works perfectly if I change my ~/init.sql to use hardcoded values like this :
CREATE DATABASE IF NOT EXISTS testingdb;
GRANT ALL PRIVILEGES ON testingdb.* TO 'testinguser'#'%';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
# where testingdb and testinguser is my .env.MYSQL_DB and .env.MYSQL_USER respectively
How do I use environment variables in docker's volume mounted files?

Env variables can be used in .sh file, so you can achieve what you want like this:
Create an init_db.sh file (instead of init_db.sql)
Then in the init_db.sh file:
echo "** Creating default DB and users"
mysql -u root -p$MYSQL_ROOT_PASSWORD --execute \
"CREATE DATABASE IF NOT EXISTS $MYSQL_DB;
GRANT ALL PRIVILEGES ON $MYSQL_DB.* TO '$MYSQL_USER'#'%';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
echo "** Finished creating default DB and users"

Related

Connection refused on mysql with user granted on %

I see other question like this here on S.O. but no one solved my problem.
I'm running MySQL using Docker, and on the first boot, I'm running some SQL queries to prepopolate the DB. One of those is the following:
CREATE USER 'user'#'%' IDENTIFIED BY 'user';
Grant All Privileges ON *.* to 'user'#'%';
FLUSH PRIVILEGES;
However, when I try to connect to the DB from another container, I get:
SQLSTATE[HY000] [2002] Connection refused (SQL: ...)
What am I doing wrong?
This happens both if I use the name of the container, and 127.0.0.1 as host
my docker-compose looks like this:
#MySQL Service
db:
image: mysql
container_name: db
restart: unless-stopped
tty: true
ports:
- "3307:3306"
- "8001:3306"
environment:
....
volumes:
- ./database/dbdata:/var/lib/mysql/:rw
- ./config/mysql/my.cnf:/etc/mysql/my.cnf
the strangest part of all of this, is that if I connect to the DB with a MySQL client installed on my PC, the connection works fine...
my.cnf is the following:
[mysqld]
general_log = 1
general_log_file = /var/lib/mysql/general.log
secure-file-priv = NULL
bind-address = 0.0.0.0

mysql docker image how to create databases with their own username and password

I have a docker image as follows:
version: '3.6'
services:
# MySQL
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: mydb
MYSQL_USER: user
MYSQL_PASSWORD: user
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3306:3306'
expose:
# Opens port 3306 on the container
- '3306'
volumes:
- ./init:/docker-entrypoint-initdb.d
The init folder directory is as follows:
init
01.sql
The 01.sql is defined as follows:
CREATE DATABASE IF NOT EXISTS `test`;
GRANT ALL ON `test`.* TO 'user'#'%';
When I execute docker-compose up the two databases are created successfully, but both mydb and test are using same username and password. Is it possible to create a different user and password for test database?
update:
I have updated the script 01.sql to:
CREATE DATABASE IF NOT EXISTS `test`;
CREATE USER 'newuser'#'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON test.* TO 'newuser'#'localhost' WITH GRANT OPTION;
But when I try to connect using DBeaver(username:newuser,password:password) get the error access denied.
However when I connect using username:root, password:root i can see the table created:
Thanks in advance
Any idea what i am doing wrong please?

Unable to connect Mysql 8 running on docker with mysql workbench

I have a docker setup that is running Mysql 8.
I am able to access Mysql inside docker container, however, I am unable to connect using Mysql workbench. I have another mysql container but this one is Mysql version 5.7 and I have no issues connecting with that one.
I have tried to allow root user full host access with % in the mysql.user
| root | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
I have tried to connect to container using hostnames: localhost, 0.0.0.0, 127.0.0.1
and port 3306 but no luck
I also created a separate user and gave full privilege and still no luck
Below is my Docker compose file
version: '3.5'
services:
database:
build:
context: ./images/mysql
restart: always
command: ['--default-authentication-plugin=mysql_native_password']
environment:
- MYSQL_DATABASE=inim
- MYSQL_USER=inimuser
- MYSQL_PASSWORD=inimpass
- MYSQL_ROOT_PASSWORD=docker
ports:
- "3306:3306"
volumes:
- ./database/data:/var/lib
volumes:
my-datavolume:
my Dockerfile:
FROM mysql:8.0.20
CMD ["mysqld"]
EXPOSE 3306
Below is my Docker PS
b8832d9711b4 docker_inim_db_database "docker-entrypoint.s…" 14 minutes ago Up 14 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp docker_inim_db_database_1
I have a similar setup with Mysql 5.7 and it connects fine. Not sure what I am doing wrong here.
You can debug your process by going to the container.
Please run:
$ docker exec docker_inim_db_database_1 /bin/bash
Now you should be in bash of the container.
Then login to mysql bash using:
$ mysql -uroot -p
and type your password or just press Enter if none.
There's two steps in that process:
a) Grant privileges. As root user execute with this substituting 'password' with your current root password :
GRANT ALL PRIVILEGES ON *.* TO 'root'#'%' IDENTIFIED BY 'password';
b) bind to all addresses:
The easiest way is to comment out the line in your my.cnf file:
#bind-address = 127.0.0.1
and restart mysql
service mysql restart
By default it binds only to localhost, but if you comment the line it binds to all interfaces it finds. Commenting out the line is equivalent to bind-address=*.
To check where mysql service has binded execute as root:
netstat -tupan | grep mysql
Update For Ubuntu 16:
Config file is (now)
/etc/mysql/mysql.conf.d/mysqld.cnf
Most of steps above are from answer: https://stackoverflow.com/a/11225588/659077

Unable to create a prepared MySql DB using docker-compose

I am trying to create a prepared Mysql DB using Docker compose, the outcome is to create the "INTERVIEW" Database and give the username "ADMIN" the access to it.
For this purpose, the folder setup_scripts contains the sql script(create_user.sql) as below to grant access:
grant all privileges on INTERVIEW.* to 'ADMIN'#'%' with grant option;
FLUSH PRIVILEGES;
The docker compose file:
services:
db:
image: mysql:8.0.17
restart: always
env_file:
- .env
ports:
- '32768:3306'
volumes:
- "./my-db-data:/var/lib/mysql"
- "./setup_scripts:/docker-entrypoint-initdb.d"
volumes:
my-db:
And the .env file:
MYSQL_DATABASE='INTERVIEW'
MYSQL_USER='ADMIN'
MYSQL_PASSWORD='password'
MYSQL_ROOT_PASSWORD='password'
Upon docker-compose up, the below error is seen, but i am unable to debug the source of the issue:
ERROR 1064 (42000) at line 5: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' at line 1
Is there a way to see verbose logs for the db startup to understand the file where the error originates?.
The issue was with the env-file declaration:
it should be as below:
env_file:
- ./.env

Unable to login to a mysql container in docker

I'm trying to set up an application which has 1 node.js server and 1 mysql database. I'm trying to integrate this with docker. I'm having trouble trying to login to mysql from my node.js app.
in short - here's my docker-compose.yml file
version: '2.1'
services:
db:
build: ./db
restart: always
environment:
# - MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=subscriptions
- MYSQL_PASSWORD=supersecretpassword
- MYSQL_ROOT_PASSWORD=supersecretpassword
- MYSQL_USER=root
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 30s
timeout: 1s
retries: 1
subscription_api:
build: ./subscription_api_server
restart: always
depends_on:
db:
condition: service_healthy
ports:
- "5000:5000"
My Dockerfile for mySQL
CREATE DATABASE IF NOT EXISTS subscriptions;
grant all privileges on *.* to root#localhost identified by 'supersecretpassword' with grant option;
FLUSH PRIVILEGES;
My node.js application uses sequelize as the ORM and the connection string is specified here config.js
"development": {
"username": "root",
"password": "supersecretpassword",
"database": "subscriptions",
"host": "db",
"dialect": "mysql"
},
When i run docker-compose up - i get the below error from my node.js application
subscription_api_1 | Sequelize CLI [Node: 10.12.0, CLI: 5.1.0, ORM: 4.39.0]
subscription_api_1 |
subscription_api_1 | Loaded configuration file "config/config.json".
subscription_api_1 | Using environment "development".
subscription_api_1 | Sun, 14 Oct 2018 17:50:17 GMT sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators at node_modules/sequelize/lib/sequelize.js:242:13
subscription_api_1 |
subscription_api_1 | ERROR: Client does not support authentication protocol requested by server; consider upgrading MySQL client
But the username/password work when i try to directly ssh into my docker container
sudo docker exec -it fullstack-dev-assignment_db_1 bash
root#d36f499b706e:/# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
root#d36f499b706e:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Am i doing something wrong with the way sequelize is setup?
I guess you are eventually pulling the mysql:latest docker image, which in this case would be from the 8.0 series. The problem is that MySQL 8.0 is now using a default authentication plugin that is incompatible with the community Node.js driver used by sequelize.
You should follow the steps described here to overcome that limitation.
In your case, besides granting the privileges, you would have to first switch the user authentication plugin as well.
ALTER USER 'root'#'localhost' IDENTIFIED WITH mysql_native_password BY 'supersecretpassword';
GRANT ALL PRIVILEGES ON *.* TO 'root'#'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;