本站公告: PUI正式上线,欢迎体验。

Docker 支持UTF-8的mysql分享

框架积累 Mignon 4389浏览 0评论

在很多docker镜像中mysql都是默认编码,没有支持UTF-8,下面是根据官方改写的mysql Dockerfile文件

Dockerfile

FROM debian:jessie

# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql

RUN mkdir /docker-entrypoint-initdb.d

# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
RUN apt-get update && apt-get install -y perl --no-install-recommends && rm -rf /var/lib/apt/lists/*

# mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
RUN apt-get update && apt-get install -y libaio1 pwgen && rm -rf /var/lib/apt/lists/*

ENV MYSQL_MAJOR 5.5
ENV MYSQL_VERSION 5.5.48

# note: we're pulling the *.asc file from mysql.he.net instead of dev.mysql.com because the official mirror 404s that file for whatever reason - maybe it's at a different path?
RUN apt-get update && apt-get install -y curl --no-install-recommends && rm -rf /var/lib/apt/lists/* \
	&& curl -SL "http://dev.mysql.com/get/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux2.6-x86_64.tar.gz" -o mysql.tar.gz \
	&& curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux2.6-x86_64.tar.gz.asc" -o mysql.tar.gz.asc \
	&& apt-get purge -y --auto-remove curl \
	&& export GNUPGHOME="$(mktemp -d)" \
# gpg: key 5072E1F5: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
	&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5 \
	&& gpg --batch --verify mysql.tar.gz.asc mysql.tar.gz \
	&& rm -r "$GNUPGHOME" mysql.tar.gz.asc \
	&& mkdir /usr/local/mysql \
	&& tar -xzf mysql.tar.gz -C /usr/local/mysql --strip-components=1 \
	&& rm mysql.tar.gz \
	&& rm -rf /usr/local/mysql/mysql-test /usr/local/mysql/sql-bench \
	&& rm -rf /usr/local/mysql/bin/*-debug /usr/local/mysql/bin/*_embedded \
	&& find /usr/local/mysql -type f -name "*.a" -delete \
	&& apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/* \
	&& { find /usr/local/mysql -type f -executable -exec strip --strip-all '{}' + || true; } \
	&& apt-get purge -y --auto-remove binutils
ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts

# replicate some of the way the APT package configuration works
# this is only for 5.5 since it doesn't have an APT repo, and will go away when 5.5 does
RUN mkdir -p /etc/mysql/conf.d \
	&& { \
		echo '[mysqld]'; \
		echo 'skip-host-cache'; \
		echo 'skip-name-resolve'; \
		echo 'user = mysql'; \
		echo 'datadir = /var/lib/mysql'; \
		echo '!includedir /etc/mysql/conf.d/'; \
	} > /etc/mysql/my.cnf

RUN mkdir -p /etc/mysql/conf.d \
	&& { \
		echo '[client]'; \
		echo 'default-character-set=utf8'; \
		echo '[mysqld]'; \
		echo 'character-set-server=utf8'; \
	} > /etc/mysql/conf.d/character.cnf
VOLUME /var/lib/mysql

COPY docker-entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

docker-entrypoint.sh

#!/bin/bash
set -eo pipefail

# if command starts with an option, prepend mysqld
if [ "${1:0:1}" = '-' ]; then
	set -- mysqld "$@"
fi

if [ "$1" = 'mysqld' ]; then
	# Get config
	DATADIR="$("$@" --verbose --help --log-bin-index=`mktemp -u` 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')"

	if [ ! -d "$DATADIR/mysql" ]; then
		if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" -a -z "$MYSQL_USER" -a -z "$MYSQL_PASSWORD" ]; then
			echo >&2 'error: database is uninitialized and password option is not specified '
			echo >&2 '  You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD, MYSQL_RANDOM_ROOT_PASSWORD, MYSQL_USER and MYSQL_PASSWORD'
			exit 1
		fi

		if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
			MYSQL_RANDOM_ROOT_PASSWORD='yes'
		fi

		mkdir -p "$DATADIR"
		chown -R mysql:mysql "$DATADIR"

		echo 'Initializing database'
		mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --basedir=/usr/local/mysql
		echo 'Database initialized'

		"$@" --skip-networking --basedir=/usr/local/mysql &
		pid="$!"

		mysql=( mysql --protocol=socket -uroot )

		for i in {30..0}; do
			if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then
				break
			fi
			echo 'MySQL init process in progress...'
			sleep 1
		done
		if [ "$i" = 0 ]; then
			echo >&2 'MySQL init process failed.'
			exit 1
		fi

		if [ -z "$MYSQL_INITDB_SKIP_TZINFO" ]; then
			# sed is for https://bugs.mysql.com/bug.php?id=20545
			mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
		fi

		if [ ! -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
			MYSQL_ROOT_PASSWORD="$(pwgen -1 32)"
			echo "GENERATED ROOT PASSWORD: $MYSQL_ROOT_PASSWORD"
		fi
		
		echo "What's done in this file shouldn't be replicated or products like mysql-fabric won't work."
		
		"${mysql[@]}" <<-EOSQL
			SET @@SESSION.SQL_LOG_BIN=0;
			DELETE FROM mysql.user ;
			CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
			GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ;
			DROP DATABASE IF EXISTS test ;
			FLUSH PRIVILEGES ;
		EOSQL

		if [ ! -z "$MYSQL_ROOT_PASSWORD" ]; then
			mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
		fi

		if [ "$MYSQL_DATABASE" ]; then
			echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
			mysql+=( "$MYSQL_DATABASE" )
		fi

		if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
			"${mysql[@]}" <<-EOSQL
				SET @@SESSION.SQL_LOG_BIN=0;
				CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}' ;
				GRANT Alter, Alter Routine, Create, Create Routine, Create Temporary Tables, Create View, Delete, Drop, Event, Execute, Index, Insert, Process, Replication Client, Replication Slave, Select, Show Databases, Show View, Trigger, Update ON *.* TO '${MYSQL_USER}'@'%' WITH GRANT OPTION ;
				-- REVOKE ALL ON mysql.* FROM '${MYSQL_USER}'@'%';
				delete from mysql.db where Host='%' and User='${MYSQL_USER}';
				insert into mysql.db ( Create_tmp_table_priv, Insert_priv, Host, Update_priv, Show_view_priv, Trigger_priv, Grant_priv, Index_priv, Alter_priv, User, References_priv, Create_routine_priv, Event_priv, Execute_priv, Alter_routine_priv, Drop_priv, Db, Select_priv, Delete_priv, Lock_tables_priv, Create_view_priv, Create_priv) values ( 'N', 'N', '%', 'N', 'N', 'N', 'N', 'N', 'N', '${MYSQL_USER}', 'N', 'N', 'N', 'N', 'N', 'N', 'performance_schema', 'N', 'N', 'N', 'N', 'N');
				insert into mysql.db ( Create_tmp_table_priv, Insert_priv, Host, Update_priv, Show_view_priv, Trigger_priv, Grant_priv, Index_priv, Alter_priv, User, References_priv, Create_routine_priv, Event_priv, Execute_priv, Alter_routine_priv, Drop_priv, Db, Select_priv, Delete_priv, Lock_tables_priv, Create_view_priv, Create_priv) values ( 'N', 'N', '%', 'N', 'N', 'N', 'N', 'N', 'N', '${MYSQL_USER}', 'N', 'N', 'N', 'N', 'N', 'N', 'mysql', 'N', 'N', 'N', 'N', 'N');
				FLUSH PRIVILEGES ;
			EOSQL
        		
		    echo "CREATE mysql USER '$MYSQL_USER($MYSQL_PASSWORD)' successful."
			
			if [ "$MYSQL_DATABASE" ]; then
				echo "GRANT ALL ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%' ;" | "${mysql[@]}"

			 	echo "CREATE database '$MYSQL_DATABASE' successful"
			fi
			echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
			
		fi

		echo
		for f in /docker-entrypoint-initdb.d/*; do
			case "$f" in
				*.sh)     echo "$0: running $f"; . "$f" ;;
				*.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
				*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
				*)        echo "$0: ignoring $f" ;;
			esac
			echo
		done

		if [ ! -z "$MYSQL_ONETIME_PASSWORD" ]; then
			echo >&2
			echo >&2 'Sorry, this version of MySQL does not support "PASSWORD EXPIRE" (required for MYSQL_ONETIME_PASSWORD).'
			echo >&2
		fi
		if ! kill -s TERM "$pid" || ! wait "$pid"; then
			echo >&2 'MySQL init process failed.'
			exit 1
		fi

		echo
		echo 'MySQL init process done. Ready for start up.'
		echo
	fi

	chown -R mysql:mysql "$DATADIR"
fi

exec "$@"

优化

1、优化了创建新用户时,新用户权限分配。

2、优化了当不设置root 用户密码时,脚本会出现错误并自动退出,

3、优化不设置root用户密码并且没有设置root用户名密码为空时,自动随机生成root用户密码。随机密码请到log中查看"GENERATED ROOT PASSWORD"

docker-compose.yml

mysql:
  image: mysql:5.5.48
  privileged: true
  restart: always
  ports:
  - 3306:3306
  volumes:
  - /my/own/datadir:/var/lib/mysql
  environment:
  - MYSQL_ROOT_PASSWORD=admin1234
  - MYSQL_PASSWORD=admin123
  - MYSQL_USER=admin
  - MYSQL_DATABASE=sixtykb

脚本地址:https://coding.net/u/meyer/p/docker-worker/git/tree/master/mysql

转载请注明:码农博客 » Docker 支持UTF-8的mysql分享

游客
发表我的评论 换个身份
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  • 验证码 (必填)点击刷新验证码