Docker - How to take a look at the Tables inside MySQL volume? - mysql

I have imported an SQL file contains my schema and all its tables, By using:
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
- ./resources/file.sql:/docker-entrypoint-initdb.d/file.sql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: db
The problem is, when I trying to retrieve data from some tables an exception in the backend appear:
throws exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table
'db.Configuration' doesn't exist
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'db.Configuration' doesn't exist
And some tables work perfectly like user table.
Although I have tested the SQL file in MySQL Workbench.
The question is, Is there a way I can see what tables are inside the db_data volume?

Yes, you can see All Table information from docker command line.
First, go inside docker container, run below command.
docker exec -it mysql_container_name mysql -uroot -p
where “root” is the username for MySQL database.
After running above command it will ask you a password.
Then Select Database, run below command
USE Name-Of-The-Database
get the list of all tables.
show tables;
Run any query, e.g select * from
SELECT * FROM table_name;
I have listed down some daily docker useful commands, have a look.
https://rohanjmohite.wordpress.com/2017/08/04/docker-daily-useful-commands/
please let me know in case any further more explanation required?

You can execute any SQL command directly from the host to view your database.
You are looking for this command:
docker exec -it mysql-container mysql -uroot -pmy-secret-pw -D thisdatabase -e "SELECT * FROM table_name;
where mysql-container is the name of the mysql container
where -uroot is the account for the sql container
where -pmy-secret-pw is the password for the sql container
where thisdatabase is the name of the database to inspect
where table_name is obviously the database table name of interest
TIP: if it is a new container, and you don't know the password, just run this command:
sudo docker logs mysql-container 2>&1 | grep GENERATED

One solution is to use MySQL Workbench and create a connection pointing to the docker database container. From there you can check what schema tables have been created.
If the database docker container is started, you can inspect the container and find the IPAddress using the following command:
docker inspect container-name-here
get the IPAddress and use it in the MySQLWorkbench to create the connection

Related

MySQL Table doesn't exist error when using MSQL Docker container/MySQL Workbench

It's my first time using Docker and MySQL Workbench. I was using XAMPP before to run my mysql local server and manage the database using phpMyadmin. And all is fine, then I decided to try running mysql server using Docker and I cannot get it to work.
My error is
code: 'ER_NO_SUCH_TABLE',
errno: 1146,
sqlMessage: 'Table \'ToastHRMDB-dev.Employee\' doesn\'t exist',
sqlState: '42S02',
And my query below that is working fine when I use XAMMP, but doesn't work in mysql Docker or probably workbench is the issue?
SELECT
Employee.id as id,
Employee.employee_number as employeeNumber,
Employee.first_name as firstName,
Employee.middle_name as middleName,
Employee.last_name as lastName,
Employee.suffix as suffix,
Employee.nickname as nickname,
Employee.tr_email as trEmail,
Employee.image_url as imageUrl,
Employee.loginservice_id as authId,
Role.definition as role
FROM Employee
INNER JOIN RoleMap ON Employee.id = RoleMap.employee_id
INNER JOIN Role ON RoleMap.role_id = Role.id
WHERE Employee.tr_email = ?
AND Employee.is_del = 0`;
Here's the thing though. If I change all those table names in my query the exact casing same in the database then I can get it to run without error(using Docker/Mysql Workbench). For example changing Employee on my query to lowercase employee.
I don't want the my original query to change though. I cannot tell if this is just about some setting in Docker? Or in Mysql Workbench? I tried setting up my schema with different collation, like utf8 and ascii but no luck. Maybe I need to choose other charset type?
By the way here is the command that I ran to initialize my docker container
docker run --name mysql_5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37
You have to enable or tell MySQL to use lower case table name and Identifier Case Sensitivity doc
For Example
docker run --name mysql_5 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.37 --lower_case_table_names=1

How to import a mysql dump file into a Docker mysql container

Greetings and thanks in advance, I'm actually new to docker and docker-compose, watching a lot of videos and reading a lot of articles so far along with trying things.
I've got a front end container and a back end container that build and run alone as a Dockerfile and in a docker-compose setup.
(I've been building with Dockerfile first and then integrating the containers into docker-compose to make sure i understand things correctly)
I'm at the point where i need my database info, since i'll use docker-compose, as i understand it, it should build under the same network with a react front end and django back end.
I have a backup mysql dump file that I'm working with, what i think i need to do is have a container running mysql server and serving out my tables (like I have it locally working). I haven't been able to figure out how to import the backup into my docker mysql container.
Any help is appreciated.
What I've tried so far is using docker in the command line to outline the pieces i'll need in the Dockerfile and then what to move into the docker-compose as mentioned above:
docker run -d --name root -e MYSQL_ROOT_PASSWORD=root mysql # to create my db container
Then I've tried a bunch of commands and permutations of commands, recently in the CLI, here are some of my most recent trials and errors:
docker exec -i root mysql -uroot -proot --force < /Users/homeImac/Downloads/dump-dev-2020-11-10-22-43-06.dmp
ERROR 1046 (3D000) at line 22: No database selected
docker exec -i f803170ce38b sh -c 'exec mysql -uroot -p"root"' < /Users/homeImac/Downloads/dump-dev-2020-11-10-22-43-06.dmp
ERROR 1046 (3D000) at line 22: No database selected
docker exec -i f803170ce38b sh -c 'exec mysql -uroot -h 192.168.1.51 -p"root"' < /Users/homeImac/Downloads/dump-dev-2020-11-10-22-43-06.dmp
ERROR 1045 (28000): Access denied for user 'root'#'homeimac' (using password: YES)
I've scoured the web so far and i'm not sure where to go next, have I got the right idea? If anyone has an example of how to import a database dump (in dmp or dmp.gz), once i get that working, I'll actually do that in the docker-compose file.
Thinking about it, i just have to create the container and import so I might not even need a Dockerfile.
I'll cross that bridge when i get there. This is what I'm thinking though:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: 'app'
etc etc
I've learned a lot super fast, maybe too fast. Thanks for any tips!
The answer to your question is given in the docker hub page of MySQL.
Initializing a fresh instance
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint->initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
In your docker-compose.yml use:
volumes:
- ${PWD}/config/start.sql:/docker-entrypoint-initdb.d/start.sql
and that's it.
Here's the answer that worked for me after working with 2 colleagues that know backend better where I work.
It was pretty simple actually. I created a directory in my repo that would be empty.
I added *.sql and *.dmp to my .gitignore so the dump files would not increase the size of my image.
That directory using docker-compose would be used as a volume under the mysql service:
volumes:
- ~/workspace/app:/workspace/app
The dump file is placed there and is imported into the sql service when I run:
mysql -u app -papp app < /path/to/the/dumpfile
I can go in using docker exec and verify not only the database is there but the tables from my dump file are there as well.
For me, I had to create a new superuser also in my backend container through our Django app.
python3 manage.py createsuperuser
With that, then logging in on localhost:8000/api, everything was linked up between the mysql, backend, and frontend containers.
Hope this helps! I'm sure not all the details are the same for others post volumes, but using volumes, I didn't have to copy any dump file in and it ended up automatically imported and served. That was my big issue.
another way:
docker exec -i containername mysql -uroot -ppassword mysql < dump.sql
from the folder where dump.sql resides

Where docker stores mysql settings

I am facing one issue with docker, L am using laradock docker env for laravel. Since it has issue with mysql version I had to run those command:
$ docker-compose exec mysql bash
$ mysql -u root -p
ALTER USER 'root'#'localhost' indentified WITH mysql_native_password BY 'root';
Also imported database through http://localhost:8080 and phpmyadmin
So I am trying to reproduce this issue again, so I deleted everything from docker with
$ docker system prune
but when I rebuild the containers
sudo docker-compose up -d nginx mysql phpmyadmin workspace
My previous database is loaded again.
So my question would be how to delete db and MySQL settings, so I can execute the alter command and import database again.
Overall I am trying to determine if this issue with MySQL will occur on another platform again, so I am trying to reproduce it from scratch and that is why I need to reset completely MySQL env and databases.
So not sure where MySQL settings are stored and how to delete them.
MySQL is storing most of the important information of your container in a volume.
Now, the command:
docker system prune
do not remove the volumes, per default.
If you also want to remove them, you can run:
docker system prune --volumes
If you do want to list or act on those specific volumes:
docker volume --help
would give you all the commands on volumes like rm, ls, ...

How to run a SQL script at every MySQL initialization?

I would like to like to run a SQL script at MySQL initialization. This script has basically some UPDATE commands and has be run at each initialization. Basically, the ideia is to update Root and User passwords at each initialization, with vault credentials that are obtained at each database startup. The MySQL database is being deployed inside a Docker container.
In this scenario, is there a way to preset a SQL script that can be run at every database initialization inside a Docker container? If so, please give us an example of how to do implement that. I do use docker-entrypoint.sh and foreground.sh for some customizations at such container.
mysqld accepts a parameter that specifies initialization scripts and you can use that.
docker-compose.yml
version: "3.3"
services:
db:
image: mariadb:10.1
environment:
- MYSQL_ROOT_PASSWORD
volumes:
- ./init.sql:/script/init.sql
command: "--init-file /script/init.sql"
init.sql
UPDATE mysql.user SET authentication_string=PASSWORD("mihai") WHERE USER="root";
UPDATE mysql.user SET plugin="mysql_native_password";
.env
MYSQL_ROOT_PASSWORD=rootpassword
Run the container and test it:
docker-compose up -d
docker-compose exec db mysql -hlocalhost -uroot -pmihai
select plugin from mysql.user where USER='root';
You can see that the plugin has also been updated so the scripts both worked.
You can remove the command and test with the original password as well. Make sure to remove the volumes between runs.

Docker - MySQL commands within Dockerfile using RUN (ERROR 2002)

I am using Docker to create a dockerfile with mysql as the base image:
FROM mysql
#set root pass
ENV MYSQL_ROOT_PASSWORD password
#update linux
RUN apt-get update
#create database
RUN mysql -u root -ppassword -e "CREATE DATABASE dbname"
#install vim
RUN apt-get install vim -y
The dockerfile fails on the step where I try to create a database, it doesn't finish building and i receive this error:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
When I remove the #create database run command the dockerfile will build and I am able to run a container from that image. I know that it isn't a problem with the mysql server as I can enter the container and run the mysql command manually with success and the service status is running.
Using an environment variable i.e MYSQL_ROOT_PASSWORD within the file also allows me to create a database successfully but this will only work with a single database, I need to be able to use the mysql command to make queries, such as creating additional databases / assigning users etc.
This may be because I need to specify the host and port of the docker container but this still does not allow me to connect
RUN mysql -u root -ppassword -h 127.0.0.1 -P 3308 -e "CREATE DATABASE dbname"
Strangely, doing this also often crashes the container and puts it in a state where it will crash again on start-up every time that I try to restart it again.
I think the issue might be that in the service hasn't started within the container used to build your Dockerfile.
Try starting and configuring MySQL server within a single step. As a reference please check this file: https://github.com/dockerfile/mysql/blob/master/Dockerfile
Use below-given commands in your Dockerfile:
RUN service mysql restart && echo 'CREATE DATABASE db_name;' | mysql -uroot -
pYOUR_ROOT_PASSWORD
Had the very same problem: When starting the container and running a set of RUN instructions, or .sh or .sql scripts in /docker-entrypoint-initdb.d/ no connection to the database server could be established.
I found the solution by a comment of #wpalmer on the mysql-image:
The init scripts run by the entrypoint, internally, use the variable "${mysql[#]}" to call mysql (for example, when loading .sql files placed in the docker-entrypoint-initdb.d directory. Any .sh files which are processed by the entrypoint are included by "sourcing" them, meaning that variable is available for use by any .sh files which are run).
So what this means for you, instead of providing the plain mysql command with user, pass etc. as in
RUN mysql -u root -ppassword -e "CREATE DATABASE dbname"
use the placeholder instead:
RUN "${mysql[#]}" -e "CREATE DATABASE dbname"
You can try to build other image and run the create DB from there.
Example of docker-compose.yml
web:
build: web
links:
- "db:db.local"
entrypoint: entrypoint.sh
db:
build: db
environment:
MYSQL_ROOT_PASSWORD: password
command: mysqld
For entrypoint.sh you put something like this:
#!/bin/sh
#this is a hack to wait until the DB image is up and the port is open
until mysqladmin -u root -ppassword -e -h db.local ping; do
echo "$(date) - waiting for mysql"
sleep 3
done
if ! mysql -u root -ppassword -e -h db -e 'use dbname'; then
mysql -u root -ppassword -e "CREATE DATABASE dbname"
fi
exec "$#"
You can copy your queries as .sql file into "/docker-entrypoint-initdb.d" container directory. mysql will execute them after starting container
COPY ./init/db.sql /docker-entrypoint-initdb.d/
read official doc https://hub.docker.com/_/mysql?tab=description&page=1
Initializing a fresh instance