Im using this tutum-docker-mysql dockerfile, to get up and running with a docker image with mysql installed in it,the docker file creates a user with the name root and no password, what i need is to add something like this to the dockerfile:
RUN mysql -uroot -p"" && mysql create database test;
So when I build an image from the docker file, the database should already be there.
I was able to accomplish the goal of adding a database to the tutum-docker-mysql image by doing the following.
git clone https://github.com/tutumcloud/tutum-docker-mysql.git
cd tutum-docker-mysql
vi create_mysql_admin_user.sh
Inside of that .sh file I added a line, right below the two "mysql -uroot" lines that are already there. I simply added:
mysql -uroot -e "create database test;"
After that change to that .sh file, I simply built the docker image.
docker build -t tutum/mysql .
After the docker image was built, I could run it with something like:
docker run -d -p 3307:3306 tutum/mysql
Once the container is running, you need to know the password to use and the ip address of the container. To get the password you simply do
docker logs 2976a81f1a9b19787d9bde893c831b7e6586d7c8391ccd222ad29b02c282d896
But of course use the container id, that was returned from the "docker run" command above. Now that you have the password, you need the ip address. I get that by doing.
docker inspect 2976a81f1a9b19787d9bde893c831b7e6586d7c8391ccd222ad29b02c282d896
And looking at the "Gateway" address. With the password and the ip address I was then able to do this mysql command from OUTSIDE of the container.
mysql -uadmin -pJcM5FCphMOp4 -h172.17.42.1 -P3307
Where the ip address and the password are the values I got from the previous two docker commands. After that command has run, I can then issue a "show databases" command with the following results.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
mysql>
I fought for a while trying it by modifying the Dockerfile. I think it might be possible, but after a while, I found the above solution a lot quicker and simpler.
You can pass ON_CREATE_DB env parameter on container startup.
Example from tutum README.md
docker run -d -p 3306:3306 -e ON_CREATE_DB="newdatabase" tutum/mysql
Related
I am trying to setup MariaDB in a Docker container for CI/CD testing.
However, the way I do it the DB does not exist when I log into the container.
Here's parts of my Dockerfile
FROM debian:stable-slim
RUN apt -y install mariadb-server mariadb-client
EXPOSE 3306
ADD ./DBShema.sql /db/DBShema.sql
RUN mysqld_safe \
mysqladmin --silent --wait=30 ping \
mysql < /db/DBShema.sql
Does not show my DB / tables.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.001 sec)
How should that go properly to make the piped DB info persistent?
I think you are overcomplicating things. I do not see the point of starting from a plain Debian installation that requires you to install the RDBMS manually.
There are MariaDB images already made that you can use as a starting point for your CI images. Take the following Dockerfile as an example:
FROM mariadb:10.6.4-focal
COPY schema.sql /docker-entrypoint-initdb.d
This effectively copies over an sql script into the directory that is used to initialize the database on the first container start. This is mentioned in this portion of the documentation.
Once this is done the spun off container will contain all the changes included in the related sql file. I hope this is what you want.
All my experience with Docker so far has led me to believe that containers are stateless.
If so, why is my container storing the password that I change it to after the first run if I spun it up without specifying a volume or bind mount? I am especially puzzled since none of the other edits I make to the dbms persist (like creating tables).
Additional Details:
Versions:
1. Docker - 18.09.0 build 4d60db4
2. Image - mysql/mysql-server:latest
Commands:
1. $ docker run --name=sql -d mysql/mysql-server:latest
2. $ docker logs sql 2>&1 | grep GENERATED to grab the generated password for first login
3. $ docker exec -it sql mysql -uroot -p
4. mysql> Enter Password: <generated password>
5. mysql> ALTER USER 'root'#'localhost' IDENTIFIED BY 'stkoverflw';
6. mysql> exit
7. $ docker stop sql
8. $ docker start sql
9. $ docker exec -it sql mysql -uroot -p
10. mysql> Enter Password: <stkoverflw>
How does the password configuration persist across restarts of the container?
Containers are not stateless. Containers are easy to create and destroy, so they can be used to run a service which is stateless, but each container is itself stateful.
When the container is running, there is a volume containing its root filesystem. You don't have to tell Docker to create it. Docker has to create it because otherwise where do the container's files go?
When you say docker stop, the container stops running but it is not destroyed. When you say docker start, the same container resumes with the same root volume. That's where the changed password persists. The process running in the container was stopped and a new process was started (so state held in memory would be lost), but the filesystem is still there.
To get rid of a container (including the changed password), say docker rm. Then you can say docker run to start from scratch.
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
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
Docker for Windows
I have a machine set up with 2 containers. They are both running the standard mysql image. One is set up to be the server, and I am linking to it from the other and attempting to run mysql commands.
Ideally, I would like to be able to do this all through the command prompt so I can call it through Python.
I was able to run a few commands error-free and attempted to place my name into the Username table of myDB.
When I run the command:
docker exec sqlserverClient mysql -uroot -ppassword -e"use myDB" -e"select * from Usernames"
I get back the output:
Warning: Using a password on the command line interface can be insecure
And nothing else.
Where is my table? Even if the insert went wrong, shouldn't I at least see a blank table?
I expected to see something like this:
+------------+-------------+
| firstname | lastname |
+------------+-------------+
| First | Last |
+------------+-------------+
"docker logs sqlserverClient" doesn't have it. So where did it go?
Try with docker exec -it, to have tty and the output
But remember docker exec is for debug only.
The best practice is to have a docker container with:
an entrypoint set to sqlserverClient
a cmd that you pass in parameter when running a transient container.
That is:
docker run --rm -it sqlimage mysql -uroot -ppassword -e"use myDB" -e"select * from Usernames"
Once the command is executed, the container stopped and is rmeoved.
That means you can have an alias like:
alias drs='docker run --rm -it sqlimage'
And call:
drs mysql -uroot -ppassword -e"use myDB" -e"select * from Usernames"