Docker - can not start mysql permission error - mysql

I have problem with docker and mysql. I have build an image based on phusion/baseimage. I want to create image where /var/lib/mysql directory is shared with my host (OS X), because I dont want to store my data on container.
Everything works fine when directory /var/lib/mysql is not shared. When I share this directory, mysql service can not start. In logs are informations about problems with permissions while starting.
Result of ls -la from /var/lib is:
[...]
drwxr-xr-x 1 lc staff 170 Jan 3 16:55 mysql
[...]
The mysql user should be an owner. I tried to do:
sudo chown -R mysql:mysql mysql/
But this command didn't return any error and didn't change owner.
I have also tried to add my user (from container) to mysql group:
lc#cbe25ac0681e:~$ groups lc
lc : lc sudo mysql
But It also didn't work. Have anybody any idea how to solve this issue?
My docker-compose.yml file:
server:
image: lukasz619/light-core_server
ports:
- "40080:80"
- "40022:22"
- "40443:443"
- "43306:3306"
volumes:
- /Users/lukasz/Workspace/database/mysql:/var/lib/mysql
This is my Dockerfile:
FROM phusion/baseimage
RUN apt-get update
RUN apt-get install -y apache2
# Enable SSH
RUN rm -f /etc/service/sshd/down
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
# public key for root
ADD public_key.pub /tmp/public_key.pub
RUN cat /tmp/public_key.pub >> /root/.ssh/authorized_keys && rm -f /tmp/public_key.pub
EXPOSE 80
CMD ["/sbin/my_init"]
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

When we say that users are shared between the container and the host, it's not quite true; it's the UIDs that are actually shared. What this means is that the user named mysql in the container most likely has a different UID to the user mysql on the host.
We can try to fix this by using the image to set the permissions:
docker run --user root lukasz619/light-core_server chown -R mysql:mysql /var/lib/mysql
This may work, depending on how you've set up the image. There is also a further complication from the VM running in-between.

The problem is OS X.. I ran this docker-composer.yml
server:
image: lukasz619/light-core_server
ports:
- "40080:80"
- "40022:22"
- "40443:443"
- "43306:3306"
volumes:
- /var/mysql:/var/lib/mysql
Its possible to share directories (and do chown) ONLY between boot2docker and container, but do not work properly shareing between Os X and container.

Related

Is it possible to restore removed mysql docker container sql data? [duplicate]

I was running mariadb instance on docker windows toolkit. I did a env vaiable change on the mariaDB container using kitematic. Now it has recreated an instance loosing all my database. Is there a way to recover from this ?
Checked if threre are dangling volumes, and there are few
docker volume ls -f dangling=true
Got the data recovered using the dangling volumes.
Approach is as following.
First get the list of dangling volumes.
$ docker volume ls -f dangling=true
DRIVER VOLUME NAME
local 6f79b6329d98379495a284287e32a7a57605483dd7bf7fa19924fb2a98fb1d19
local 47bb077ef6f6df9f56bd30c35eeb45f35e62213d2c50db6f078bfdeeee6698ec
Then mounted it on to a Ubuntu container (so that you can go inside the directory and check what is there, as there is no other way to do this when you are using Docker Tool Box on windows)
$ docker run --name tempContainer1-UBUNTU -v 6f79b6329d98379495a284287e32a7a57605483dd7bf7fa19924fb2a98fb1d19:/var/lib/backup -t -i ubuntu /bin/bash
Then you will be inside the bash of newly created contianer. Go to newly mounted directory and check content
$cd /var/lib/backup
$ls
$aria_log.00000001 aria_log_control ib_buffer_pool ib_logfile0 ib_logfile1 ibdata1 ibtmp1 multi-master.info mysql performance_schema
-- once you are sure directory data is what you require, make a zip file of the folder
$apt-get update
$apt-get install zip
$cd ..
$zip -r backup.zip backup
On another terminal from host copy the content of container backup.zip to host
$docker cp tempContainer1-UBUNTU:/var/lib/backup.zip .
Then create a docker compose file like following and mount the backup folder as data directory. Run this on linux host as this mounting will not work as expected for mysql on windows.
version: "3.2"
services:
mysql:
image: mariadb:10.4.12
restart: always
ports:
- "3306:3306"
command: mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=ON --log_bin=ON
volumes:
- ./backup_data_folder:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: somepassword
TZ: Asia/Singapore
networks:
- frontend
container_name: maria
networks:
frontend:
Start
$docker-compose up
Once it is up, from another terminal go inside newly created container
$docker exec -t -i maria /bin/bash
-- Take dump of all the DBS
$mysqldump -u root -p --all-databases > alldb.sql
Copy content of the dump to host from another terminal from host
$docker cp maria:/alldb.sql .
Now this sql file is a full dump, restore it as usual on your mysql DB or contianer.
mysql -u root -p < alldb.sql
Recently I had to face the same problem for a lost wordpress container and I've followed the instructions from Don. However, as there were lots of dangling volumes, I had to optimize the process. I've managed a way to do it simpler, in the same terminal, resulting in the following steps:
docker volume ls -f dangling=true
DRIVER VOLUME NAME
local 43277666c8bc3da0b585d90952c2303226c92c6c6a561007c0c7ee00b6da817e
local 4fde3ea412e54a1b8b42fce6dae5de5135b9fd12933b020b43bd482cd5fd2225
local 52074ccfd62fb83b8b40cff5f8024215b34f79ad09b630e067ec732f811f798c
...
Then, for each container execute the following instruction, replacing 43277666c8bc3d... with each VOLUME NAME found. This instruction will remove previously maria-restore containers if they exist, create a new one and attach to it:
docker container ls -a -q --filter "name=maria-restore" && docker container rm -f maria-restore; docker run --name maria-restore -v 43277666c8bc3da0b585d90952c2303226c92c6c6a561007c0c7ee00b6da817e:/var/lib/mysql -d mariadb:10.4.12 mysqld --innodb-flush-method=littlesync --innodb-use-native-aio=ON --log_bin=ON && docker exec -it maria-restore bash
If it wasn't a mysql volume, it will fail and exit immediately. If it is a mysql volume, you'll be inside the mariadb container. The database will be already started. You can then connect to the database to see if it is the right one and backup it:
root#8b35c8e2c474:/# mysql -uadmin -p
root#8b35c8e2c474:/# mysqldump -uadmin -p --all-databases > alldb.sql
root#8b35c8e2c474:/# exit
Copy the backed up database:
docker cp mysql-restore:/alldb.sql .
Finally you'll have to clean up the maria-restore container:
docker container ls -a -q --filter "name=maria-restore" && docker container rm -f maria-restore

Mysql installation for alpine linux in docker

I have still problem with mysql installation on alpine in docker.
I need also openjdk:8u201-jdk-alpine3.9.
My dockerfile:
FROM openjdk:8u201-jdk-alpine3.9
RUN apk update && \
apk add mysql mysql-client && \
rm -f /var/cache/apk/* && \
addgroup mysql mysql && \
mkdir run/mysqld && \
touch /var/run/mysqld/mysqld.sock && \
touch /var/run/mysqld/mysqld.pid && \
chown -R mysql:mysql /var/run/mysqld/mysqld.sock && \
chown -R mysql:mysql /var/run/mysqld/mysqld.pid && \
chmod -R 644 /var/run/mysqld/mysqld.sock && \
apk add openrc --no-cache
But, in container:
- there is no mysql service (only mariadb, but it is probably standard situation for alpine)
- there is no any my.cnf file in /etc/mysql directory
When I tried mysql command, I got error:
Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (111)
When I tried mysql -h 127.0.0.1 -P 3306 -u root command, I got error:
Can't connect to MySQL server on '127.0.0.1' (115)
That same for localhost.
First of all - why do you want to install mysql-server on that specific image?
I would suggest using 2 separate containers - one for the mysql database and one for the application you are developing using that openjdk image.
You can simply use this gist https://gist.github.com/karlisabele/d0bebe3d27fc44a57d1db9a9abdff45a
to create a setup where your Java application can connect to mysql database using database (the service name) as hostname for mysql server.
See https://hub.docker.com/_/mysql for additional configurations on mysql image (you should define MYSQL user, password, db name etc...)
UPDATE
I updated the gist and added the environment variables necessary for the mysql to work... Replace the qwerty values with your own and you should be able to access the database from your Java application via database:3306 using the username and password provided in the environment variables
The volumes definition at the end of the file tells docker daemon that we want to create a persistent volume somewhere in the host file system and use mysql as an alias. So that when we define the database service volumes we can simply use the mysql:/var/lib/mysql and it will actually mount an obscure folder that docker created on your filesystem. This will allow the mysql database to have persistent state everytime you start the service (because it will mount the data from your host machine) and you don't have to worry about the actual location of the volume
You can see all volumes by running docker volumes ls
vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
#skip-networking
restart the mysql container

Docker-compose : mysqld: Can't create/write to file '/var/lib/mysql/is_writable' (Errcode: 13 - Permission denied)

I'm having an issue when starting the db service with docker compose:
version: '3'
services:
# Mysql DB
db:
image: percona:5.7
#build: ./docker/mysql
volumes:
- "./db/data:/var/lib/mysql"
- "./db/init:/docker-entrypoint-initdb.d"
- "./db/backups:/tmp/backups"
- "./shared/home:/home"
- "./shared/root:/home"
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: db_name
MYSQL_USER: user
MYSQL_PASSWORD: pass
ports:
- "3307:3306"
I have tried everything with no luck:
"./db/data:/var/lib/mysql:rw"
Creating a dockerfile and create from build instead of image:
FROM percona:5.7
RUN adduser mysql
RUN sudo chown mysql /var/lib/mysql
RUN sudo chgrp mysql /var/lib/mysql
Also I have tried to add a user on db service:
user: "1000:50"
But any of those could solve that.. What I'm missing?
MySQL 5.7 installation error `mysqld: Can't create/write to file '/var/lib/mysql/is_writable'`
I had to change ./db/data user:group to 999:999, so docker user is who is making the changes.
sudo chown 999:999 ./db/data
Make sure that the user who is running docker has access to ./db/data
# Not in the dockerfile
sudo chown $(whoami) ./db/data
sudo chgrp $(whoami) ./db/data
Docker tells you that you don't have the permissions, it might also mean that you need to verify that you shared volume ./db/data need to have the correct permissions.
According Dockerfile Percona 5.7 images runs under CentOS v8 and user mysql. Check the user ID (uid) and group ID (gid) inside container:
user#host$ docker run --rm -t percona:5.7.29 sh -c 'id'
uid=999(mysql) gid=999(mysql) groups=999(mysql)
Default user inside container uses 999 uid and gid. Than change your directory rights to 999:999:
sudo chown 999:999 ./db/data
This is an addition to Albeis answer.
I spent a whole day with a similar (almost exactly) problem. I also changed ownership of the related files, only to see them get wiped out and come back with permissions issues. I changed the ownership of my curl-installed docker-compose executable. I didn't receive a bit of reprieve until adding the volumes to the .dockerignore, as was suggested in this Github issue reply.
I suffered this issue and it took quite some time to figure out what the culprit was.
In my case, I have a dual boot system Winblowz-Linux.
My code of the problematic project was on a Windows filesystem.
Once I cloned the project into my Linux drive, on a ext4 filesystem, the problem went away.
need permission to execute scripts in directory
sudo chown 999:999 ./db/data
sudo chmod +x ./db/data

How to create mysql volume which exists even if i remove the docker container

I created docker container with mysql using -v option:
-v /storage/mysql1/mysql-datadir:/var/lib/mysql
When i removed container i lost database saved in /var/lib/mysql .
How can i create mysql container with -v option (to see everything from the host) and not lost the data?
Have you tried restarting the mysql service in your host?
This is something like restoring MYSQL db from physical file.
When you perform db operations inside container, it saves real-data and indexes in /var/lib/mysql path or the path that you specify while installing.
But, for Host machine, MYSQL service still does not know about the change.
Restart the MYSQL service by service mysql restart.
Additionally check the owner and permission in the MYSQL data folder like below:
sudo chown -R mysql:mysql /var/lib/mysql
sudo chmod -R 660 /var/lib/mysql/
sudo chown -R mysql.mysql /var/log/mysql
While running container, mount /var/log/mysql as well along with data folder.

Can I change owner of directory that is mounted on volume in IBM containers?

I'm trying to launch postgres in IBM containers. I have just created volume by:
$ cf ic volume create pgdata
Then mount it:
$ cf ic run --volume pgdata:/var/pgsql -p 22 registry.ng.bluemix.net/ruimo/pgsql944-cli
After logging into container through ssh, I found the mounted directory is owned by root:
drwxr-xr-x 3 root root 4096 Jul 8 08:20 pgsql
Since postgres does not permit to run by root, I want to change the owner of this directory. But I cannot change the owner of this directory:
# chown postgres:postgres pgsql
chown: changing ownership of 'pgsql': Permission denied
Is it possible to change owner of mounted directory?
In IBM Containers, the user namespace is enabled for docker engine. When, the user namespace is enabled, the effective root inside the container is a non-root user out side the container process and NFS is not allowing the mapped non-root user to perform the chown operation on the volume inside the container. Please note that the volume pgdata is a NFS, this can verified by executing mount -t nfs4 from container.
You can try the workaround suggested for
How can I fix the permissions using docker on a bluemix volume?
In this scenario it will be
1. Mount the Volume to `/mnt/pgdata` inside the container
cf ic run --volume pgdata:/mnt/pgdata -p 22 registry.ng.bluemix.net/ruimo/pgsql944-cli
2. Inside the container
2.1 Create "postgres" group and user
groupadd --gid 1010 postgres
useradd --uid 1010 --gid 1010 -m --shell /bin/bash postgres
2.2 Add the user to group "root"
adduser postgres root
chmod 775 /mnt/pgdata
2.3 Create pgsql directory under bind-mount volume
su -c "mkdir -p /mnt/pgdata/pgsql" postgres
ln -sf /mnt/pgdata/pgsql /var/pgsql
2.2 Remove the user from group "root"
deluser postgres root
chmod 755 /mnt/pgdata
In your Dockerfile you can modify the permissions of a directory.
RUN chown postgres:postgres pgsql
Additionally when you ssh in you can modify the permissions of the directory by using sudo.
sudo chown postgres:postgres pgsql
Here are 3 different but possible solutions:
Using a dockerfile and doing a chown before mounting the volume.
USER ROOT command in dockerfile before you do a chown.
Use --cap-add flag.