dawarich/docker/sidekiq-entrypoint.sh

37 lines
1.2 KiB
Bash
Raw Normal View History

2025-06-09 07:39:25 -04:00
#!/bin/sh
unset BUNDLE_PATH
unset BUNDLE_BIN
set -e
echo "⚠️ Starting Sidekiq in $RAILS_ENV environment ⚠️"
# Parse DATABASE_URL if present, otherwise use individual variables
if [ -n "$DATABASE_URL" ]; then
# Extract components from DATABASE_URL
DATABASE_HOST=$(echo $DATABASE_URL | awk -F[@/] '{print $4}')
DATABASE_PORT=$(echo $DATABASE_URL | awk -F[@/:] '{print $5}')
DATABASE_USERNAME=$(echo $DATABASE_URL | awk -F[:/@] '{print $4}')
DATABASE_PASSWORD=$(echo $DATABASE_URL | awk -F[:/@] '{print $5}')
DATABASE_NAME=$(echo $DATABASE_URL | awk -F[@/] '{print $5}')
else
# Use existing environment variables
DATABASE_HOST=${DATABASE_HOST}
DATABASE_PORT=${DATABASE_PORT}
DATABASE_USERNAME=${DATABASE_USERNAME}
DATABASE_PASSWORD=${DATABASE_PASSWORD}
DATABASE_NAME=${DATABASE_NAME}
fi
# Wait for the database to become available
echo "⏳ Waiting for database to be ready..."
until PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -p "$DATABASE_PORT" -U "$DATABASE_USERNAME" -d "$DATABASE_NAME" -c '\q'; do
>&2 echo "Postgres is unavailable - retrying..."
sleep 2
done
echo "✅ PostgreSQL is ready!"
# run sidekiq
fix(docker): app and sidekiq containers ignore signals Typically, when attempting to stop a container via `docker stop` or `podman stop`, the container engine will send a stop signal (SIGTERM by default) to the container's main process. There are two common ways this can go wrong: 1. The main process is run as PID 1 and doesn't register a signal handler for the stop signal and is consequently ignored 2. The main process is a shell script running a foreground process with no `trap`s and is consequently ignored by the *shell* In either case, because the graceful stop signal is ignored, the container engine will then send a `SIGKILL` to the container process after a default timeout of 10 seconds. This is why some containers can be observed to "hang" when being stopped when they have no other reason to do so. Unlike `SIGTERM` or `SIGINT`, `SIGKILL` is an immediate, ungraceful stop that doesn't give the process time to clean up. There is a fair bit of nuance in how `sh` and `bash` handle signals in different circumstances. The behavior relevant to the second case above and Dawarich's entrypoints in particular is that the shell ignores signals like `SIGTERM` and `SIGINT` when waiting on a foreground job; in this case, that would be: `bundle exec ${@}`. The reason that `SIGINT` is not ignored after pressing `Ctrl+C` while running the docker compose stack is because in that case the shell is **interactive** and the shell *does* respond to `SIGINT` then (c.f. the aforementioned nuance). Thankfully, the fix is simple: `exec` the main process, which causes the server process to *replace* the shell process and directly receive any signals sent. Additionally, the stop signal for the app process should be set to `SIGINT`, as that is the expected signal for graceful shutdown. Sidekiq is fine with either `SIGTERM` or `SIGINT`, which is convenient.
2025-12-06 18:00:35 -05:00
exec bundle exec sidekiq