Unable to see the tables inside a docker container - mysql

Following is the code inside container for the sql:
mysql:
image: mariadb
command: --max_allowed_packet=32505856
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_USER=abc
- MYSQL_PASSWORD=xyz.123
- MYSQL_DATABASE=abc
- MYSQL_ALLOW_EMPTY_PASSWORD=true
restart: always
ports:
- 3306:3306
volumes:
# Using volume mount to mimic prod setup
- /tmp/mysql:/vol_mount/
I have been trying to access the database to view tables but have been unable to do so thus far.
I have tried running commands like:
docker exec -it container_name mysql -uabc -p
and then have tried bot 'root' and 'xyz.123' when prompted to enter password. But then I get an error like
"ERROR 1045 (28000): Access denied for user 'abc'#'2001:db8:1::a7'
(using password: YES)"
I need to know the commands that will allow for me to access the DB and view tables. Thanks.

This will open your mysql console with user root:
docker exec -ti mariadb-test sh -c 'mysql -uroot -p${MYSQL_ROOT_PASSWORD}'
Please note that I named the container mariadb-test in the compose file you can use a different name if you like.
Similarly you can connect with used abc:
docker exec -ti mariadb-test sh -c 'mysql -uabc -p${MYSQL_PASSWORD}'
UPDATE:
Run the following to check the environment variables inside your container. They should match the values provided in the docker-compose.yml.
docker exec -ti mariadb-test sh -c 'env | grep MYSQL'
Since in my solution you don't even have to type the password, it should work anyway. Please try to start from a clean state: bring down all the containers, remove volumes and restart the services with this docker-compose file.

Related

CircleCI job creates docker MySQL 8 but nothing can connect

(See UPDATE at end of post for potentially helpful debug info.)
I have a CircleCI job that deploys MySQL 8 via - setup_remote_docker+docker-compose and then attempts to start a Java app to communicate with MySQL 8. Unfortunately, even though docker ps shows the container is up and running, any attempt to communicate with MySQL--either through the Java app or docker exec--fails, saying the container is not running (and Java throws a "Communications Link Failure" exception). It's a bit confusing because the container appears to be up, and the exact same commands work on my local machine.
Here's my CircleCI config.yml:
Build and Test:
<<: *configure_machine
steps:
- *load_repo
- ... other unrelated stuff ...
- *load_gradle_wrapper
- run:
name: Install Docker Compose
environment:
COMPOSE_VERSION: '1.29.2'
command: |
curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o ~/docker-compose
chmod +x ~/docker-compose
sudo mv ~/docker-compose /usr/local/bin/docker-compose
- setup_remote_docker
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Query MySQL #test that fails
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
And here's my docker-compose.yml that is run in one of the steps:
version: "3.1"
services:
# MySQL Dev Image
mysql-migrate:
container_name: mysql8_test_mysql
image: mysql:8.0
command:
mysqld --default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
--log-bin-trust-function-creators=true
environment:
MYSQL_DATABASE: test_db
MYSQL_ROOT_PASSWORD: rootpass
ports:
- "3306:3306"
volumes:
- "./docker/mysql/data:/var/lib/mysql"
- "./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf"
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
It's a fairly simple setup and the output from CircleCI is positive until it reaches the docker exec, which I added to test the connection. Here is what the output from CircleCI says per step:
Start MySQL Docker:
#!/bin/bash -eo pipefail
docker-compose up -d
Creating network "project_default" with the default driver
Pulling mysql-migrate (mysql:8.0)...
8.0: Pulling from library/mysql
5158dd02: Pulling fs layer
f6778b18: Pulling fs layer
a6c74a04: Pulling fs layer
4028a805: Pulling fs layer
7163f0f6: Pulling fs layer
cb7f57e0: Pulling fs layer
7a431703: Pulling fs layer
5fe86aaf: Pulling fs layer
add93486: Pulling fs layer
960383f3: Pulling fs layer
80965951: Pulling fs layer
Digest: sha256:b17a66b49277a68066559416cf44a185cfee538d0e16b5624781019bc716c122 121B/121BkBBB
Status: Downloaded newer image for mysql:8.0
Creating mysql8_******_mysql ...
Creating mysql8_******_mysql ... done
So we know MySQL 8 was pulled fine (and therefore the previous step worked). Next step is to ask Docker what's running.
Check Docker MySQL:
#!/bin/bash -eo pipefail
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb6b7941ad65 mysql:8.0 "docker-entrypoint.s…" 1 second ago Up Less than a second 0.0.0.0:3306->3306/tcp, 33060/tcp mysql8_test_mysql
CircleCI received exit code 0
Looks good so far. But now let's actually try to run a command against it via docker exec.
Query MySQL:
#!/bin/bash -eo pipefail
docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306' (111)
Exited with code exit status 1
CircleCI received exit code 1
So now we can't connect to MySQL even though docker ps showed it up and running. I even tried adding an absurd step to wait in case MySQL needed more time:
- run:
name: Start MySQL docker
command: docker-compose up -d
- run:
name: Check Docker MySQL
command: docker ps
- run:
name: Wait Until Ready
command: sleep 120
- run:
name: Query MySQL
command: docker exec -it mysql8_test_mysql mysql mysql -h 127.0.0.1 --port 3306 -u root -prootpass -e "show databases;"
Of course adding a 2 minute wait for MySQL to spin up didn't help. Any ideas as to why this is so difficult in CircleCI?
Thanks in advance.
UPDATE 1: I can successfully start MySQL if I SSH into the job's server and run the same command myself:
docker-compose up
Then in another terminal run this:
docker exec -it mysql8_test_mysql mysql mysql -h localhost --port 3306 -u root -prootpass -e "show databases;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| test_db |
| mysql |
| performance_schema |
| sys |
+--------------------+
So it is possible to start MySQL. It's just not working right when through job steps.
UPDATE 2: I moved the two minute wait between docker-compose up -d and docker ps and now it shows nothing is running. So the container must be starting then crashing and that's the reason for why it's not available moments later.
The cause of the problem was the volumes entry in my docker-compose.yml with this line:
- "./mysql_schema_v1.sql:/docker-entrypoint-initdb.d/mysql_schema_v1.sql"
The container appeared to be up when I checked immediately after docker-compose up -d but in actuality it would crash seconds later because CircleCI appears to have an issue with Docker volume, potentially related to this: https://discuss.circleci.com/t/docker-compose-doesnt-mount-volumes-with-host-files-with-circle-ci/19099.
To make it work I removed that volume entry and added run commands to copy and import the schema like so:
- run:
name: Start MySQL docker
command: docker-compose up -d
# Manually copy schema file instead of using docker-compose volumes (has issues with CircleCI)
- run:
name: Copy Schema
command: docker cp mysql_schema_v1.sql mysql8_mobile_mysql:docker-entrypoint-initdb.d/mysql_schema_v1.sql
- run:
name: Import Schema
command: docker exec mysql8_mobile_mysql /bin/sh -c 'mysql -u root -prootpass < docker-entrypoint-initdb.d/mysql_schema_v1.sql'
With this new setup I've been able to create the tables and connect to MySQL. However, there appears to be an issue running tests against MySQL causing hangups but that might be unrelated. I will follow up with more information, but at least I hope this can help someone else.

Docker - Securely set MySQL/MariaDB root password at build stage

I'm trying to create a docker build/compose where I can securely set the root password for my MariaDB server at build/runtime rather than having to do it manually in the shell through docker exec. I want to be a completely hands-off build.
I have tried multiple ways of getting this to work, including BuildKit secrets, but am trying to avoid using Swarm if possible. I read that it was possible to do it using docker compose so I have written a YAML for it, however it does not seem to be working.
The compose seems to work fine, however when I try to update my database from a dump (this exec is just for testing so fine that it isn't hands-off) using this command:
docker exec -i my_db_containter mysql -uroot -pmypassword < dbserver/sqlconfig/db_dump.sql
I get this error:
ERROR 1045 (28000): Access denied for user 'root'#'localhost' (using password: YES)
Can anyone spot what I might be doing wrong here, is able to perhaps suggest an alternative solution to setting the server root password in this manner?
--
EDIT: After doing some more reading, it seems like even this method isn't that secure as it just seems to mount a read-only file in the container? Does anyone have any suggestions as to how I can automatically and securely set the MYSQL_ROOT_PASSWORD, ideally without swarm? If swarm really is the only option then I guess I can look into it.
--
Here is what I have so far:
docker-compose.yaml:
version: '3.9'
services:
db:
build:
context: "./dbserver"
container_name: 'my_db_container'
environment:
MYSQL_DATABASE: 'my_db'
MYSQL_ROOT_PASSWORD: /run/secrets/dbrootpass
networks:
my_net:
ipv4_address: 203.0.113.88
secrets:
- dbrootpass
networks:
my_net:
ipam:
driver: default
config:
- subnet: "203.0.113.0/24"
secrets:
dbrootpass:
file: ./rootpass
rootpass:
mypassword
Create secrets:
$ read -p "Enter variable for MARIADB_ROOT_PASSWORD : " token && echo -n "$token" | podman secret create "MARIADB_PASSWORD" -
Enter variable for MARIADB_ROOT_PASSWORD : whynot
7f3b681f9a05729ad5b6af9d5
$ podman run --secret=MARIADB_ROOT_PASSWORD,type=env --secret=MARIADB_PASSWORD,type=env --env MARIADB_USER=bob mariadb:10.5
Inside container:
$ podman exec -ti funny_cohen bash
root#2583f8620571:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
mysql 1 0 0 03:31 ? 00:00:00 mysqld
root 143 0 0 03:32 pts/0 00:00:00 bash
root 146 143 0 03:32 pts/0 00:00:00 ps -ef
root#2583f8620571:/# printenv
GPG_KEYS=177F4010FE56CA3336300305F1656F24C74CD1D8
PWD=/
MARIADB_USER=bob
container=podman
HOME=/root
MARIADB_VERSION=1:10.5.10+maria~focal
GOSU_VERSION=1.12
TERM=xterm
MARIADB_MAJOR=10.5
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/printenv
It does show up in podman inspect funny_cohen however.

Docker: Error while creating a container with volume

I'm trying to create a simple mysql container, but I'm getting an error.
I created a Dockerfile:
FROM mysql
ENV MYSQL_ROOT_PASSWORD <password>
I built the image:
docker build -t mysql-image -f api/db/Dockerfile .
But when I tried to create a container with a host volume, an error appears:
docker run -d -v $(pwd)/api/db/data:/var/lib/mysql --rm --name mysql-container mysql-image
docker: Error response from daemon: pull access denied for de, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
If I run the same command, but without the volume parameters, then the container is created without any errors:
docker run -d --rm --name mysql-container mysql-image
I appreciate any help
Do you have whitespace in your current path? If so, it may be confusing the $(pwd) as two or more separate parameters. Try wrapping the whole parameter to -v in double quotes.
docker run -d -v "$(pwd)/api/db/data:/var/lib/mysql" --rm --name mysql-container mysql-image

Best way to initialize DB script while building docker image

I am building a docker machine using the image "mysql". I have some setup script to run for the first time the machine is built. This setup script will create some database and dabase users with specified permmissions.
Following are the minimized version of my files..
pcdb1.entrypoint.sh
#!/bin/sh
mysql -uroot -p'pass123' -e 'show databases MYENTRYDB;'
Dockerfile
FROM mysql:5.7
COPY ./pcdb1.entrypoint.sh /
ENTRYPOINT ["/pcdb1.entrypoint.sh"];
I am getting the following error in the log
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
pcdb1 exited with code 1
What I understood is, my script is trying to run before mysql is started. But I am not sure how to do it properly. Can I get a suggestion?
EDIT: 20181007
I have found the way you mentioned in question--initialize DB while building docker image. But with a little difference, the way I found seems like initializing DB while running a container from image, although the initializing script was specified while building the image.
According to the official information about mysql:5.7, there is paragraph named "Initializing a fresh instance". We could just add a initializing script into the directory /docker-entrypoint-initdb.d, the default ENTRYPOINT and CMD of image mysql:5.7 would execute it after database start-up.
For example:
FROM mysql:5.7
COPY init-database.sql /docker-entrypoint-initdb.d/
content of init-database.sql:
create database light;
create user 'light'#'%' identified by 'abc123';
grant all privileges on light.* to 'light'#'%' identified by 'abc123';
grant all privileges on light.* to 'light'#'localhost' identified by 'abc123';
Build new image:
docker build -t light/mysql:5.7 .
Run a container:
docker run -tid --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD='abc123' light/mysql:5.7
Examine initialization:
docker run -ti mysql /bin/bash
root#25e73d40c4ff:/# mysql -uroot -p
Enter password: (abc123)
Welcome to the MySQL monitor.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
All work well.
Former answer below.
How to start mysql damon in container?
First of all, you are right on "trying to run before mysql is started" part. But still, there is a missing on "how MySQL starts exactly". If you execute docker history mysql:5.7 --no-trunc, you could see three important records among output like below:
/bin/sh -c #(nop) CMD ["mysqld"]
/bin/sh -c #(nop) ENTRYPOINT ["docker-entrypoint.sh"]
/bin/sh -c ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh
So far we should know when we start a mysql container with command below, the exact initial command in container is docker-entrypoint.sh mysqld.
docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' mysql:5.7
How to initiate mysql in container?
Secondly, let's now have a check on docker-entrypoint.sh script.
There is a specific line like below, just at roughly middle position of this script, which means to start mysql daemon.
mysql=( mysql --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" )
After starting mysql, we could see lots of initiating statements in docker-entrypoint.sh script. Such as creating root user with password or not, granting privileges to root, creating database declared by users with MYSQL_DATABASE env and so on.
Now here are solutions offered for you.
Self-defining the docker-entrypoint.sh script.
In this way, you could whatever you want which is legal in mysql.
Get the whole entrypoint.sh script on your host.
Add your self-definition of mysql in the script, make your
self-defining content at the bottom of this script. I assume you
don't want to mess it with original content.
Build a new mysql image for your own with command and Dockerfile below.
command: docker build -t mysql:self .
Dockerfile:
FROM mysql:5.7
COPY /path/to/your-entrypoint.sh /
ENTRYPOINT ["/your-entrypoint.sh"]
CMD ["mysqld"]
If your don't want a new image, there is another way to change
ENTRYPOINT when you run a container. But still, you should make your own script available in container.
docker run -tid -v /path/to/your-entrypoint.sh:/entrypoint.sh -p 3306:3306 -e MYSQL_ROOT_PASSWORD='abc123' mysql:5.7
Using default ENVs provided by mysql:5.7
In this way, there is a limit, especially on "specified permmissions" you mentioned.
The ENVs you need are: MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD.
The command should like this:
docker run -tid -e MYSQL_ROOT_PASSWORD='abc123' -e MYSQL_DATABASE='apps' -e MYSQL_USER='light' -e MYSQL_PASSWORD='abc123' mysql:5.7
This means that the database apps and user light will be created automatically, and the user light will be granted superuser permissions for the database apps.
More reference here on hub.docker.com.

can't connect to mysql docker when mount a directory

I use official mysql 5.5 docker as database container.
first pull container:
docker pull mysql:5.5
then I run:
docker run --name mysqldb -e MYSQL_ROOT_PASSWORD=testword mysql:5.5
it run successfully, and the container mysqldb with ip is 172.17.0.20.And I can access this mysqldb by this:
mysql -h 172.17.0.20 -u root -p # this command from 172.17.0.23
input password, then I get this:
mysql>
this is a test for official mysql. I can access mysqldb from remote host/container.
Then I want to use host directory(store some databases) so I do this:
docker run --name mysqldb_with_data -v /var/lib/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=testword mysql:5.5
it run successfully. But when I want to access this mysqldb_with_data container with ip 172.17.0.21, I meet a error:
mysql -h 172.17.0.251 -u root -p # this command from 172.17.0.23
Enter password:
ERROR 1045 (28000): Access denied for user 'root'#'172.17.0.23' (using password: YES)
I just use host data to replace the data of mysql container, but I can't access mysqldb from remote host/container.I don't know why.
It works for me. Try your command without any space between -u and root and between -p and testword.
I too had the same issue. It was because I have copied /var/lib/mysql from container to /var/lib/mysql on host OS by:
docker cp <container name>:/var/lib/mysql/ /var/lib/
To copy the /var/lib/mysql in correct way you need to do the following:
Get the source of original mount
docker inspect <container name> | grep -A7 Mounts | grep Source
"Source":"/var/lib/docker/volumes/5a5fcb8c277c6a28f6eea2d156b5703cfc9feb86786ecf61caab95d803773647/_data",
Stop the container
docker stop <container name>
Copy the data from "Source" to /var/lib/mysql/
mkdir /var/lib/mysql/
cp -a /var/lib/docker/volumes/5a5fcb8c277c6a28f6eea2d156b5703cfc9feb86786ecf61caab95d803773647/_data/* /var/lib/mysql/
After doing this, you'll be able to work with dockerized mysql as expected.
So, basically the problem was with mysql data files, not with dockerezation. To get them in consistent state they should be copied while DB is stopped.