How to execute query using script in MySQL Docker image? - mysql

I am trying to give user a web interface in which , user can write a query and then i will be executing that query on my server.
I am using the following MySQL docker image with the latest tag i.e. mysql:latest
https://hub.docker.com/_/mysql/
So i am runnig the docker image using this command
docker run -it --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -v /root/ServerCode/:/usercode mysql /bin/bash
My root/ServerCode directory contains a script which i want to use for running mysql server and user's query.
My script is
#!/bin/bash
set -e
/etc/init.d/mysqld start
It gives me error
bash: /etc/init.d/mysqld: No such file or directory
I have also tried using this
service mysqld start
It is also giving error
mysqld: unrecognized service
Edit:
#!/bin/bash
set -e
exec 1> $"/usercode/logfile.txt"
exec 2> $"/usercode/errors"
# These output and error files are in mounted folder which i check after running script
/etc/init.d/mysqld start // run sql server here
#here i want to run that query and then get out of conatiner `

The entyrypoint scipt only does the initdb if mysqld is the argument; in your case it sees bash and so skips the initdb and just runs bash with its arguments.
If you are just trying to run some setup scripts once mysql is running have you looked at /docker-entrypoint-initdb.d/?
Create a docker-compose.yml
version: '2'
services:
db:
image: mysql
container_name: mysql
restart: always
volumes:
- /var/db/startuphry/mysql:/var/lib/mysql
- ./conf/my.cnf:/etc/mysql/conf.d/settings.cnf
- ./conf/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
ports:
- "${MYSQL_PORT}:3306"
Create a conf folder add the my.cnf file to it
[mysqld]
local-infile=0
Create folder docker-entrypoint-initdb.d inside conf folder and all sql files inside this folder
Tree looks likes this
|____docker-compose.yml
|____conf
|___my.cnf
|___docker-entrypoint-initdb.d
|___one.sql
|___two.sql
You can put any .sh files or .sql files in there and they will be run/imported before the mysql service is available outside the container.

Try running the "/etc/init.d/mysqld start" inside the mysql docker container.
/root/server is a host machine path . Mysql has been installed in container not in the host machine. Please run the "/etc/init.d/mysqld start " not in the host machine.

Related

Service mysql not runnig Dockerfile

I have from issue running mysql using Dockerfile
FROM mysql:latest
# Add a database
ENV MYSQL_DATABASE some_table_name
ENV MYSQL_ROOT_PASSWORD some_password
ADD some_table.sql /docker-entrypoint-initdb.d
ENTRYPOINT /bin/bash
Building an image works for this code but mysql service is not found in the container when I try to run service mysql start. mysqld command would not run due to some root security issues. Is anyone able to help? Thank you.
Remove the ENTRYPOINT
build and run the container.
Run another process to check inside the container name like:
docker exec -ti {containername} mysql -u root -p
This will check the password is set right. Then SHOW CREATE TABLE {db.tablename}

Build docker container for Mysql 8.0 fail

I need create a docker container for several projects tha use Mysql 8.0 with PHP 7.3
I like create it, because I need modify mysql startup configuration
For this I create
Dockerfile
FROM mysql:8.0
COPY mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf
ENV MYSQL_ROOT_PASSWORD="123456"
mysqld_charset.cnf
[mysqld]
default-authentication-plugin = mysql_native_password
collation-server = utf8mb4_general_ci
character-set-server = utf8mb4
License and readme files.
Execute
$ docker build --no-cache -t mysql8_legacy_password .
Sending build context to Docker daemon 14.85kB
Step 1/3 : FROM mysql:8.0
---> 62a9f311b99c
Step 2/3 : COPY mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf
---> 0e21143ae822
Step 3/3 : ENV MYSQL_ROOT_PASSWORD="123456"
---> Running in a8d350dbd651
Removing intermediate container a8d350dbd651
---> 7dd66b27be00
Successfully built 7dd66b27be00
Successfully tagged mysql8_legacy_password:latest
$ docker run --name mysql8_legacy_password -it mysql:8.0
error: database is uninitialized and password option is not specified
You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD
The issue is in the run command.
docker run --name mysql8_legacy_password -it mysql:8.0
You are trying to start a container from mysql:8.0 image in which no env has been setup.
The last argument of the docker run command should be the image name. Since you have tagged your image as mysql8_legacy_password, this should work:
docker run --name container_name -it mysql8_legacy_password
docker run

Docker MySQL container unable to wait for MySQL server ready

I am attempting to create a docker container using the mysql:5 docker image. Once the MySQL server is up and running I want to create some databases, users and tables.
My Dockerfile looks like this;
FROM mysql:5
# Add db.data with correct permissions
RUN mkdir /server_data
WORKDIR /server_data
ADD --chown="root:root" ./db.data .
# Copy setup directory
COPY ./setup setup
COPY ./config /etc/mysql/conf.d
CMD ["./setup/setup.sh", "mysql", "-u", "root", "<", "./setup/schema.sql"]
My ./setup/setup.sh script looks like this;
#!/bin/bash
# wait-for-mysql.sh
set -e
shift
cmd="$#"
until mysql -uroot -c '\q'; do
>&2 echo "mysql is unavailable - sleeping"
sleep 1
done
>&2 echo "mysql is up - executing command"
exec $cmd
My docker-compose.yml looks like this;
version: "3"
services:
db:
build: ./db
volumes:
- data-db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=password
restart: always
container_name: db
volumes:
data-db:
When I run 'docker-compose up --build' I get the following output;
Building db
Step 1/7 : FROM mysql:5
---> 0d16d0a97dd1
Step 2/7 : RUN mkdir /server_data
---> Using cache
---> 087b5ded3a53
Step 3/7 : WORKDIR /server_data
---> Using cache
---> 5a32ea1b0a49
Step 4/7 : ADD --chown="root:root" ./db.data .
---> Using cache
---> 5d453c52a9f1
Step 5/7 : COPY ./setup setup
---> 9c5359818748
Step 6/7 : COPY ./config /etc/mysql/conf.d
---> b663a380813f
Step 7/7 : CMD ["./setup/setup.sh", "mysql", "-u", "root", "<", "./setup/schema.sql"]
---> Running in 4535b2620141
Removing intermediate container 4535b2620141
---> 2d2fb7e308ad
Successfully built 2d2fb7e308ad
Successfully tagged wasdbsandbox_db:latest
Recreating db ... done
Attaching to db
db | ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
db | mysql is unavailable - sleeping
db | ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
db | mysql is unavailable - sleeping
This goes on interminably until I press Ctrl + c.
If I comment out the CMD line in my Dockerfile the output from running 'docker-compose up --build' is the output of the ENTRYPOINT command that is defined in the official mysql Dockerfile.
Why is mysql never starting when I use my own CMD command?
This is supported already by the official mysql image. No need to make your own custom solution.
Look at the Docker Hub README under "Initializing a fresh instance".
You can see in the official image under the 5.7 Dockerfile (for example) that it copies in a ENTRYPOINT script. That script doesn't run at build time, but at run-time right before the CMD starts the daemon.
In that existing ENTRYPOINT script you'll see that it will process any files you put in /docker-entrypoint-initdb.d/
So in short, when you start a new container from that existing official image it will:
start the mysqld in local-only mode
creates default user, db, pw, etc.
runs any scripts you put in /docker-entrypoint-initdb.d/
stops the mysqld and hands off to the Dockerfile CMD
CMD will run the mysqld to listen on the network

Adding Flyway to a MySQL Docker Container

I'm building an derivative to this Docker container for mysql (using it as a starting point): https://github.com/docker-library/mysql
I've amended the Dockerfile to add in Flyway. Everything is set up to edit the config file to connect to the local DB instance, etc. The intent is to call this command from inside the https://github.com/docker-library/mysql/blob/master/5.7/docker-entrypoint.sh file (which runs as the ENTRYPOINT) around line 186:
flyway migrate
I get a connection refused when this is run from inside the shell script:
Flyway 4.1.2 by Boxfuse
ERROR:
Unable to obtain Jdbc connection from DataSource
(jdbc:mysql://localhost:3306/db-name) for user 'root': Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State : 08
Error Code : -1
Message : Could not connect to address=(host=localhost)(port=3306)(type=master) : Connection refused
But, if I remove the command from the shell script, rebuild and log in to the container, and run the same command manually, it works with no problems.
I suspect that there may be some differences with how the script connects to the DB to do its thing (it has a built in SQL "runner"), but I can't seem to hunt it down. The container restarts the server during the process, which is what may be the difference here.
Since this container is intended for development, one alternative (a work-around, really) is to use the built in SQL "runner" for this container, using the filename format that Flyway expects, then use Flyway to manage the production DB's versions.
Thanks in advance for any help.
I mean it's the good way to start from the ready image (for start).
You may start from image docker "mysql"
FROM mysql
If you start the finished image - when creating new version your docker then
will only update the difference.
Next, step you may install java and net-tools
RUN apt-get -y install apt-utils openjdk-8-jdk net-tools
Config mysql
ENV MYSQL_DATABASE=mydb
ENV MYSQL_ROOT_PASSWORD=root
Add flyway
ADD flyway /opt/flyway
Add migrations
ADD sql /opt/flyway/sql
Add config flyway
ADD config /opt/flyway/conf
Add script to start
ADD start /root/start.sh
Check start mysql
RUN netstat -ntlp
Check java version
RUN java -version
Example file: /opt/flyway/conf/flyway.conf
flyway.driver=com.mysql.jdbc.Driver
flyway.url=jdbc:mysql://localhost:3306/mydb
flyway.user=root
flyway.password=root
Example file: start.sh
#!/bin/bash
cd /opt/flyway
flyway migrate
# may change to start.sh to start product migration or development.
Flyway documentation
I mean that you in next step may use flyway as service:
For example:
docker run -it -p 3307:3306 my_docker_flyway /root/start << migration_prod.sh
docker run -it -p 3308:3306 my_docker_flayway /root/start << migration_dev.sh
etc ...
services:
# Standard Mysql Box, we have to add tricky things else logging by workbench is hard
supermonk-mysql:
image: mysql
command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
environment:
- MYSQL_ROOT_PASSWORD=P#ssw0rd
- MYSQL_ROOT_HOST=%
- MYSQL_DATABASE=test
ports:
- "3306:3306"
healthcheck:
test: ["CMD-SHELL", "nc -z 127.0.0.1 3306 || exit 1"]
interval: 1m30s
timeout: 60s
retries: 6
# Flyway is best for mysql schema migration history.
supermonk-flyway:
container_name: supermonk-flyway
image: boxfuse/flyway
command: -url=jdbc:mysql://supermonk-mysql:3306/test?verifyServerCertificate=false&useSSL=true -schemas=test -user=root -password=P#ssw0rd migrate
volumes:
- "./sql:/flyway/sql"
depends_on:
- supermonk-mysql
mkdir ./sql
vi ./sql/V1.1__Init.sql # and paste below
CREATE TABLE IF NOT EXISTS test.USER (
id VARCHAR(64),
fname VARCHAR(256),
lname VARCHAR(256),
CONSTRAINT pk PRIMARY KEY (id));
save and close
docker-compose up -d
wait for 2 minutes
docker-compose run supermonk-flyway
Ref :
https://github.com/supermonk/webapp/tree/branch-1/docker/docker-database
Thanks to docker community and mysql community
docker-compose logs -f

Docker, how to run .sql file in an image?

It's my first time working with Docker an I am not sure if I am doing things well.
I have a rails applications that depends on a Mysql database, so I've configured the docker-compose.yml file like this:
db:
image: library/mysql:5.6
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
expose:
- "3306"
ports:
- "3306:3306"
rails-app:
build: .
dockerfile: Dockerfile
environment:
RAILS_ENV: development
links:
- db
volumes:
- ".:/home/app"
volumes_from:
- bundle
... omitted lines ...
Then, if I run the following:
$ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql
I get this error:
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.99.100' (111)
This sounds normal, because I suspect that I have to build before some container that links to db.
I know this because if I run this in this order:
$ docker-compose build rails-app
$ docker-compose run -e RAILS_ENV=development rails-app bundle
$ docker-compose run -e RAILS_ENV=development rails-app bundle exec rake db:create
$ docker-compose run db mysql --host=$DOCKER_LOCALHOST --port=3306 --protocol=tcp -u root < shared/create_common_tables.sql
It works fine.
But, how can I do to execute this sql before creating any container?
You can load the sql file during the build phase of the image. To do this you create a Dockerfile for the db service that will look something like this:
FROM mysql:5.6
COPY setup.sh /mysql/setup.sh
COPY setup.sql /mysql/setup.sql
RUN /mysql/setup.sh
where setup.sh looks something like this:
#!/bin/bash
set -e
service mysql start
mysql < /mysql/setup.sql
service mysql stop
And in your docker-compose.yml you'd change image to build: ./db or the path where you put your files.
Now this works if you have all your sql in a raw .sql file, but this wont be the case if you're using rails or a similar framework where the sql is actually stored in code. This leaves you with two options.
Instead of using FROM mysql:5.6 you can use FROM your_app_image_that_has_the_code_in_it and apt-get install mysql .... This leaves you with a larger image that contains both mysql and your app, allowing you to run the ruby commands above. You'd replace the mysql < /mysql/setup/sql with the rails-app bundle exec rake db:create lines. You'd also have to provide an app config that hits a database on localhost:3306 instead of db:3306
My preferred option is to create a script which exports the sql into a .sql file, which you can then use to build your database container. This is a bit more work, but is a lot nicer. It means that instead of running rails-app bundle exec rake db:create you'd just run the script to load a db.
Such a script would look something like this:
#!/bin/bash
set -e
docker-compose build rails-app
docker run -d --name mysql_empty mysql:5.6
docker run --link mysql_empty:db -v $PWD:/output project_rails-app export.sh
where export.sh looks something like this:
#!/bin/bash
set -e
RAILS_ENV=development
rails-app bundle exec rake db:create
mysqldump > /output/setup.sql
You could also replace the docker run script with a second compose file if you wanted to.