Skip to content

Commit 55fa7a5

Browse files
committed
Add support for "/docker-entrypoint-initdb.d" similar to PostgreSQL's implementation
This also cleans up some minor unnecessary bits in `docker-entrypoint.sh` so that it's more consistent. Compare to https://github.com/docker-library/postgres/blob/a82c28e1c407ef5ddfc2a6014dac87bcc4955a26/docker-entrypoint.sh#L49-L97
1 parent 4df6cba commit 55fa7a5

File tree

6 files changed

+102
-114
lines changed

6 files changed

+102
-114
lines changed

5.5/Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
FROM debian:wheezy
2+
23
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
34
RUN groupadd -r mysql && useradd -r -g mysql mysql
45

6+
RUN mkdir /docker-entrypoint-initdb.d
7+
58
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
69
# File::Basename
710
# File::Copy

5.5/docker-entrypoint.sh

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
#!/bin/bash
22
set -e
33

4-
get_option () {
5-
local section=$1
6-
local option=$2
7-
local default=$3
8-
# my_print_defaults can output duplicates, if an option exists both globally and in
9-
# a custom config file. We pick the last occurence, which is from the custom config.
10-
ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2- | tail -n1)
11-
[ -z $ret ] && ret=$default
12-
echo $ret
13-
}
14-
154
# if command starts with an option, prepend mysqld
165
if [ "${1:0:1}" = '-' ]; then
176
set -- mysqld "$@"
@@ -20,9 +9,6 @@ fi
209
if [ "$1" = 'mysqld' ]; then
2110
# Get config
2211
DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')"
23-
SOCKET=$(get_option mysqld socket "/tmp/mysql.sock")
24-
HOSTNAME=$(hostname)
25-
PIDFILE=$(get_option mysqld pid-file "$DATADIR/mysqld.pid")
2612

2713
if [ ! -d "$DATADIR/mysql" ]; then
2814
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then
@@ -38,25 +24,25 @@ if [ "$1" = 'mysqld' ]; then
3824
mysql_install_db --user=mysql --datadir="$DATADIR" --rpm --basedir=/usr/local/mysql
3925
echo 'Finished mysql_install_db'
4026

41-
mysqld --user=mysql --datadir="$DATADIR" --skip-networking --basedir=/usr/local/mysql --pid-file="$PIDFILE" &
42-
for i in $(seq 30 -1 0); do
43-
[ -S "$SOCKET" ] && break
27+
mysqld --user=mysql --datadir="$DATADIR" --skip-networking --basedir=/usr/local/mysql &
28+
pid="$!"
29+
for i in {30..0}; do
30+
if echo 'SELECT 1' | mysql --protocol=socket -uroot &> /dev/null; then
31+
break
32+
fi
4433
echo 'MySQL init process in progress...'
4534
sleep 1
4635
done
47-
if [ $i = 0 ]; then
36+
if [ "$i" = 0 ]; then
4837
echo >&2 'MySQL init process failed.'
4938
exit 1
5039
fi
5140

52-
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql --protocol=socket -uroot mysql
41+
mysql=( mysql --protocol=socket -uroot )
5342

54-
# These statements _must_ be on individual lines, and _must_ end with
55-
# semicolons (no line breaks or comments are permitted).
56-
# TODO proper SQL escaping on ALL the things D:
43+
mysql_tzinfo_to_sql /usr/share/zoneinfo | "${mysql[@]}" mysql
5744

58-
tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql)
59-
cat > "$tempSqlFile" <<-EOSQL
45+
"${mysql[@]}" <<-EOSQL
6046
-- What's done in this file shouldn't be replicated
6147
-- or products like mysql-fabric won't work
6248
SET @@SESSION.SQL_LOG_BIN=0;
@@ -65,36 +51,43 @@ if [ "$1" = 'mysqld' ]; then
6551
CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
6652
GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ;
6753
DROP DATABASE IF EXISTS test ;
54+
FLUSH PRIVILEGES ;
6855
EOSQL
56+
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
6957

7058
if [ "$MYSQL_DATABASE" ]; then
71-
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile"
59+
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
60+
mysql+=( "$MYSQL_DATABASE" )
7261
fi
7362

7463
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
75-
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile"
64+
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" | "${mysql[@]}"
7665

7766
if [ "$MYSQL_DATABASE" ]; then
78-
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile"
67+
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}"
7968
fi
80-
fi
8169

82-
echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile"
83-
84-
mysql --protocol=socket -uroot < "$tempSqlFile"
70+
echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
71+
fi
8572

86-
rm -f "$tempSqlFile"
87-
kill $(cat $PIDFILE)
88-
for i in $(seq 30 -1 0); do
89-
[ -f "$PIDFILE" ] || break
90-
echo 'MySQL init process in progress...'
91-
sleep 1
73+
echo
74+
for f in /docker-entrypoint-initdb.d/*; do
75+
case "$f" in
76+
*.sh) echo "$0: running $f"; . "$f" ;;
77+
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
78+
*) echo "$0: ignoring $f" ;;
79+
esac
80+
echo
9281
done
93-
if [ $i = 0 ]; then
94-
echo >&2 'MySQL hangs during init process.'
82+
83+
if ! kill -s TERM "$pid" || ! wait "$pid"; then
84+
echo >&2 'MySQL init process failed.'
9585
exit 1
9686
fi
87+
88+
echo
9789
echo 'MySQL init process done. Ready for start up.'
90+
echo
9891
fi
9992

10093
chown -R mysql:mysql "$DATADIR"

5.6/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ FROM debian:wheezy
33
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
44
RUN groupadd -r mysql && useradd -r -g mysql mysql
55

6+
RUN mkdir /docker-entrypoint-initdb.d
7+
68
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
79
# File::Basename
810
# File::Copy

5.6/docker-entrypoint.sh

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
#!/bin/bash
22
set -e
33

4-
get_option () {
5-
local section=$1
6-
local option=$2
7-
local default=$3
8-
# my_print_defaults can output duplicates, if an option exists both globally and in
9-
# a custom config file. We pick the last occurence, which is from the custom config.
10-
ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2- | tail -n1)
11-
[ -z $ret ] && ret=$default
12-
echo $ret
13-
}
14-
154
# if command starts with an option, prepend mysqld
165
if [ "${1:0:1}" = '-' ]; then
176
set -- mysqld "$@"
@@ -20,8 +9,6 @@ fi
209
if [ "$1" = 'mysqld' ]; then
2110
# Get config
2211
DATADIR="$("$@" --verbose --help 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')"
23-
SOCKET=$(get_option mysqld socket "$DATADIR/mysql.sock")
24-
PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid")
2512

2613
if [ ! -d "$DATADIR/mysql" ]; then
2714
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then
@@ -38,25 +25,25 @@ if [ "$1" = 'mysqld' ]; then
3825
echo 'Finished mysql_install_db'
3926

4027
mysqld --user=mysql --datadir="$DATADIR" --skip-networking &
41-
for i in $(seq 30 -1 0); do
42-
[ -S "$SOCKET" ] && break
28+
pid="$!"
29+
for i in {30..0}; do
30+
if echo 'SELECT 1' | mysql --protocol=socket -uroot &> /dev/null; then
31+
break
32+
fi
4333
echo 'MySQL init process in progress...'
4434
sleep 1
4535
done
46-
if [ $i = 0 ]; then
36+
if [ "$i" = 0 ]; then
4737
echo >&2 'MySQL init process failed.'
4838
exit 1
4939
fi
5040

51-
# sed is for https://bugs.mysql.com/bug.php?id=20545
52-
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | mysql --protocol=socket -uroot mysql
41+
mysql=( mysql --protocol=socket -uroot )
5342

54-
# These statements _must_ be on individual lines, and _must_ end with
55-
# semicolons (no line breaks or comments are permitted).
56-
# TODO proper SQL escaping on ALL the things D:
43+
# sed is for https://bugs.mysql.com/bug.php?id=20545
44+
mysql_tzinfo_to_sql /usr/share/zoneinfo | sed 's/Local time zone must be set--see zic manual page/FCTY/' | "${mysql[@]}" mysql
5745

58-
tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql)
59-
cat > "$tempSqlFile" <<-EOSQL
46+
"${mysql[@]}" <<-EOSQL
6047
-- What's done in this file shouldn't be replicated
6148
-- or products like mysql-fabric won't work
6249
SET @@SESSION.SQL_LOG_BIN=0;
@@ -65,36 +52,43 @@ if [ "$1" = 'mysqld' ]; then
6552
CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
6653
GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ;
6754
DROP DATABASE IF EXISTS test ;
55+
FLUSH PRIVILEGES ;
6856
EOSQL
57+
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
6958

7059
if [ "$MYSQL_DATABASE" ]; then
71-
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile"
60+
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
61+
mysql+=( "$MYSQL_DATABASE" )
7262
fi
7363

7464
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
75-
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile"
65+
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" | "${mysql[@]}"
7666

7767
if [ "$MYSQL_DATABASE" ]; then
78-
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile"
68+
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}"
7969
fi
80-
fi
81-
82-
echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile"
8370

84-
mysql --protocol=socket -uroot < "$tempSqlFile"
71+
echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
72+
fi
8573

86-
rm -f "$tempSqlFile"
87-
kill $(cat $PIDFILE)
88-
for i in $(seq 30 -1 0); do
89-
[ -f "$PIDFILE" ] || break
90-
echo 'MySQL init process in progress...'
91-
sleep 1
74+
echo
75+
for f in /docker-entrypoint-initdb.d/*; do
76+
case "$f" in
77+
*.sh) echo "$0: running $f"; . "$f" ;;
78+
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
79+
*) echo "$0: ignoring $f" ;;
80+
esac
81+
echo
9282
done
93-
if [ $i = 0 ]; then
94-
echo >&2 'MySQL hangs during init process.'
83+
84+
if ! kill -s TERM "$pid" || ! wait "$pid"; then
85+
echo >&2 'MySQL init process failed.'
9586
exit 1
9687
fi
88+
89+
echo
9790
echo 'MySQL init process done. Ready for start up.'
91+
echo
9892
fi
9993

10094
chown -R mysql:mysql "$DATADIR"

5.7/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ FROM debian:wheezy
33
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
44
RUN groupadd -r mysql && useradd -r -g mysql mysql
55

6+
RUN mkdir /docker-entrypoint-initdb.d
7+
68
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
79
# File::Basename
810
# File::Copy

5.7/docker-entrypoint.sh

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
#!/bin/bash
22
set -e
33

4-
get_option () {
5-
local section=$1
6-
local option=$2
7-
local default=$3
8-
# my_print_defaults can output duplicates, if an option exists both globally and in
9-
# a custom config file. We pick the last occurence, which is from the custom config.
10-
ret=$(my_print_defaults $section | grep '^--'${option}'=' | cut -d= -f2- | tail -n1)
11-
[ -z $ret ] && ret=$default
12-
echo $ret
13-
}
14-
154
# if command starts with an option, prepend mysqld
165
if [ "${1:0:1}" = '-' ]; then
176
set -- mysqld "$@"
@@ -20,8 +9,6 @@ fi
209
if [ "$1" = 'mysqld' ]; then
2110
# Get config
2211
DATADIR="$("$@" --verbose --help --innodb-read-only 2>/dev/null | awk '$1 == "datadir" { print $2; exit }')"
23-
SOCKET=$(get_option mysqld socket "$DATADIR/mysql.sock")
24-
PIDFILE=$(get_option mysqld pid-file "/var/run/mysqld/mysqld.pid")
2512

2613
if [ ! -d "$DATADIR/mysql" ]; then
2714
if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" ]; then
@@ -38,24 +25,24 @@ if [ "$1" = 'mysqld' ]; then
3825
echo 'Database initialized'
3926

4027
mysqld --user=mysql --datadir="$DATADIR" --skip-networking &
41-
for i in $(seq 30 -1 0); do
42-
[ -S $SOCKET ] && break
28+
pid="$!"
29+
for i in {30..0}; do
30+
if echo 'SELECT 1' | mysql --protocol=socket -uroot &> /dev/null; then
31+
break
32+
fi
4333
echo 'MySQL init process in progress...'
4434
sleep 1
4535
done
46-
if [ $i = 0 ]; then
36+
if [ "$i" = 0 ]; then
4737
echo >&2 'MySQL init process failed.'
4838
exit 1
4939
fi
5040

51-
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql --protocol=socket -uroot mysql
41+
mysql=( mysql --protocol=socket -uroot )
5242

53-
# These statements _must_ be on individual lines, and _must_ end with
54-
# semicolons (no line breaks or comments are permitted).
55-
# TODO proper SQL escaping on ALL the things D:
43+
mysql_tzinfo_to_sql /usr/share/zoneinfo | "${mysql[@]}" mysql
5644

57-
tempSqlFile=$(mktemp /tmp/mysql-first-time.XXXXXX.sql)
58-
cat > "$tempSqlFile" <<-EOSQL
45+
"${mysql[@]}" <<-EOSQL
5946
-- What's done in this file shouldn't be replicated
6047
-- or products like mysql-fabric won't work
6148
SET @@SESSION.SQL_LOG_BIN=0;
@@ -64,36 +51,43 @@ if [ "$1" = 'mysqld' ]; then
6451
CREATE USER 'root'@'%' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}' ;
6552
GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION ;
6653
DROP DATABASE IF EXISTS test ;
54+
FLUSH PRIVILEGES ;
6755
EOSQL
56+
mysql+=( -p"${MYSQL_ROOT_PASSWORD}" )
6857

6958
if [ "$MYSQL_DATABASE" ]; then
70-
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" >> "$tempSqlFile"
59+
echo "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\` ;" | "${mysql[@]}"
60+
mysql+=( "$MYSQL_DATABASE" )
7161
fi
7262

7363
if [ "$MYSQL_USER" -a "$MYSQL_PASSWORD" ]; then
74-
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" >> "$tempSqlFile"
64+
echo "CREATE USER '"$MYSQL_USER"'@'%' IDENTIFIED BY '"$MYSQL_PASSWORD"' ;" | "${mysql[@]}"
7565

7666
if [ "$MYSQL_DATABASE" ]; then
77-
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" >> "$tempSqlFile"
67+
echo "GRANT ALL ON \`"$MYSQL_DATABASE"\`.* TO '"$MYSQL_USER"'@'%' ;" | "${mysql[@]}"
7868
fi
79-
fi
8069

81-
echo 'FLUSH PRIVILEGES ;' >> "$tempSqlFile"
82-
83-
mysql --protocol=socket -uroot < "$tempSqlFile"
70+
echo 'FLUSH PRIVILEGES ;' | "${mysql[@]}"
71+
fi
8472

85-
rm -f "$tempSqlFile"
86-
kill $(cat $PIDFILE)
87-
for i in $(seq 30 -1 0); do
88-
[ -f "$PIDFILE" ] || break
89-
echo 'MySQL init process in progress...'
90-
sleep 1
73+
echo
74+
for f in /docker-entrypoint-initdb.d/*; do
75+
case "$f" in
76+
*.sh) echo "$0: running $f"; . "$f" ;;
77+
*.sql) echo "$0: running $f"; "${mysql[@]}" < "$f" && echo ;;
78+
*) echo "$0: ignoring $f" ;;
79+
esac
80+
echo
9181
done
92-
if [ $i = 0 ]; then
93-
echo >&2 'MySQL hangs during init process.'
82+
83+
if ! kill -s TERM "$pid" || ! wait "$pid"; then
84+
echo >&2 'MySQL init process failed.'
9485
exit 1
9586
fi
87+
88+
echo
9689
echo 'MySQL init process done. Ready for start up.'
90+
echo
9791
fi
9892

9993
chown -R mysql:mysql "$DATADIR"

0 commit comments

Comments
 (0)