diff --git a/Dockerfile b/Dockerfile index 71815fe..b0e06e3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,12 +12,14 @@ RUN GOOS=linux GOARCH=$TARGETARCH go build -o explo ./src/main/ FROM python:3.12-alpine -# Install runtime deps: libc compat, ffmpeg, yt-dlp, tzdata +# Install runtime deps: libc compat, ffmpeg, yt-dlp, tzdata, shadow for user management, su-exec for user switching RUN apk add --no-cache \ libc6-compat \ ffmpeg \ yt-dlp \ - tzdata + tzdata \ + shadow \ + su-exec # Install ytmusicapi in the container RUN pip install --no-cache-dir ytmusicapi @@ -33,7 +35,11 @@ COPY src/downloader/youtube_music/search_ytmusic.py . RUN chmod +x /start.sh ./explo -# Can be defined from compose as well +# Can be defined from compose as well ENV WEEKLY_EXPLORATION_SCHEDULE="15 0 * * 2" +# Default PUID and PGID +ENV PUID=1000 +ENV PGID=1000 + CMD ["/start.sh"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index c61bbd0..05fd6a7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,6 +10,8 @@ services: # - $PLAYLIST_DIR:$PLAYLIST_DIR # for MPD. Both paths should be as defined in .env (e.g /my/playlists/:/my/playlists/) environment: - TZ=UTC # Change this to the timezone set in ListenBrainz (default is UTC) + - PUID=1000 # User ID for file permissions (optional, defaults to 1000) + - PGID=1000 # Group ID for file permissions (optional, defaults to 1000) - WEEKLY_EXPLORATION_SCHEDULE=15 00 * * 2 # Runs weekly, every Tuesday 15 minutes past midnight - WEEKLY_EXPLORATION_FLAGS= # Run weekly exploration with default settings diff --git a/docker/start.sh b/docker/start.sh index 4db84c3..e472b49 100644 --- a/docker/start.sh +++ b/docker/start.sh @@ -1,9 +1,45 @@ #!/bin/sh + +# Handle PUID/PGID +if [ "$PUID" != "0" ] && [ "$PGID" != "0" ]; then + echo "[setup] Setting up user with PUID=$PUID and PGID=$PGID" + + # Create group if it doesn't exist + if ! getent group explo > /dev/null 2>&1; then + groupadd -g "$PGID" explo + fi + + # Create user if it doesn't exist + if ! getent passwd explo > /dev/null 2>&1; then + useradd -u "$PUID" -g "$PGID" -d /opt/explo -s /bin/sh explo + fi + + # Ensure explo user owns the working directory and data directory + chown -R explo:explo /opt/explo + [ -d /data ] && chown -R explo:explo /data + + # If running as non-root, exec as the explo user + if [ "$(id -u)" = "0" ]; then + exec su-exec explo "$0" "$@" + fi +fi + echo "[setup] Initializing cron jobs..." +# Determine which user to run cron jobs as +CRON_USER="root" +if [ "$PUID" != "0" ] && [ "$PGID" != "0" ]; then + CRON_USER="explo" + # Create crontab directory for explo user if it doesn't exist + mkdir -p /var/spool/cron/crontabs + touch "/var/spool/cron/crontabs/$CRON_USER" + chown "$CRON_USER:$CRON_USER" "/var/spool/cron/crontabs/$CRON_USER" +fi + if [ -n "$CRON_SCHEDULE" ]; then - echo "$CRON_SCHEDULE apk add --upgrade yt-dlp && cd /opt/explo && ./explo >> /proc/1/fd/1 2>&1" > /etc/crontabs/root - chmod 600 /etc/crontabs/root + cmd="apk add --upgrade yt-dlp && cd /opt/explo && ./explo >> /proc/1/fd/1 2>&1" + echo "$CRON_SCHEDULE $cmd" > "/var/spool/cron/crontabs/$CRON_USER" + chmod 600 "/var/spool/cron/crontabs/$CRON_USER" echo "[setup] Registered single CRON_SCHEDULE job: $CRON_SCHEDULE" crond -f -l 2 fi @@ -23,13 +59,13 @@ for var in $(env | grep "_SCHEDULE=" | cut -d= -f1); do # Default: just run explo if flags are empty cmd="apk add --upgrade yt-dlp && cd /opt/explo && ./explo $flags >> /proc/1/fd/1 2>&1" - echo "$schedule $cmd" >> /etc/crontabs/root + echo "$schedule $cmd" >> "/var/spool/cron/crontabs/$CRON_USER" echo "[setup] Registered job: $job" echo " Schedule: $schedule" echo " Command : ./explo $flags" done -chmod 600 /etc/crontabs/root +chmod 600 "/var/spool/cron/crontabs/$CRON_USER" echo "[setup] Starting cron..." crond -f -l 2 \ No newline at end of file