【问题标题】:Mysql won't start in docker container when mounting /var/lib/mysql to local host volume将 /var/lib/mysql 挂载到本地主机卷时,Mysql 不会在 docker 容器中启动
【发布时间】:2018-02-01 23:31:36
【问题描述】:

我有以下 Dockerfile 来创建运行 NGINX 和 MYSQL 的容器。我正在尝试将 /var/lib/mysql 挂载到本地 Docker 主机,以便在容器被销毁后保留 MySQL 数据库。

    FROM ubuntu:16.04
    MAINTAINER - ******


    ## Install php nginx mysql supervisor ###
    ########################################
    RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
        php-fpm \
        php-cli \
        php-gd  \
        php-mcrypt \
        php-mysql \
        php-curl \
        php-xml \
        php-json \
        nginx \
        curl \
        unzip \
        mysql-server \
        supervisor


    ### Nginx  & PHP-FPM ###
    ########################


    # Remove the default Nginx configuration file
    RUN rm -v /etc/nginx/nginx.conf

    # Copy configuration files from the current directory
    ADD files/nginx.conf /etc/nginx/nginx.conf
    ADD files/php-fpm.conf /etc/php/7.0/fpm/


    ### MYSQL ###
    ############
    ENV ROOT_PWD test

    ### Supervisor.conf ###
######################
ADD files/supervisord.conf /etc/supervisor/supervisord.conf


### Container configuration ###
###############################

EXPOSE 80
VOLUME /DATA
VOLUME /var/lib/mysql

# Set the default command to execute
# when creating a new container
ADD start.sh /
RUN chmod u+x /start.sh
CMD /start.sh

下面是我的入口点脚本 start.sh:

#!/bin/sh


# 1.MYSQL SETUP 
#
# ###########

MYSQL_CHARSET=${MYSQL_CHARSET:-"utf8"}
MYSQL_COLLATION=${MYSQL_COLLATION:-"utf8_unicode_ci"}

create_data_dir() {
  mkdir -p /var/lib/mysql
  chmod -R 0700 /var/lib/mysql
  chown -R mysql:mysql /var/lib/mysql
}

create_run_dir() {
  mkdir -p /run/mysqld
  chmod -R 0755 /run/mysqld
  chown -R mysql:root /run/mysqld
}

create_log_dir() {
  mkdir -p /var/log/mysql
  chmod -R 0755 /var/log/mysql
  chown -R mysql:mysql /var/log/mysql
}

mysql_default_install() {
    /usr/bin/mysql_install_db --datadir=/var/lib/mysql
}

create_modx_database() {
   # start mysql server.
    /usr/bin/mysqld_safe >/dev/null 2>&1 &

   # wait for mysql server to start (max 30 seconds).
    timeout=30
    echo -n "Waiting for database server to accept connections"
    while ! /usr/bin/mysqladmin -u root status >/dev/null 2>&1
    do
      timeout=$(($timeout - 1))
      if [ $timeout -eq 0 ]; then
        echo -e "\nCould not connect to database server. Aborting..."
        exit 1
      fi
      echo -n "."
      sleep 1
    done
    echo

    # create database and assign user permissions.
    if [ -n "${DB_NAME}" -a -n "${DB_USER}" -a -n "${DB_PASS}" ]; then
       echo "Creating database \"${DB_NAME}\" and granting access to \"${DB_USER}\" database."
        mysql -uroot  -e  "CREATE DATABASE ${DB_NAME};"
        mysql -uroot  -e  "GRANT USAGE ON *.* TO ${DB_USER}@localhost IDENTIFIED BY '${DB_PASS}';"
        mysql -uroot  -e  "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO ${DB_USER}@localhost;"

    fi 

}

set_mysql_root_pw() {
    # set root password for mysql.
    echo "Setting root password"
    /usr/bin/mysqladmin -u root password "${ROOT_PWD}"

    # shutdown mysql reeady for supervisor to start mysql.
    /usr/bin/mysqladmin -u root --password=${ROOT_PWD} shutdown
}


# 2.NGINX & PHP-FPM 
#
# ################

create_www_dir() {
  # Create LOG directoties for NGINX & PHP-FPM
  echo "Creating www directories"
  mkdir -p /DATA/logs/php-fpm
  mkdir -p /DATA/logs/nginx
  mkdir -p /DATA/www

}

apply_www_permissions(){
  echo "Applying www permissions"
  chown -R www-data:www-data /DATA/www /DATA/logs

}



# Running all script functions
create_data_dir
create_run_dir
create_log_dir
mysql_default_install
create_modx_database
set_mysql_root_pw
create_www_dir
apply_www_permissions

# Start Supervisor 
echo "Starting Supervisor"
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

我无需将 /var/lib/mysql 文件夹安装到本地 docker 主机即可成功运行容器:

docker run  --name modx.test --expose 80  -d -e 'VIRTUAL_HOST=modx.test' -e 'DB_NAME=modx' -e 'DB_USER=modx' -e 'DB_PASS=test' -v /data/sites/test:/DATA  modx

如果我尝试使用以下命令安装 /var/lib/mysql:

docker run  --name modx.test --expose 80  -d -e 'VIRTUAL_HOST=modx.test' -e 'DB_NAME=modx' -e 'DB_USER=modx' -e 'DB_PASS=test' -v /data/sites/test:/DATA  -v /data/sites/test/mysql:/var/lib/mysql modx

出现以下错误:2017-08-24 07:47:22 [ERROR] The data directory '/var/lib/mysql' already exist and is not empty. Waiting for database server to accept connections.............................-e Could not connect to database server. Aborting...

【问题讨论】:

  • 为什么不使用 docker hub 中的现有容器?
  • 它是自动安装 MODX CMS 的更大项目的一部分,但我已将其从代码中删除。
  • 我认为是因为我没有将 /var/lib/mysql 声明为 VOLUME,将尝试这样做。
  • 如果使用 VOLUME 而不是 BIND mount 它似乎可以工作
  • 如果您真的必须创建自己的映像,请查看 dockerhub 的 Dockerfile 以了解他们在做什么以及您有什么不同。

标签: docker


【解决方案1】:

设法解决了问题。通过使用/usr/sbin/mysqld --initialize-insecure --datadir=/var/lib/mysql 并添加一个 IF 子句来检查是否已经创建了初始数据库。

mysql_default_install() {
  if [ ! -d "/var/lib/mysql/mysql" ]; then
      echo "Creating the default database"
      /usr/sbin/mysqld --initialize-insecure --datadir=/var/lib/mysql

  else
      echo "MySQL database already initialiazed"
  fi
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多