Docker compose does not execute .sql - mysql

Trying to use docker compose for my application, so using official mysql images and my own Dockerfile to create my app image. I think some how my initdb.sql is not executed during docker compose up.
Running this as :
docker-compose up --build
But I can not see that initdb.sql is executed.
My docker compose looks like this:
version: "3"
services:
db:
image: mysql:5.7
restart: always
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_DATABASE: "MYDB"
MYSQL_USER: "myuser"
MYSQL_PASSWORD: "mypassword"
MYSQL_ROOT_PASSWORD: "mypassword"
ports:
- "3306:3306"
expose:
- "3306"
volumes:
- my-db:/var/lib/mysql
- ./sqlinit:/docker-entrypoint-initdb.d/initdb.sql
networks:
vpcbr:
ipv4_address: 10.5.0.6
app:
restart: always
build: .
ports:
- 5000:5000
volumes:
- .:/app
depends_on:
- db
networks:
vpcbr:
ipv4_address: 10.5.0.5
volumes:
my-db:
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
# gateway: 10.5.0.1
As you can see I have my initdb.sql in this directory ./sqlinit and after I login to mysql container I can see this file in /docker-entrypoint-initdb.d/initdb.sql
But looks like is not executed because when I login to my app I can see:
pymysql.err.OperationalError: (1044, "Access denied for user 'myuser'#'%' to database 'MYDB'")
and on container mysql
2019-09-15T13:17:59.361447Z 2 [Note] Access denied for user 'myuser'#'%' to database 'MYDB
Of course I'm doing something wrong, I found some similar problems here but I still haven't fixed my issue

The problem should be in the way you are mapping the volume. You should map the source file into the target file instead of a source folder into a file, like so:
- ./sqlinit/initdb.sql:/docker-entrypoint-initdb.d/initdb.sql

Related

Laravel dockerized app taking DB_HOST as SERVER_ADDR instead of container

I have a laravel app and the database containers are configured in this way:
db:
image: "mysql:5.7"
command: ["--sql- mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"]
environment:
MYSQL_DATABASE: mydb
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
networks:
- simple_net
app:
build:
context: .
dockerfile: ./setup/Dockerfile
restart: unless-stopped
tty: true
ports:
- "${APP_PORT}:80"
working_dir: /var/www/
volumes:
- ./:/var/www/
environment:
DB_CONNECTION: mysql
DB_HOST: db
DB_DATABASE: mydb
DB_USERNAME: root
# SERVER_ADDR: localhost
When I tried to start the app with docker-compose up it throws an exception that says SQLSTATE[HY000] [1045] Access denied for user 'root'#'172.23.0.6' (using password: NO). The IP refers to the environmental variable SERVER_ADDR, I tried to set it up with the values localhost and '' (empty) but nothing has worked so far.
You should set the .env's DB_HOST to the name of your container, in your case db.
DB_HOST=db
I do not believe injecting environment variables replaces filling the .env.
Also, if you want to Dockerize your Laravel applications, several options already exist and work out of the box:
Laradock
Docker Compose Laravel
Laradose (which I maintain)
You don't need DB_CONNECTION: mysql there.
Instead inside your .env file in lavel you will use this like:
DB_CONNECTION: mysql
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: mydb
DB_USERNAME: root
DB_PASSWORD: password
Your app container does not need this environment, that's your server running. You try to configure the environment of the db container inside server container which will run your app.
Change your docker-compose to:
db:
image: "mysql:5.7"
command: ["--sql- mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"]
environment:
MYSQL_ROOT_USER: root
MYSQL_ROOT_PASSWORD: password
MYSQL_DATBASE: mydb
MYSQL_USER: root
MYSQL_PASSWORD: password
SERVICE_TAGS: dev
SERVICE_NAME: mysql
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped
networks:
- simple_net
app:
build:
context: .
dockerfile: ./setup/Dockerfile
restart: unless-stopped
tty: true
ports:
- "${APP_PORT}:80"
working_dir: /var/www/
volumes:
- ./:/var/www/
networks:
- simple_net
Bridge your containers under your network so they can interact with each other.
Run docker-compose up --build and then access your laravel container and run inside the container php artisan optimize to configure cache for routes,env variables, files etc etc.
docker exec -it db mysql -u root -p password
Based on your comments you have issues to access the container and the reason is you don't use credentials for it and mysql tries to use the default ones. Above command defines the right user and password, you will also be asked to fill the password.
Also mysql has more parameters to define the host etc etc you can have a look further for that.

How to fix 'The server requested authentication method unknown to the client [caching_sha2_password]' on docker compose?

I'm setting up a wamp. The docker-compose was working very well until I experience some problems with the phpmyadmin and mysql container. I couldn't connect nor from php or phpmyadmin and usually had this error message : mysqli_real_connect(): The server requested authentication method unknown to the client [caching_sha2_password]
I was able to solve the problem by just connecting entering the shell of the db container docker exec -it db mysql -uroot -p and running this command : ALTER USER 'root' IDENTIFIED WITH mysql_native_password by '123456'; But this kind of boring because I have a partner working on the same project and we have to change working posts a lot so it means rerun docker each time in the development phase so I was wondering what's wrong on my docker-compose...
Here it is :
version: "3.1"
services:
www:
build: .
container_name: app
ports:
- "8001:80"
volumes:
- ~/Desktop/WORK_in_progress/camagru/www/:/var/www/html/
links:
- db
networks:
- default
db:
image: mysql:8.0
container_name: db
restart: always
tty: true
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
command: --innodb-use-native-aio=0
environment:
MYSQL_DATABASE: CAMAGRU
MYSQL_USER: user
MYSQL_PASSWORD: 123456
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ~/Desktop/WORK_in_progress/camagru/dump:/docker-entrypoint-initdb.d
- ~/Desktop/WORK_in_progress/camagru/conf:/etc/mysql/conf.d
- persistent:/var/lib/mysql
networks:
- default
phpmyadmin:
container_name: phpmyadmin
restart: always
tty: true
image: phpmyadmin/phpmyadmin
links:
- db:db
ports:
- 8000:80
environment:
MYSQL_USER: user
MYSQL_PASSWORD: 123456
MYSQL_ROOT_PASSWORD: 123456
volumes:
persistent:
note : I don't use any configurations file, I modified a bit a compose that I found online.
Your command is right, the issue appears because you have defined the command key two times, and the second one is overriding the first one. Instead you should define it only once and like this:
command: --default-authentication-plugin=mysql_native_password --innodb-use-native-aio=0

How to fix "Access denied for user 'root'#'172.22.0.4' (using password: YES)" when connecting to mysql container?

I'm creating a laravel project in a docker container, along with MySQL and phpmyadmin, when trying to migrate (or access the database from phpmyadmin) I get access denied error.
I've tried several SOF solutions but none of them worked, also tried ones in GitHub issues.
here is my docker-compose.yml
version: "3"
services:
web:
container_name: ${APP_NAME}_web
build:
context: ./docker/web
ports:
- 9000:80
volumes:
- ./:/var/www/app
networks:
- mynet
db:
image: mysql:5.7
container_name: db
command: --default-authentication-plugin=mysql_native_password
restart: always
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: laracocodb
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
volumes:
- mysqldata:/var/lib/mysql/
networks:
- mynet
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: phpma
links:
- db:db
ports:
- 9191:80
environment:
MYSQL_USERNAME: root
MYSQL_ROOT_PASSWORD: root
PMA_HOST: db
networks:
- mynet
networks:
mynet:
driver: bridge
volumes:
mysqldata:
driver: local
no matter where I access the database (from db container bash, from phpmyadmin index page or from the web service when trying to migrate the database), the error is always access denied
I have also run into this problem many times, by default MySQL allows root to be accessed by localhost user that means even if you have opened the port 3306:3306, you will still need to add the user.
Follow these commands and the error will resolve!
https://stackoverflow.com/a/11225588

Host 'X' is not allowed to connect to this MySQL server

I wanna deploy MySQL+PHPMyAdmin. My docker-compose.yml:
version: "3"
services:
db:
image: mysql:5.7
restart: always
container_name: db
volumes:
- ./~mysql:/var/lib/mysql
- ./mysql.cnf:/etc/mysql/conf.d/my.cnf
environment:
MYSQL_DATABASE: "dbtest"
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_ROOT_HOST: "%"
networks:
- db
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: "mysqladmin ping -h localhost"
interval: 1s
timeout: 1s
retries: 60
phpmyadmin:
image: phpmyadmin/phpmyadmin:4.7
restart: always
container_name: phpmyadmin
ports:
- 8080:80
networks:
- external-net
- db
environment:
PMA_HOST: db
depends_on:
- db
networks:
external-net:
external:
name: external-net
db:
driver: bridge
After some time later I getting subject error. MYSQL_ROOT_HOST don't helped. When I trying to connect to mysql from db-container:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
I really don't know what to do with this magic... Thx.
This problem might occur, if the files on your local system were created in a corrupted way or are not correctly accessible by the Docker daemon. This might be due to the following reasons:
Docker is lacking the access rights on your local hard drive, on Windows e.g. C.
While building up your containers Docker didn't have the access rights to your local hard drive. Even though Docker asks during the first --build process to allow an access to C on Windows these files might still be corrupted.
The solution could be do delete the according local files after the access to Docker has been granted, in your case these are files in /~mysql and the file mysql.cnf.
You can pass an extra environment variable when starting the MySQL container MYSQL_ROOT_HOST= this will create a root user with permission to login from given IP address. In case where you want to allow login from any IP you can specify MYSQL_ROOT_HOST=%.
This will work only for a newly created containers.
When spinning new container:
docker run --name some-mysql -e MYSQL_ROOT_HOST=% -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest
In compose file it would be
version: '2'
services:
### Mysql container
mysql:
image: mysql:latest
ports:
- "3306:3306"
volumes:
- /var/lib/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test_db
MYSQL_USER: test
MYSQL_PASSWORD: test_pass
MYSQL_ROOT_HOST: '%' # needs to be enclosed with quotes
I've recreated your setup and was just adding some ENV configuration to do the trick, I've removed volumes section because there was no problem with it:
docker-compose.yml
version: "3"
services:
db:
image: mysql:5.7
restart: always
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=rootpasswd
- MYSQL_DATABASE=phpmyadmin
- MYSQL_USER=user
- MYSQL_PASSWORD=userpasswd
networks:
- db
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: "mysqladmin ping -h localhost"
interval: 1s
timeout: 1s
retries: 60
phpmyadmin:
image: phpmyadmin/phpmyadmin:4.7
restart: always
container_name: phpmyadmin
ports:
- 8080:80
networks:
- external-net
- db
environment:
PMA_HOST: db
depends_on:
- db
networks:
external-net:
external:
name: external-net
db:
driver: bridge
Accessing PHPMyadmin with root:rootpasswd works fine.
For some reason using "~" before the volume path solves the problem for me.
volumes:
- ./~mysql:/var/lib/mysql
- ./mysql.cnf:/etc/mysql/conf.d/my.cnf
Change this code to
volumes:
- ~/mysql:/var/lib/mysql
for MySQL container.
In Genetal settings of Docker enable daemon without TLS. I think It works.
Docker image

docker nodejs container cant connect mysql container

I'm running Docker server in Digital Ocean. There I have two containers Nodejs and Mysql. Mysql container has open port to 3306.
When trying to access mysql via nodejs by Docker Server ip + port. I get Error: connect ETIMEDOUT.
When I run same nodejs docker setup in my local computer it works fine. Is there something i'm missing?
Here is nodejs docker-composer.yml:
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST=192.168.11.207 #or public ip in internet
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
Here is docker-composer.yml for mysql
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
I'll modify answer as we advance - Following your comments, while I can not access to your env, lets try to solve this incrementally:
Let's make the db visible to the node.js server
See how it works and then probably dive into env networking configuration.
There 2 ways to solve 1st and may be 2nd problem as i see without being able to touch your env:
1st one will ensure that the server sees the database, but if you can not connect to the db from outside seems there firewall/droplet networking configuration issue, and you can try 2nd way (wont likely to change, but it's good to try). This assumes you use same docker compose and same bridge cusom network:
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST= mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
networks:
inner:
alias: server
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "<externalEnvIp>:3036:3306"
restart: always
networks:
inner:
alias: mysql
networks:
inner:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "true"
com.docker.network.bridge.enable_ip_masquerade: "true"
ipam:
driver: default
config:
- subnet: 172.16.100.0/24
gateway: 172.16.100.1
Option 2 :
version: '2'
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST= mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
network_mode: "host"
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
network_mode: "host"
More precise solution (to find the roots of the problem) would involve into deep digging into your env network configuration, docker networking settings etc., but those solutions may help and fix your problem for now.
Pleasse after you try please output the results.
The docker networking doesn't allow you to go from inside a container back out to the host IP to connect to a port exposed by another container. I haven't dug into this enough to see if that's due to the iptables rules or perhaps something inside of docker-proxy. Either way, it's never been worth investigating since container-to-container networking is a built in feature of docker.
To use docker's networking, the containers need to be on the same docker network, and you reference them by their container name in DNS. With docker-compose, normally you can use the service name in place of the container name (e.g. test-web-install and mysql from your examples) since compose creates an alias for these. However, since you've overridden the container name for mysql, use your flask_mysql container name instead.
In your scenario, since you've split up the startup with two separate docker-compose.yml files, you'll be on separate networks created by compose. You have two options to resolve this:
Merge the two into a single docker-compose.yml (BlackStork gave an example of this).
Use an externally defined network that you create in advance.
To do the latter, first create your network:
docker network create dbnet
Then update your docker-compose.yml for the app to look like:
version: '2'
networks:
dbnet:
external: true
services:
test-web-install:
image: example-nodejs:latest
working_dir: /home/app
volumes:
- ./:/home/app
command: sh -c 'nodemon'
environment:
- NODE_ENV=development
- DB_HOST=flask_mysql
- DB_PORT=3036
- DB_PASSWORD=root
- DB_USER=root
- DB_DATABASE=root
ports:
- "3000:3000"
networks:
- dbnet
And the docker-compose.yml for mysql:
version: '2'
networks:
dbnet:
external: true
services:
mysql:
container_name: flask_mysql
restart: always
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 'root' # TODO: Change this
MYSQL_USER: 'root'
MYSQL_PASS: 'root'
MYSQL_DATABASE: 'root'
volumes:
- ./data:/var/lib/mysql
ports:
- "3036:3306"
restart: always
networks:
- dbnet