mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-04-20 05:51:21 -04:00
Hey, made the tweaks we discussed, plus a couple related fixes :) - Removed APP_ENV entirely. All dev-specific functionality is enabled via `DEBUG: true` env var - Set secure cookie handling to false by default, added to the readme to enable if exclusively using HTTPS connection - Fixed healthcheck potentially not working with auth enabled - Removed APP_ENV from docker compose files and made sure app.db lines are included in all versions. APP_ENV in people's existing composes should get ignored entirely and will be put on the default env, so no issues when updating.
190 lines
5.7 KiB
Bash
190 lines
5.7 KiB
Bash
#!/bin/bash
|
|
LOG_DIR=${LOG_ROOT:-/var/log/}/cwa-book-downloader
|
|
mkdir -p $LOG_DIR
|
|
LOG_FILE=${LOG_DIR}/cwa-bd_entrypoint.log
|
|
|
|
# Cleanup any existing files or folders in the log directory
|
|
rm -rf $LOG_DIR/*
|
|
|
|
(
|
|
if [ "$USING_TOR" = "true" ]; then
|
|
./tor.sh
|
|
fi
|
|
)
|
|
|
|
exec 3>&1 4>&2
|
|
exec > >(tee -a $LOG_FILE) 2>&1
|
|
echo "Starting entrypoint script"
|
|
echo "Log file: $LOG_FILE"
|
|
set -e
|
|
|
|
# Print build version
|
|
echo "Build version: $BUILD_VERSION"
|
|
echo "Release version: $RELEASE_VERSION"
|
|
|
|
# Configure timezone
|
|
if [ "$TZ" ]; then
|
|
echo "Setting timezone to $TZ"
|
|
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
|
fi
|
|
|
|
# Set UID if not set
|
|
if [ -z "$UID" ]; then
|
|
UID=1000
|
|
fi
|
|
|
|
# Set GID if not set
|
|
if [ -z "$GID" ]; then
|
|
GID=100
|
|
fi
|
|
|
|
if ! getent group "$GID" >/dev/null; then
|
|
echo "Adding group $GID with name appuser"
|
|
groupadd -g "$GID" appuser
|
|
fi
|
|
|
|
# Create user if it doesn't exist
|
|
if ! id -u "$UID" >/dev/null 2>&1; then
|
|
echo "Adding user $UID with name appuser"
|
|
useradd -u "$UID" -g "$GID" -d /app -s /sbin/nologin appuser
|
|
fi
|
|
|
|
# Get username for the UID (whether we just created it or it existed)
|
|
USERNAME=$(getent passwd "$UID" | cut -d: -f1)
|
|
echo "Username for UID $UID is $USERNAME"
|
|
|
|
test_write() {
|
|
folder=$1
|
|
test_file=$folder/calibre-web-automated-book-downloader_TEST_WRITE
|
|
mkdir -p $folder
|
|
(
|
|
echo 0123456789_TEST | sudo -E -u "$USERNAME" HOME=/app tee $test_file > /dev/null
|
|
)
|
|
FILE_CONTENT=$(cat $test_file || echo "")
|
|
rm -f $test_file
|
|
[ "$FILE_CONTENT" = "0123456789_TEST" ]
|
|
result=$?
|
|
if [ $result -eq 0 ]; then
|
|
result_text="true"
|
|
else
|
|
result_text="false"
|
|
fi
|
|
echo "Test write to $folder by $USERNAME: $result_text"
|
|
return $result
|
|
}
|
|
|
|
make_writable() {
|
|
folder=$1
|
|
set +e
|
|
test_write $folder
|
|
is_writable=$?
|
|
set -e
|
|
if [ $is_writable -eq 0 ]; then
|
|
echo "Folder $folder is writable, no need to change ownership"
|
|
else
|
|
echo "Folder $folder is not writable, changing ownership"
|
|
change_ownership $folder
|
|
chmod g+r,g+w $folder || echo "Failed to change group permissions for ${folder}, continuing..."
|
|
fi
|
|
test_write $folder || echo "Failed to test write to ${folder}, continuing..."
|
|
}
|
|
|
|
# Ensure proper ownership of application directories
|
|
change_ownership() {
|
|
folder=$1
|
|
mkdir -p $folder
|
|
echo "Changing ownership of $folder to $USERNAME:$GID"
|
|
chown -R "${UID}" "${folder}" || echo "Failed to change user ownership for ${folder}, continuing..."
|
|
chown -R ":${GID}" "${folder}" || echo "Failed to change group ownership for ${folder}, continuing..."
|
|
}
|
|
|
|
change_ownership /app
|
|
change_ownership /var/log/cwa-book-downloader
|
|
change_ownership /tmp/cwa-book-downloader
|
|
|
|
# Test write to all folders
|
|
make_writable /cwa-book-ingest
|
|
|
|
# Set the command to run based on DEBUG setting
|
|
# DEBUG=true uses Flask dev server, otherwise uses gunicorn for production
|
|
is_debug=$(echo "$DEBUG" | tr '[:upper:]' '[:lower:]')
|
|
if [ "$is_debug" = "true" ]; then
|
|
command="python3 app.py"
|
|
else
|
|
# Use geventwebsocket worker for SocketIO + WebSocket compatibility
|
|
# This special worker class handles WebSocket upgrades properly
|
|
# --workers 1: SocketIO requires sticky sessions, use 1 worker or configure sticky sessions
|
|
# -t 300: 300 second timeout for long-running requests
|
|
command="gunicorn --worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker --workers 1 -t 300 -b ${FLASK_HOST:-0.0.0.0}:${FLASK_PORT:-8084} app:app"
|
|
fi
|
|
|
|
# If DEBUG and not using an external bypass
|
|
if [ "$DEBUG" = "true" ] && [ "$USING_EXTERNAL_BYPASSER" != "true" ]; then
|
|
set +e
|
|
set -x
|
|
echo "vvvvvvvvvvvv DEBUG MODE vvvvvvvvvvvv"
|
|
echo "Starting Xvfb for debugging"
|
|
python3 -c "from pyvirtualdisplay import Display; Display(visible=False, size=(1440,1880)).start()"
|
|
id
|
|
free -h
|
|
uname -a
|
|
ulimit -a
|
|
df -h /tmp
|
|
env | sort
|
|
mount
|
|
cat /proc/cpuinfo
|
|
echo "==========================================="
|
|
echo "Debugging Chrome itself"
|
|
chromium --version
|
|
mkdir -p /tmp/chrome_crash_dumps
|
|
timeout --preserve-status 5s chromium \
|
|
--headless=new \
|
|
--no-sandbox \
|
|
--disable-gpu \
|
|
--enable-logging --v=1 --log-level=0 \
|
|
--log-file=/tmp/chrome_entrypoint_test.log \
|
|
--crash-dumps-dir=/tmp/chrome_crash_dumps \
|
|
< /dev/null
|
|
EXIT_CODE=$?
|
|
echo "Chrome exit code: $EXIT_CODE"
|
|
ls -lh /tmp/chrome_entrypoint_test.log
|
|
ls -lh /tmp/chrome_crash_dumps
|
|
if [[ "$EXIT_CODE" -ne 0 && "$EXIT_CODE" -le 127 ]]; then
|
|
echo "Chrome failed to start. Lets trace it"
|
|
apt-get update && apt-get install -y strace
|
|
timeout --preserve-status 10s strace -f -o "/tmp/chrome_strace.log" chromium \
|
|
--headless=new \
|
|
--no-sandbox \
|
|
--version \
|
|
< /dev/null
|
|
EXIT_CODE=$?
|
|
echo "Strace exit code: $EXIT_CODE"
|
|
echo "Strace log:"
|
|
cat /tmp/chrome_strace.log
|
|
fi
|
|
|
|
pkill -9 -f Xvfb
|
|
pkill -9 -f chromium
|
|
sleep 1
|
|
ps aux
|
|
set +x
|
|
set -e
|
|
echo "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
|
|
fi
|
|
|
|
# Hacky way to verify /tmp has at least 1MB of space and is writable/readable
|
|
echo "Verifying /tmp has enough space"
|
|
rm -f /tmp/test.cwa-bd
|
|
for i in {1..150000}; do printf "%04d\n" $i; done > /tmp/test.cwa-bd
|
|
sum=$(python3 -c "print(sum(int(l.strip()) for l in open('/tmp/test.cwa-bd').readlines()))")
|
|
[ "$sum" == 11250075000 ] && echo "Success: /tmp is writable" || (echo "Failure: /tmp is not writable" && exit 1)
|
|
rm /tmp/test.cwa-bd
|
|
|
|
echo "Running command: '$command' as '$USERNAME' (debug=$is_debug)"
|
|
|
|
# Stop logging
|
|
exec 1>&3 2>&4
|
|
exec 3>&- 4>&-
|
|
|
|
exec sudo -E -u "$USERNAME" HOME=/app $command
|