9

On OS X.

I am trying to run mysql in a docker container through boot2docker, by mounting the volume /var/lib/mysql on the host, so that I can have persistant mysql data. I plan to use a data only container in future, but right now I was trying to do this using this option.

I use the following command to run the container :

docker run -v /Users/yash/summers/db:/var/lib/mysql -i -t 'image name'

The /Users/yash/summers/db folder is already there.

I am facing persmission issues in this. Using commandline, I am able to access the directory, create/remove new files, but when I am running service mysql start, I get the following error:

150528 15:43:43 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
150528 15:43:43 [Warning] Using unique option prefix key_buffer instead of key_buffer_size is deprecated and will be removed in a future release. Please use the full name instead.
150528 15:43:43 [Note] /usr/sbin/mysqld (mysqld 5.5.43-0ubuntu0.14.04.1) starting as process 909 ... 
150528 15:43:43 [Warning] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
150528 15:43:43 [Warning] Using unique option prefix myisam-recover instead of myisam-recover-options is deprecated and will be removed in a future release. Please use the full name instead.150528 15:43:43 [Note] Plugin 'FEDERATED' is disabled.
/usr/sbin/mysqld: Table 'mysql.plugin' doesn't exist
150528 15:43:43 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
150528 15:43:43 InnoDB: The InnoDB memory heap is disabled
150528 15:43:43 InnoDB: Mutexes and rw_locks use GCC atomic builtins
150528 15:43:43 InnoDB: Compressed tables use zlib 1.2.8 
150528 15:43:43 InnoDB: Using Linux native AIO
150528 15:43:43 InnoDB: Initializing buffer pool, size = 128.0M
150528 15:43:43 InnoDB: Completed initialization of buffer pool
150528 15:43:43  InnoDB: Operating system error number 13 in a file operation.
InnoDB: The error means mysqld does not have the access rights to
InnoDB: the directory.
InnoDB: File name ./ibdata1
InnoDB: File operation call: 'create'.
InnoDB: Cannot continue operation.
150528 15:43:44 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended 

I have trying to solve this for the past 2 days, going through so many pages like this, this, and this.

I can't solve my problem. I think I am not able to perfectly do what the solutions are suggesting.

From my understanding, there are some workarounds listed on those pages which include changing the uids and guids, but I think they are not well explained.

Can anybody please explain to me a detailed workaround for this.

Update 1 : I tried the it with using a data only container also, and still facing the same issue.

I am able to run everything fine if I don't use any -v or --volumes-from option, so I think there is no prob in mysql server.

Update 2 : Dockerfile used for creating the data-only container:

FROM ubuntu

RUN mkdir /var/lib/mysql

VOLUME /var/lib/mysql
Community
  • 1
  • 1
Yash
  • 5,225
  • 4
  • 32
  • 65

3 Answers3

3

There are two different solutions.

  1. Solution #1. With Dockerfile

    (I don't like it because I prefer official image from Docker Hub without any changes)

    Add RUN usermod -u 1000 mysql to your Docker file to set ID 1000 for user "mysql" ( the same ID like inside docker-machine).

  2. Solution #2. With my.cnf.

    Still I am using my own config I prefer this solution. We alredy have root user with ID 1000, because of that we can run MySQL with this user:

    • my.cnf

      Main row is user = root (you can use sed to change only this row in file. I prefer mount all file)

      [client]
      port        = 3306
      socket      = /var/run/mysqld/mysqld.sock
      default-character-set = utf8
      
      [mysqld_safe]
      pid-file    = /var/run/mysqld/mysqld.pid
      socket      = /var/run/mysqld/mysqld.sock
      nice        = 0
      
      [mysqld]
      user        = root
      pid-file    = /var/run/mysqld/mysqld.pid
      socket      = /var/run/mysqld/mysqld.sock
      port        = 3306
      basedir     = /usr
      datadir     = /var/lib/mysql
      tmpdir      = /tmp
      lc-messages-dir = /usr/share/mysql
      explicit_defaults_for_timestamp
      init_connect='SET collation_connection = utf8_unicode_ci'
      init_connect='SET NAMES utf8'
      character-set-server=utf8
      collation-server=utf8_unicode_ci
      skip-character-set-client-handshake
      
      # Instead of skip-networking the default is now to listen only on
      # localhost which is more compatible and is not less secure.
      #bind-address   = 127.0.0.1
      
      #log-error  = /var/log/mysql/error.log
      
      # Recommended in standard MySQL setup
      sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
      
      # Disabling symbolic-links is recommended to prevent assorted security risks
      symbolic-links=0
      
      # * IMPORTANT: Additional settings that can override those from this file!
      #   The files must end with '.cnf', otherwise they'll be ignored.
      #
      !includedir /etc/mysql/conf.d/
      
    • Change default my.cnf with this file:

      docker run -it -v ./mysql/var/lib/mysql:/var/lib/mysql -v ./my.cnf::/etc/mysql/my.cnf mariadb:10.0.22

ashatrov
  • 1,082
  • 7
  • 11
0

When you are using docker run -v option then docker don't manipulate with files ownership. So owner of the mounted folder inside container will have the same UID as in the host system (username can be different). You can change ownership of the file or directory inside container by chmod command but it change ownership in host sytem too. So you can prepare correct ownership on your host system before you run docker container. This example demonstrates how it works (try it on your system):

I have ~/foo directory which is owned by me - my UID is 1000

~ $ ls -lnd foo
drwxr-xr-x 2 1001 1000 4096 Nov 24 22:47 foo

Run docker container, mount ~/foo directory to them and display ownership inside container

~ $ docker run -it --rm -v ~/foo:/tmp/foo busybox ls -ln /tmp
total 4
drwxr-xr-x    2 1000     1000          4096 Nov 24 21:47 foo

Owner UID inside container is the same. Now I change directory ownership on my computer.

~ $ sudo chown 1001 foo

Start container again, mount the foo directory and display ownership

~ $ docker run -it --rm -v ~/foo:/tmp/foo busybox ls -ln /tmp
total 4
drwxr-xr-x    2 1001     1000          4096 Nov 24 21:47 foo

Owner UID was changed as well

But there is one exception. If you try to mount volume to nonexistent directory then docker will create this missing directory automatically (but this is deprecated feature, so don't do this) and this directory will by created with UID 0. Try it:

~ $ docker run -it --rm -v ~/foo:/tmp/bar/foo busybox ls -ln /tmp
total 4
drwxr-xr-x    3 0        0             4096 Nov 24 22:10 bar
eNca
  • 1,043
  • 11
  • 21
-1

I similarly ran into this issue; I solved it by chmod/chown'ing inside my data container, e.g.:

FROM ubuntu

# Create data directory
RUN mkdir -p /data /var/lib/mysql
RUN chmod -R 777 /data /var/lib/mysql
RUN chown -R root:root /data /var/lib/mysql

# Create /data volume
VOLUME /data
VOLUME /var/lib/mysql

I believe this works because UFS now properly records permissions rather than relying on a direct from host mount to do so, which as you've discovered, does not work on OS X

Aaron
  • 4,194
  • 2
  • 19
  • 19