Reputation: 83
I have already read and try this
I'm not able to gracefully stop my docker container, the container just stop and kill everything inside instead of run my trap handler, I have been trying to solve this 1 year or more.
This is my entrypoint
ENTRYPOINT ["/home/sdtdserver/user.sh", "/home/sdtdserver/install.sh"]
This is one of the script that do preparations and then continue to other, user.sh
#!/bin/bash
exit_handler() {
# Execute the shutdown commands
echo "[INFO] Stopping 7 Days To Die Server" >> /home/sdtdserver/log/console/sdtdserver-console.log
su-exec sdtdserver /home/sdtdserver/sdtdserver stop
exit
}
set -eu
# Print info
echo "
=======================================================================
USER INFO:
UID: $PUID
GID: $PGID
MORE INFO:
If you have permission problems remember to use same user UID and GID.
Check it with "id" command
If problem persist check:
https://github.com/vinanrra/Docker-7DaysToDie/blob/master/README.md
=======================================================================
"
# Set user and group ID to sdtdserver user
groupmod -o -g "$PGID" sdtdserver > /dev/null 2>&1
usermod -o -u "$PUID" sdtdserver > /dev/null 2>&1
# Locale, Timezone
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 && \
ln -snf /usr/share/zoneinfo/$TimeZone /etc/localtime && echo $TimeZone > /etc/timezone
# Apply owner to the folder to avoid errors
chown -R sdtdserver:sdtdserver /home/sdtdserver
# Start cron
service cron start
# Change user to sdtdserver
su-exec sdtdserver "$@"
# Trap specific signals and forward to the exit handler
trap exit_handler SIGTERM
# Keep script alive to trap SIGTERM
while true; do
sleep 10
done
I think my problem come here: su-exec sdtdserver "$@" - Line 43
I'm using su-exec to execute the swap the user and execute the next scripts as other user, and maybe that's the problem, I have been thinking too to move the user.sh script to somewhere where the script will be executed when it's started without using the entrypoint in the Dockerfile and instead swap to my other script install.sh and even remove the use of su-exec and reformat everything in one script (I don't like this idea tbh)
#!/bin/bash
rootDir=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")
scriptsDir="${rootDir}/scripts"
# Show log function
show_log () {
i="0"
# -F = --follow=name --retry
tail -F /home/sdtdserver/log/console/sdtdserver-console.log
}
test_alert () {
if [ "${TEST_ALERT,,}" == 'yes' ]; then
source $scriptsDir/server_alerts.sh
fi
}
# Check requeriments
# Check if script is missing
if [ ! -f sdtdserver ]; then
source $scriptsDir/check_script.sh
fi
# Check if server have been installed
if [ ! -f serverfiles/DONT_REMOVE.txt ]; then
source $scriptsDir/first_install.sh
fi
# Crontab
echo "# Crontab file" > crontab.txt
if [ "${BACKUP,,}" == 'yes' ]; then
source $scriptsDir/crontab/backup.sh
fi
if [ "${MONITOR,,}" == 'yes' ]; then
source $scriptsDir/crontab/monitor.sh
fi
echo "# Don't remove the empty line at the end of this file. It is required to run the cron job" >> crontab.txt
crontab crontab.txt
rm crontab.txt
# Use of case to avoid errors if used wrong START_MODE
case $START_MODE in
0)
exit
;;
1)
source $scriptsDir/server_start.sh
test_alert
show_log
;;
2)
source $scriptsDir/server_update.sh
exit
;;
3)
source $scriptsDir/server_update.sh
source $scriptsDir/server_start.sh
test_alert
show_log
;;
4)
source $scriptsDir/server_backup.sh
exit
;;
*)
source $scriptsDir/check_startMode.sh
exit
;;
esac
This is top command inside the container:
This is the GitHub branch where I'm doing the testing: fix-exit
First thanks to everyone that try to help me and second I just don't want to copy and paste a code, I want to understand why isn't working, because that's the issue I have, I'm clueless and that's why I'm unable to fix it, even documentation it's appreciated.
Upvotes: 3
Views: 2113
Reputation: 83
The problem was that I wasn't running the script asynchronous, and bash was waiting to end the tail command at the end of install.sh (which was "endless"), here is the part of the code that was changed:
# Change user to sdtdserver
su-exec sdtdserver bash /home/sdtdserver/install.sh &
# If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
# When bash is waiting for an asynchronous command via the wait builtin,
# the reception of a signal for which a trap has been set will cause the 'wait' builtin to return immediately with an exit status greater than 128,
# immediately after which the trap is executed.
wait $!
Also, this man had the same problem, but I didn't know that the tail was the problem.
SIGTERM signal not caught when the last process is tail
Upvotes: 4