-
Notifications
You must be signed in to change notification settings - Fork 0
/
start.sh
256 lines (227 loc) · 9.37 KB
/
start.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/bin/bash
#
# this waits for changes in files passed in params and sends php-fpm a USR1
# signal to reload the logfiles
#
# we need to watch the containing directories and filter events by files, as
# when a file is open while being deleted (as it happens with php-fpm
# logfiles), inotify fails to register a delete_self event, for some reason.
#
function watch_logfiles {
# inform
echo "+-- watching for changes in watchfile(s):"
# prepare the watch files array
unset WATCH_FILES
WATCH_FILES=()
# build the egrep filter
# start off with the general events happening directly on watched directories
EGREP_FILTER="^(.+ (DELETE_SELF|MOVE_SELF|UNMOUNT)"
# get the watch files; filter out `/dev/null`s we don't need
for WATCH_FILE in "$@"; do
if [ ! $WATCH_FILE = "/dev/null" ]; then
WATCH_FILES+=("$WATCH_FILE")
echo " +-- $WATCH_FILE"
# add filter for the particular filee in its directory
# TODO: escape regex special chars in filenames!
EGREP_FILTER="${EGREP_FILTER}|$( dirname "$WATCH_FILE" )/ (MOVED_FROM|DELETE) $( basename "$WATCH_FILE" )"
fi
done
# do we actually have any files to watch?
if [ ${#WATCH_FILES[@]} = 0 ]; then
echo " +-- no files to watch."
return 0
fi
# finish the regex with a nice dollar sign
EGREP_FILTER="$EGREP_FILTER)$"
# loopy-loop!
while true; do
echo " +-- checking watchfiles..."
for WATCH_FILE in "${WATCH_FILES[@]}"; do
# if the file is not there, create
if [ ! -e "$( dirname "$WATCH_FILE" )" ]; then
echo " +-- waiting for missing watch file directory: $( dirname "$WATCH_FILE" )"
sleep 1
continue 2 # we want to break out to the outer loop, and then to continue
fi
done
echo " +-- watchfiles ok, setting the watches for dirs containing ${WATCH_FILES[*]}"
# monitor for events on directories *containing* the files we want to watch
# grep only the events we want
# and then act upon them
#
# using pure egrep confuses read in the next piped step, so we need to work
# around that via a minimal while look; not elegant, but works
inotifywait -m \
-e delete_self \
-e move_self \
-e unmount \
-e delete \
-e moved_from \
-q $( dirname "${WATCH_FILES[@]}" ) \
| while true; do egrep -m 1 "$EGREP_FILTER"; done \
| while true; do
read -r AN_EVENT
echo " +-- event: $AN_EVENT"
echo " sending USR1 to php-fpm (pid $( cat "$PHP_PID_FILE" ))..."
kill -USR1 "$( cat "$PHP_PID_FILE" )"
# TODO handle DELETE_SELF, MOVE_SELF, UNMOUNT
done
done
}
function abort {
# kill php-fpm if it is running
[ -s $PHP_PID_FILE ] && kill -USR1 "$( cat "$PHP_PID_FILE" )"
# inform
echo
echo "* * * ABORTED * * *"
echo
exit 0
}
# trap whatever we need to trap
trap abort SIGHUP SIGINT SIGQUIT SIGTERM SIGSTOP SIGKILL
# we need root
if [[ `whoami` != "root" ]]; then
echo "we need root, and we are: $( whoami ); exiting!.."
exit 1
fi
# sanity check
if [[ "$PHP_APP_NAME" == "" || "$PHP_APP_USER" == "" || "$PHP_APP_GROUP" == "" || "$PHP_APP_DIR" == "" ]]; then
echo '$PHP_APP_NAME, $PHP_APP_USER, $PHP_APP_GROUP or $PHP_APP_DIR are not set'
exit 2
fi
# info
echo "\$PHP_APP_NAME :: $PHP_APP_NAME"
echo "\$PHP_APP_USER :: $PHP_APP_USER"
echo "\$PHP_APP_GROUP :: $PHP_APP_GROUP"
echo "\$PHP_APP_DIR :: $PHP_APP_DIR"
echo "\$PHP_LISTEN :: $PHP_LISTEN"
echo "\$PHP_ACCESS_LOG :: $PHP_ACCESS_LOG"
echo "\$PHP_ERROR_LOG :: $PHP_ERROR_LOG"
echo "\$PHP_SLOW_LOG :: $PHP_SLOW_LOG"
echo "\$PHP_SLOW_LOG_TIMEOUT :: $PHP_SLOW_LOG_TIMEOUT"
echo "\$PHP_PID_FILE :: $PHP_PID_FILE"
# do we have UID/GID number given explicitly?
if [[ "$PHP_APP_UID" != "" ]]; then
echo "\$PHP_APP_UID :: $PHP_APP_UID"
fi
if [[ "$PHP_APP_GID" != "" ]]; then
echo "\$PHP_APP_GID :: $PHP_APP_GID"
fi
# get group data, if any, and check if the group exists
if GROUP_DATA=`getent group "$PHP_APP_GROUP"`; then
# it does! do we have the gid given?
if [[ "$PHP_APP_GID" != "" ]]; then
# we do! do these match?
if [[ `echo "$GROUP_DATA" | cut -d ':' -f 3` != "$PHP_APP_GID" ]]; then
# they don't. we have a problem
echo "ERROR: group $PHP_APP_GROUP already exists, but with a different gid (`echo "$GROUP_DATA" | cut -d ':' -f 3`) than provided ($PHP_APP_GID)!"
exit 3
fi
fi
# if no gid given, the existing group satisfies us regardless of the GID
# group does not exist
else
# do we have the gid given?
GID_ARGS=""
if [[ "$PHP_APP_GID" != "" ]]; then
# we do! does a group with a given id exist?
if getent group "$PHP_APP_GID" >/dev/null; then
echo "ERROR: a group with a given id ($PHP_APP_GID) already exists, can't create group $PHP_APP_GROUP with this id"
exit 4
fi
# prepare the fragment of the groupadd command
GID_ARGS="-g $PHP_APP_GID"
fi
# we either have no GID given (and don't care about it), or have a GID given that does not exist in the system
# great! let's add the group
groupadd $GID_ARGS "$PHP_APP_GROUP"
fi
# get user data, if any, and check if the user exists
if USER_DATA=`id -u "$PHP_APP_USER" 2>/dev/null`; then
# it does! do we have the uid given?
if [[ "$PHP_APP_UID" != "" ]]; then
# we do! do these match?
if [[ "$USER_DATA" != "$PHP_APP_UID" ]]; then
# they don't. we have a problem
echo "ERROR: user $PHP_APP_USER already exists, but with a different uid ("$USER_DATA") than provided ($PHP_APP_UID)!"
exit 5
fi
fi
# if no uid given, the existing user satisfies us regardless of the uid
# but is he in the right group?
adduser "$PHP_APP_USER" "$PHP_APP_GROUP"
# user does not exist
else
# do we have the uid given?
UID_ARGS=""
if [[ "$PHP_APP_UID" != "" ]]; then
# we do! does a group with a given id exist?
if getent passwd "$PHP_APP_UID" >/dev/null; then
echo "ERROR: a user with a given id ($PHP_APP_UID) already exists, can't create user $PHP_APP_USER with this id"
exit 6
fi
# prepare the fragment of the useradd command
UID_ARGS="-u $PHP_APP_UID"
fi
# we either have no UID given (and don't care about it), or have a UID given that does not exist in the system
# great! let's add the user
useradd $UID_ARGS -r -g "$PHP_APP_GROUP" "$PHP_APP_USER"
fi
# do we need particular packages installed?
if [ ! -z ${INSTALL_PACKAGES+x} ]; then
# aye, install them
echo
echo "* * * WARNING: INSTALL_PACKAGES envvar support is deprecated and will soon be removed!"
echo "* * * WARNING: use INSTALL_PACKAGES build arg instead!"
echo
DEBIAN_FRONTEND=noninteractive apt-get -q update && apt-get -q -y --no-install-recommends install $INSTALL_PACKAGES && apt-get -q clean && apt-get -q -y autoremove
fi
# log, run and data
mkdir -p /var/log/php-fpm
mkdir -p /var/run/php-fpm
mkdir -p $PHP_APP_DIR
chown $PHP_APP_USER:$PHP_APP_GROUP /var/log/php-fpm
chown $PHP_APP_USER:$PHP_APP_GROUP /var/run/php-fpm
chown $PHP_APP_USER:$PHP_APP_GROUP $PHP_APP_DIR
# PHP-FPM pool configuration.
# expects configuration in /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf file
if [ -s /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf ]; then
echo "config file /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf found, ignoring any PHP_* env vars!"
else
# if that file does not exist or is empty, it creates it with config from envvars
echo "config file /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf not found, setting up from PHP_* env vars!"
mv /etc/php/7.0/fpm/pool.d/pool.conf /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- pool name..."
sed -i "s/pool_name/$PHP_APP_NAME/g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- user..."
sed -i "s/app_user/$PHP_APP_USER/g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- group..."
sed -i "s/app_group/$PHP_APP_GROUP/g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- listen..."
sed -i -r -e "s@^listen = .*@listen = $PHP_LISTEN@g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
# access and slowlog locations
echo "+-- access log..."
sed -i -r -e "s@^access\.log = .*@access.log = \"$PHP_ACCESS_LOG\"@g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- slowlog..."
sed -i -r -e "s@^slowlog = .*@slowlog = \"$PHP_SLOW_LOG\"@g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
echo "+-- slowlog timeout..."
sed -i -r -e "s@^request_slowlog_timeout = .*@request_slowlog_timeout = \"$PHP_SLOW_LOG_TIMEOUT\"@g" /etc/php/7.0/fpm/pool.d/$PHP_APP_NAME.conf
fi
# Change the default error location.
echo "+-- error log..."
sed -i "s@error_log = /var/log/php7.0-fpm.log@error_log = \"$PHP_ERROR_LOG\"@g" /etc/php/7.0/fpm/php-fpm.conf
# Change the default pidfile location.
echo "+-- pidfile..."
sed -i "s@pid = .*@pid = $PHP_PID_FILE@g" /etc/php/7.0/fpm/php-fpm.conf
# let's run the darn thing,
# if there is anything to run that is
if [ $# -ne 0 ]; then
# watch the files
watch_logfiles "$PHP_ACCESS_LOG" "$PHP_ERROR_LOG" "$PHP_SLOW_LOG" &
sleep 1
echo "+-- running command:"
echo " $@"
exec "$@"
else
echo "+-- no command specified."
fi