在很多docker镜像中mysql都是默认编码,没有支持UTF-8,下面是根据官方改写的mysql Dockerfile文件
DockerfileFROM 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 " 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[@]}" <
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[@]}" <
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[@]}"
*.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.ymlmysql:
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