I have been trying to dockerize my node js application which utilizes mysqldb for databses and I have been having issues as how to dockerize mysql . I want to build my custom docker image on top of mysql which when run create database and tables so that my node js application can use those databases and table . Below is the code of my custom mysql docker image
FROM mysql:5.7
ENV MYSQL_ROOT_PASSWORD root
ENV MYSQL_DATABASE degreeclearencedatabase
ENV MYSQL_USER root
ENV MYSQL_PASSWORD 123456
COPY ./sqlscripts/ /docker-entrypoint-initdb.d/
EXPOSE 3306
CMD ["mysqld"]
and here are my sql scripts
CREATE TABLE employees (
first_name varchar(25),
last_name varchar(25),
department varchar(15),
email varchar(50)
);
While building this image I got following logs
root#localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
Now when I ran container of that custom image , I am unable to login to mysql and getting following error
Can't connect to local MySQL server through socket
'/var/run/mysqld/mysqld.sock'
I will be really grateful if someone helps me in identifying what mistakes I am doing in my docker file ?
Thanks,
Related
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
I have such a problem, I'm trying to do master-slave replication according to this tutorial https://developpaper.com/master-slave-replication-of-mysql-based-on-docker/ .
There is no problem with the building of the image, but there is a problem with running this container. I can't get access to the mysql commands of mysql container in docker, it seems to be built from mysql (image from docker hub), but can not be started.
There are the following files:
Dockerfile:
#Using MySQL image to create a new image
FROM mysql:latest
ENV MYSQL_ROOT_PASSWORD Kohc9hai
COPY start.sh /mysql/start.sh
COPY my.cnf /etc/mysql/my.cnf
COPY init.sql /mysql/init.sql
EXPOSE 6603
CMD ["sh", "/mysql/start.sh"]
init.sql:
--Create data_ Copy database
DROP DATABASE IF EXISTS `data_copy`;
CREATE DATABASE `data_copy` /*!40100 DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_general_ci */;
--Create person table
USE `data_copy`;
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
`id` int(32) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
my.cnf:
[mysqld]
log-bin = mysql-bin
server-id = 1
start.sh:
#!/bin/sh
echo "start MySQL"
service mysql start
sleep 5
echo "initialize database"
mysql -uroot -pKohc9hai < /mysql/init.sql
echo "initialization complete"
tail -f /dev/null
By getting deeper, I think that I determined that the problem is in the file start.sh (Maybe I'm wrong).
There are logs of this container:
start MySQL
mysql: unrecognized service
initialize database
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
initialization complete
Maybe someone can help me with the solution to this problem.
I'v just started to study Docker.
mysql: unrecognized service
From next, you could see there is no mysql service in container, so you surely failure:
$ docker run --rm mysql ls /etc/init.d
hwclock.sh
In fact, mysql image use next to start mysql service:
exec gosu mysql "$BASH_SOURCE" "$#"
So you need to follow the same way.
BUT, for your scenario, looks you just customize start.sh to init some sql, while it's in fact already supported in official image:
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.
So, what you need to do is next in Dockerfile (Maybe need to specify MYSQL_DATABASE also):
COPY init.sql /docker-entrypoint-initdb.d
The document is quite old (docker version 1.13.1! Now 19.03.13!!). No special setting is required to use MySQL image. All you need to do is:
docker run --name foo -d -p 6603:6603 mysql:latest
In my Dockerfile
FROM mysql:5.7
ADD ./mysql_scripts /mysql_scripts
WORKDIR /mysql_scripts
RUN mysql -u root -p < create_user.sql &&\
mysql -u root -p < create_database.sql &&\
mysql -u root -p < create_tables.sql
EXPOSE 3306
but when I build that image I have problem like:Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
You cannot run those mysql commands, because the container is not running yet, so neither is MySQL.
What you can do is copy your .sql files to /docker-entrypoint-initdb.d. MySQL will run all .sql, .sql.gz and .sh located in this directory after initialization, which would result in the following Dockerfile:
FROM mysql:5.7
COPY ./mysql_scripts /docker-entrypoint-initdb.d
EXPOSE 3306
More information can be found on the dockerhub page of mysql
You can not import database at build time, as every RUN command run in separate shell plus MySQL process also not ready to accept the connection.
You can take benefits from docker entrypoint that does these out of the box.
COPY create_user.sql /docker-entrypoint-initdb.d/
COPY create_database.sql /docker-entrypoint-initdb.d/
COPY create_tables.sql /docker-entrypoint-initdb.d/
So when the container started it will run the above script in alphabetical order
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.
mysql-docker-init-db
Also you use MYSQL_USER to create user.
I want to create an image with docker for my app.
The app uses MySQL. I need my image to be based on MySQL image (mysql/mysql-server ?) .
IN the Dockerfile i need to set some instructions to create a DB with specific user/password . So, my app can work with that DB .
I don't need tables, only empty DB with specific name and user/password that can access this DB.
How can i do this?
I wanted something like
FROM mysql/mysql-server
# Create MySQL DB
mysql -u root -e "CREATE DATABASE MyDB"
But i don't know root user password here. It seems it is autogenerated ?
How can i do this?
That image auto-generates the root password by default, as stated in the image github repository (https://github.com/mysql/mysql-docker). You can set the MYSQL_ROOT_PASSWORD environment variable in your Dockerfile with the password you want.
Apart from that, if what you want is to create a database at image startup, you can use the environment variable MYSQL_DATABASE.
More info about the supported environment variables here:
https://github.com/mysql/mysql-docker#docker-environment-variables
You have 2 solutions here:
[Easy] Using the docker-compose and create a docker-compose.yml file like this one:
version: '3'
services:
mariadb:
container_name: mariadb
image: mariadb:latest
environment:
- MYSQL_DATABASE=_YOUR_DB_
- MYSQL_ROOT_PASSWORD="_YOUR_PASSWORD_"
- MYSQL_USER=_YOUR_USER_
- MYSQL_PASSWORD=_YOUR_USER_PASSWORD_
...
This configuration will bring a MariaDB database to you. also if you want to use it, you can simply check this page for the installation guide:
https://github.com/docker/compose
The final step is just to go into the directory you saved the docker-compose.yml and just run:
docker-compose up
or if you don't want to see the log inside the terminal just add -d flag to it.
2. [Little Complicated] You can create a custom image for your needs. in this case, it is better if you check the Dockerfile documents and then see this autogenerated default MariaDB Dockerfile for understanding what to do exactly to achieve your goal.
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