Docker container is shut down immediately unless I change the `mount` `target` - mysql

I'm trying to start a Docker container with the mysql image with a mount pointing to a single database directory (because I don't want all those other databases and log files in my project).
I tried these commands:
db=test
install -d db-data
docker run \
-d \
--rm \
--mount src=$(pwd)/db-data,target=/var/lib/mysql/$db,type=bind \
--name $db-db \
-p 33060:3306 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=$db \
mysql
When I do this, the container starts and terminates immediately. But if I use a target of target=/var/lib/mysql, only removing /$db, it works, but then this is what I'm trying to avoid.

You must not have a mount below /var/lib/mysql in the container. You will have to create a mount for /var/lib/mysql.
This is the error you are facing:
0 [ERROR] [MY-010457] [Server] --initialize specified but the data directory has files in it. Aborting.
0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
0 [ERROR] [MY-010119] [Server] Aborting
0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.26) MySQL Community Server - GPL.
If /var/lib/mysql is not fully populated at startup, the entrypoint will initialize the /var/lib/mysql directory. This will fail, if there are already files in it, which is the case when you mount a file/directory into the data directory.

To be sure that all initialization down on the container, you can add volume after create container.
create container without mount:
docker run \
-d \
--rm \
--name $db-db \
-p 33060:3306 \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=$db \
mysql
commit your existing container (that is create a new image from container’s changes):
docker commit 5a8f89adeead newcontainername
run the new container with volume:
docker run -ti --mount src=$(pwd)/db-data,target=/var/lib/mysql/$db,type=bind newcontainername /bin/bash
start the new container (you can find it with docker ps -a) ans stop the old one (already running):

Related

MySql docker container not starting when using a network share for data directory

I'm running docker in Ubuntu and trying to create and run a MySql container. I want to use a mounted network share for the data directory. I am trying the following docker run command, but I'm having issues with permissions. How do I fix this?
root#jarvis:/mnt/wayne/mysql-data$ sudo docker run -it -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin -v /mnt/wayne/mysql:/var/lib/mysql/ --name mysqlserver mysql/mysql-server
[Entrypoint] MySQL Docker Image 8.0.20-1.1.16
[Entrypoint] Initializing database
2020-06-08T21:43:25.253898Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.20) initializing of server in progress as process 22
2020-06-08T21:43:25.281460Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2020-06-08T21:43:27.815075Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted)
2020-06-08T21:43:29.851875Z 0 [ERROR] [MY-010295] [Server] Could not set file permission for ca.pem
2020-06-08T21:43:29.852970Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
2020-06-08T21:43:29.854806Z 0 [ERROR] [MY-010119] [Server] Aborting
2020-06-08T21:43:31.947298Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.20) MySQL Community Server - GPL.
You use CIFs for network mount means the remote server is windows right? My answer is based on this assumption.
The latest mysql docker image has a user named mysql and its uid=27,gid=27
You verify this by mounting an empty folder as data_dir. You will see that the files created by mysql container has user and group is as 27.
Hence the mysql container expects files with uid/gid(owner userid and owner group id) as 27 in its data_dir. But the files that you mounted from the windows share has uid/gid which belongs to the user that executes mount command in ubuntu. This is the default behavior of mount command.
To solve this you need to pass "uid=27,gid=27" parameters to the Linux mount command.
For instance
sudo mount -t cifs -o
username=windows-username,uid=27,gid=27
//WIN_SHARE_IP/ /mnt/wayne
You can have look here for further details
I must say it is unlikely to run mysql over a network share. It won't perform well.
This is not exactly with MySQL but I hope it can give you an idea, I basically use this for testing against a MySQL database from my local environment, for this I use docker-compose and MariaDB, I configure the "data-dir" as a volume so that I can stop/start the docker container without the need to "seed" every time the database.
This is the content of the /your/path/docker-compose.yml file:
---
version: '3'
services:
mariadb:
image: mariadb:10.4.13
container_name: mariadb
restart: always
ports:
- 13306:3306
environment:
MYSQL_DATABASE: world
MYSQL_ROOT_PASSWORD: test
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
volumes:
- ${PWD}/mariadb/db/:/var/lib/mysql
In the same directory, I have the volume directory /your/path/mariadb/db
Then to bring up the container I use:
$ docker-compose up
From the docker-compose.yml has you can see I use port 13306 therefore for testing/connection I use:
$ mysql -h 127.0.0.1 -P13306 -uroot -p
All the data (databases) will be in /your/path/mariadb/db
If you run into the same "permissions" problem:
mysqld: Cannot change permissions of the file 'ca.pem' (OS errno 1 - Operation not permitted)
Try to change the permissions of your volume/mount point, for example:
chmod -R 777 /your/volume/mount_point
okay, I tried this and google also, what I found is
https://github.com/docker-library/mysql/issues/302#issuecomment-308745834
So basically if you are using mysql:5.7 then upgrade to mysql:5.7.16.
And if this doesn't help then I have one more solution.
Basically the problem is you are sharing dir to container -v /mnt/wayne/mysql:/var/lib/mysql/ but you ubuntu is not giving permission to access the /mnt/wayne/mysql dir. so give admin permission to this location or you can create a docker user chown and chmode.
Basically give permission to the host machine directory. so that docker container can access it.
and One more thing give permission to the docker container dir also, that is showing in your error
The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
Create a user in a docker container which have chown and chmod permissions to the dir /var/lib/mysql/.
if you are using dockerfile to create mysql container then use these following 2 lines in it
FROM mysql:5.7.16
WORKDIR /app
RUN chown -R admin:admin /app
RUN chmod 755 /app
USER admin
CMD ["Your command"]
To operate normally, MariaDB or MySQL needs to set some permissions on their own files. Some external file systems (such as FTP and many others) do not support these features. You need to use a file system which supports these features.
there is a permission issue to access the mounted volume. Please read the documentation about use volumes:
https://docs.docker.com/storage/volumes/#use-a-volume-driver
For NFSv3 Partition:
$ docker service create -d \
--name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10' \
nginx:latest
Or check the CA.pem file permissions (use chmod 777 /path/to/ca.pem)
For NFSv4 Partition:
docker service create -d \
--name nfs-service \
--mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,"volume-opt=o=10.0.0.10,rw,nfsvers=4,async"' \
nginx:latest
Check https://docs.docker.com/storage/volumes/#use-a-volume-driver

How to get PHPMyAdmin to see MySQL in two different docker instance

I am trying to start a MySQL docker instance, and want to interface to this server with PHPMyAdmin.
My server host name from where docker is running is <ServerName>
I am using the following command to start my MySQL docker container
docker run -P --name mysql-test -v storage-test:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=MyDataBase -e MYSQL_USER=me -e MYSQL_PASSWORD=mepass -d mysql:latest
And it seems to start and create the database correctly
after that i start PHPmyAdmin container
docker run --name myadmin -d -e MYSQL_ROOT_PASSWORD=root -e PMA_HOST=ServerName -e PMA_VERBOSE=MyDataBase -e PMA_USER=me -e PMA_PASSWORD=mepass -p 8080:80 phpmyadmin/phpmyadmin
I get this log from mySql container
MySQL init process done. Ready for start up.
2019-10-01T11:36:35.909758Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2019-10-01T11:36:35.909856Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.17) starting as process 1
2019-10-01T11:36:37.735204Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2019-10-01T11:36:37.761004Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2019-10-01T11:36:37.776949Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.17' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL.
2019-10-01T11:36:37.887863Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060
However when I access the PHPMyAdmin weblogin I get the following Error:
MySQL said: Documentation
Cannot connect: invalid settings.
mysqli_real_connect(): (HY000/2002): Connection refused
phpMyAdmin tried to connect to the MySQL server, and the server
rejected the connection. You should check the host, username
and password in your configuration and make sure that they
correspond to the information given by the administrator of the
MySQL server.
If I remove the -e PMA_USER=me -e PMA_PASSWORD=mepass from the run command I get to the login where I can enter my credentials however when trying to do that I just get the
mysqli_real_connect(): (HY000/2002): Connection refused
Can anyone see what I'm doing wrong here ?
Here is a link to the two docker containers I am using
https://hub.docker.com/_/mysql
https://hub.docker.com/r/phpmyadmin/phpmyadmin/
Regards
First of all, don't use -P when running your mysql container. -P (or --publish-all) will publish the ports of the MySQL container, which means MySQL will be accessible publicly. This is likely not what you want.
Containers can connect with each-other using the docker container-container network; if both containers are connected to the same network, they can connect with each-other over that network, without having to make the ports publicly accessible. Only use -p (or -P) to make ports accessible that should be public.
For example;
1. Create a custom network;
docker network create myprivatenetwork
2. Start the mysql container
Start the mysql container, and connect it to the myprivatenetwork. I removed the -P option, which means the container is not publicly accessible, but it is accessible from network(s) it's connected to. (I wrapped the commands to make it easier to read)
docker run \
--name mysql-test \
--network myprivatenetwork \
-v storage-test:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=MyDataBase \
-e MYSQL_USER=me \
-e MYSQL_PASSWORD=mepass \
-d \
mysql:5.7
Note: I used mysql:5.7, because mysql:latest (which currently is MySQL 8) requires some additional configuration; see PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client
In general, it's recommended to be specific about the version you want to run, and don't run :latest, as it may change to newer versions, which can cause your setup to fail.
3. Start the PhpMyAdmin container
Start the PhpMyAdmin container, and connect it to the same network; phpmyadmin can connect with the mysql container using its name (mysql-test) as hostname, and using the default
mysql port (3306). For the phpmyadmin container, I kept -p to allow accessing it publicly (although you may want to have it run with TLS/SSL)
docker run \
--name myadmin \
--network myprivatenetwork \
-d \
-e MYSQL_ROOT_PASSWORD=root \
-e PMA_HOST=mysql-test \
-e PMA_PORT=3306 \
-e PMA_VERBOSE=mysql-test \
-e PMA_USER=me \
-e PMA_PASSWORD=mepass \
-p 8080:80 \
phpmyadmin/phpmyadmin
4. Visit http://localhost:8080 in your browser
You should now be able to visit PhpMyAdmin in your browser, and see the MySQL database.
Note that PhpMyAdmin is not configured with a password or TLS/SSL, so if your machine is publicly accessible (internet, or your local network), this will allow others to access your database through phpmyadmin

MySQL fail to start in Docker when mount /etc to host

I use below command to start MySQL container:
docker run --name mysql-for-teamcity \
-e MYSQL_ROOT_PASSWORD=FAKE-ROOT-PWD \
-v ~/MySQL/var_lib_mysql:/var/lib/mysql \
-v ~/MySQL/etc:/etc \
-p 3306:3306 \
-p 33060:33060 \
-it mysql
But MySQL won't start and complains:
ERROR: mysqld failed while attempting to check config
command was: "mysqld --verbose --help"
mysqld: Error on realpath() on '/var/lib/mysql-files' (Error 2 - No such file or directory)
2018-12-05T07:33:50.856816Z 0 [ERROR] [MY-010095] [Server] Failed to access directory for --secure-file-priv. Please make sure that directory exists and is accessible by MySQL Server. Supplied value : /var/lib/mysql-files
2018-12-05T07:33:50.859460Z 0 [ERROR] [MY-010119] [Server] Aborting
If I remove -v ~/MySQL/etc:/etc \ then MySQL would start correctlly.
Why can't I mount /etc to my host in Docker?
This is my silly mistake; it should be an RTFM question.
According to Docker manual, Bind mounts are used to bind directory into a container, not out.
So when I specified -v ~/MySQL/etc:/etc, the contents in my "~/MySQL/etc" would obscure the original contents in "/etc" of the MySQL image.
That's why mysqld failed while attempting to check config. Because the config does not exist in my "~/MySQL/etc/".
I leave the answer here in case someone else does not read the manual:(

Docker mysql stop with exit(1)

I was trying to bring up my MySql in the docker container. But, it stopped with code exited(1). Here is how I run it:
docker run --name demo-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql:latest --mount type=bind,source=$(pwd),target=/var/lib/mysql
Here is the log of the container
Initializing database
2018-10-12T17:50:42.694183Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2018-10-12T17:50:42.694277Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.12) initializing of server in progress as process 31
mbind: Operation not permitted
mbind: Operation not permitted
mbind: Operation not permitted
mbind: Operation not permitted
2018-10-12T17:51:10.497527Z 0 [ERROR] [MY-011071] [Server] unknown option '--mount'
2018-10-12T17:51:10.497543Z 0 [Warning] [MY-010952] [Server] The privilege system failed to initialize correctly. If you have upgraded your server, make sure you're executing mysql_upgrade to correct the issue.
2018-10-12T17:51:10.497551Z 0 [ERROR] [MY-010119] [Server] Aborting
2018-10-12T17:51:14.130241Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.12) MySQL Community Server - GPL.
Please help me...
Better answer may follow, I used to use Docker as well for MySQL but it's been a while.
Start as detached container:
docker run -v $PWD:/var/lib/mysql --name demo-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql:latest
Then attach to it like so:
docker run -i -t demo-db /bin/bash
Note about pwd use:
There's no need to use the pwd command, just get the shell variable $PWD. When you do foo=$(pwd) is kind of overkill, b/c you're actually running the pwd command in a sub shell to return $PWD.
The syntax of the docker run command is basically
docker run <docker run options> IMAGE <command and arguments>
So when you run:
docker run \
--name demo-db -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password -d \
mysql:latest \
--mount type=bind,source=$(pwd),target=/var/lib/mysql
The --mount option is after the image name, so it's passed as an argument to the container. Move this option before mysql:latest and you'll be set.

docker cp permissions are wrong when you mount the directory back into container

I am trying to grab the /var/lib/mysql directory out of a running mysql container in order to keep it for persistence. Yet when I then mount the directory as a volume mysql complains that it does not have permission:
mysqld: Table 'mysql.plugin' doesn't exist
2016-02-29 13:34:19 1 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
and
2016-02-29 13:34:20 1 [Note] Server socket created on IP: '::'.
2016-02-29 13:34:20 1 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist
docker cp `cat mysqlinitCID`:/var/lib/mysql datadir/
at this point I'm even using the tar form of docker cp in combination with -p flag to preserve permissions, yet it still comes in with privilege issues.
docker cp `cat mysqlinitCID`:/var/lib/mysql - |sudo tar -C datadir/mysql/ -pxf -
It seems like the only way to do this properly is go around docker cp and mount say /tmp and tar up /var/lib/mysql yourself and copying the tarball to the mounted point and get it out that way.
Is there a proper way to utilize docker cp that I am missing out on?
I initialize the mysql container like this to grab from:
docker run \
--name=$(NAME)-mysql-init \
-d \
--env='DB_NAME=$(DB_NAME)' \
--cidfile="mysqlinitCID" \
--env='MYSQL_USER=$(DB_USER)' --env="MYSQL_ROOT_PASSWORD=$(DB_PASS)" \
--env="MYSQL_PASSWORD=$(DB_PASS)" \
--env="MYSQL_DATABASE=$(DB_NAME)" \
mysql:5.6
and here is how I start the container with volume attached:
docker run \
--name=$(NAME)-mysql \
-d \
--env='DB_NAME=$(DB_NAME)' \
--cidfile="mysqlCID" \
--env='MYSQL_USER=$(DB_USER)' --env="MYSQL_ROOT_PASSWORD=$(DB_PASS)" \
--env="MYSQL_PASSWORD=$(DB_PASS)" \
--volume=$(MYSQL_DATADIR):/var/lib/mysql \
mysql:5.6
Ok, my issue here was a simple typo where I put a mysql directory inside another mysql directory, so the correct answer is to use the tar form with one slight modification above:
docker cp `cat mysqlinitCID`:/var/lib/mysql - |sudo tar -C datadir/ -pxf -