Open
Conversation
fix: shellcheck fixes
fix: additional fixes
Replace -S flag with -s flag to run crond in single-user mode. This prevents "can't set groups: Operation not permitted" errors since su-exec already handles the user switching to docker user. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Fix shellcheck warning in entrypoint.sh (add -r flag to read command) - Fix incorrect source URL in Dockerfile (was pointing to alertmanager-discord) - Update docker-compose.yml to version 3.8 and change config volume to read-only - Update GitHub Actions to use latest action versions for better security and features - Remove invalid -s flag from crond CMD (already fixed in previous commit) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
BusyBox v1.37.0 crond doesn't support the -s flag that was attempted in previous versions. This fix adds argument filtering in entrypoint.sh to gracefully handle and remove any -s flags passed to crond, preventing the "unrecognized option: s" error. The solution maintains all previous fixes including proper user switching via su-exec and running crond as root for cron job execution. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
… the CMD instruction. Docker doesn't perform shell variable expansion in the exec form of CMD.
The issue was that BusyBox crond was trying to interpret subdirectories in /opt/crontab as usernames. This fix: - Installs the generated crontab to /etc/crontabs/docker where BusyBox expects user crontab files - Updates the crond command to use /etc/crontabs instead of /opt/crontab - Ensures proper permissions (600) on the crontab file This resolves the "no such user" errors for 'crontab' and 'jobs' directories. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Resolves permission error "cannot create regular file '/etc/crontabs/docker'" by moving crontab files to /opt/crontab/crontabs/ owned by docker user. Changes: - Modified entrypoint.sh to write crontab to /opt/crontab/crontabs/docker - Updated Dockerfile to create crontabs directory with docker:docker ownership - Added SUID bit to /usr/bin/crontab for proper crontab management - Changed CMD to use custom crontabs directory (-c /opt/crontab/crontabs) - Removed root requirement for crond execution (now runs as docker user) - Enhanced documentation with security model and troubleshooting sections - Updated all file path references in CLAUDE.md and README.md Security improvements: - Container now runs crond as non-root docker user - Privilege separation via su-exec (starts as root, drops to docker user) - Better handling of read-only volume mounts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Enhances CI/CD workflows with performance optimizations and security improvements. Changes: - Add Docker build caching for faster builds (cache-from/cache-to with GitHub Actions cache) - Update Discord notification action from v1.12.0 to v1.15.5 - Pin Discord action to commit SHA (b8381b25576cb341b2af39926ab42c5056cc44ed) for security - Applied Discord action update to both build.yml and cleanup.yml workflows Performance Impact: - Build caching reduces rebuild time by reusing layers across workflow runs - Cache stored in GitHub Actions cache with mode=max for optimal storage 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Configures Dependabot to automatically monitor and update dependencies for the docker-crontab project. Configuration: - GitHub Actions: Weekly updates on Mondays at 9am PT - Docker base images: Weekly updates for alpine and docker:dind-alpine - Auto-assign to SimplicityGuy with appropriate labels - Group updates by ecosystem for cleaner PRs Monitoring: - GitHub Actions in workflows directory - Dockerfile base images (docker:dind-alpine, alpine:latest) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements automated Docker base image update workflow that checks for and creates PRs when base images are updated. Features: - Runs weekly on Mondays at 9am UTC - Manual trigger via workflow_dispatch - Checks alpine:latest and docker:dind-alpine for updates - Builds test image to verify compatibility - Creates PR with update details and digests - Auto-assigns to SimplicityGuy with appropriate labels - Discord notifications for workflow status Workflow: 1. Check for base image updates by pulling latest versions 2. Compare digests to detect changes 3. Build test image with new base images 4. Create PR with automated documentation 5. Send Discord notification Security: - Uses commit SHA pinning for create-pull-request action - Test build ensures compatibility before PR creation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Rename "crontab" workflow to "Build" for clarity - Rename "update-dependencies" to "Update Dependencies" for consistency - Use Title Case for all workflow names to match GitHub Actions conventions
- Automatically clean up GitHub Actions caches when PRs are closed - Prevents cache accumulation and keeps repository tidy - Uses concurrency control to prevent duplicate cleanup runs - Continues on deletion errors to ensure workflow completes - Includes 10-minute timeout for safety
Replace old cleanup workflow with improved implementation: - Migrate from snok/container-retention-policy to dataaxiom/ghcr-cleanup-action - Automatic package discovery (no hardcoded package names needed) - More flexible retention policies (keep 2 most recent tagged images) - Better handling of partial and untagged images - Remove Discord notifications to reduce dependencies - Maintain monthly cleanup schedule (15th at midnight UTC) - Add manual workflow_dispatch trigger for on-demand cleanup
- Add support for linux/arm64, linux/arm/v7, and linux/arm/v6 platforms - Increase job timeout from default to 90 minutes to accommodate multi-platform builds with QEMU emulation - Update both Docker Buildx setup and build steps with new platforms This enables the crontab image to run on: - linux/amd64: 64-bit x86 (Intel/AMD) - linux/arm64: 64-bit ARM (Raspberry Pi 4+, AWS Graviton) - linux/arm/v7: 32-bit ARM v7 (Raspberry Pi 2/3) - linux/arm/v6: 32-bit ARM v6 (Raspberry Pi Zero/1) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The cleanup workflow was failing with a 404 error because it was
looking for package "docker-crontab" (derived from repository name)
instead of the actual package name "crontab" (defined in build.yml).
Add explicit package parameter to match IMAGE_NAME from build workflow:
- Build workflow: IMAGE_NAME: ${{ github.actor }}/crontab
- Cleanup workflow: package: crontab
Fixes error:
GET /users/SimplicityGuy/packages/container/docker-crontab/versions
- 404 not found
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add automatic platform detection to download the correct rq binary for each target architecture during Docker builds. This fixes builds for ARM platforms (arm64, armv7, armv6) which were previously failing due to hardcoded x86_64 binary. Changes: - Add TARGETPLATFORM, TARGETOS, TARGETARCH, TARGETVARIANT build args - Implement platform mapping case statement: - linux/amd64 → x86_64-unknown-linux-musl - linux/arm64 → aarch64-unknown-linux-gnu - linux/arm/v7 → armv7-unknown-linux-gnueabihf - linux/arm/v6 → arm-unknown-linux-gnueabi - Add graceful fallback to x86_64 for unknown platforms - Update hadolint ignore to include SC2086 for shell expansion This aligns the Dockerfile with the CI/CD workflow which builds for linux/amd64, linux/arm64, linux/arm/v7, and linux/arm/v6 platforms. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
BusyBox crond does not automatically forward job output to the container's main process. This change redirects all cron job and onstart command output to /proc/1/fd/1 (stdout) and /proc/1/fd/2 (stderr) so that Docker can capture and display job execution logs. Users will now see: - Job start/end messages in docker logs - Command output from executed containers - Real-time job execution feedback 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add update-dependencies.sh script for automated dependency management - Supports Docker base images, rq binary, and GitHub Actions - Includes dry-run mode and automatic backups - Provides colored output and update summaries - Update Dockerfile base images: - Alpine: latest → 3.23 (pinned for stability) - Docker dind: 28.2.2-dind-alpine3.21 → 29.1.3-dind-alpine3.23 - Update GitHub Actions: - actions/checkout: v4 → v6 - Update .gitignore to exclude backup files created by update script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Previous implementation using /proc/1/fd/1 and /proc/1/fd/2 failed because cron jobs run as child processes of crond (not PID 1/tini) and cannot access PID 1's file descriptors. Changed to use standard Unix piping (2>&1 | cat) which properly routes output to Docker's logging system. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The update script was using hardcoded version numbers which caused "Pattern not found" warnings when workflow versions didn't match. Now extracts current versions directly from the workflow file using grep/sed, making the script maintainable and eliminating version sync issues. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Quote IMAGE and CONTAINER variables in generated docker run/exec commands to prevent shell metacharacter injection (entrypoint.sh:77, 90) - Quote ONSTART_COMMAND in onstart execution loop to prevent word-splitting on paths with spaces or metacharacters (entrypoint.sh:242) - Add chmod 700 on crontabs directory so only the docker user can read or modify crontab files (entrypoint.sh:232) - Remove unnecessary #hadolint ignore=DL3007 directives from both FROM lines since pinned version tags are already used (Dockerfile:1, 49) - Remove SC2086 suppression and quote variables in wget/tar commands to address the underlying shell warning (Dockerfile:20, 44-45) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename update-dependencies.sh to update-project.sh with expanded scope: - Add pre-commit autoupdate --freeze support - Scan all workflow files for GitHub Actions updates (not just build.yml) - Add docker build verification step after updates - Add --skip-tests flag and git dirty-tree warning - Use portable sed for macOS/Linux compatibility - Adopt emoji-based section logging style Also rename workflow, update dependabot with security update groups, and fix stale GitHub Action versions in build.yml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
entrypoint.sh: - Fix CRONTAB_FILE evaluated before HOME_DIR is resolved - Fix jq pipeline crash on array-format configs (JSON/YAML) - Reject unsupported @every schedule with clear error - Remove fragile \* escape/unescape round-trip in schedule parsing - Fix [ -a ] test operator to [ -n ] for DOCKER_PORT_2375_TCP check - Add --rm to docker run to prevent container leak on every cron job - Sanitize COMMENT field to strip newlines (injection prevention) - Detect slug collisions and append counter suffix - Write scripts atomically via temp file then mv - Track onstart job PIDs and warn on non-zero exit - Warn when no config file is found - Scope IFS to read command instead of setting globally Dockerfile: - Fix LABEL created using BUILD_DATE build-arg instead of literal $(date) - Fix crond -d 7 (nearly silent) to -d 0 (most verbose) - Add gcompat for ARM glibc-linked rq binary compatibility - Validate DOCKER_GID is numeric before use CI/CD & config: - Fix update-project.yml grep pattern to match actual Dockerfile FROM lines - Fix update-project.yml update detection logic (was inverted) - Pass BUILD_DATE build-arg in build.yml - Remove deprecated docker-compose version key - Update EOL alpine:3.5 to alpine:3.21 in docker-compose and samples - Replace unsupported @every 2m with */2 * * * * in all sample configs - Fix corrupted TOML table key for logrotate entry - Fix TOML sample using ${PWD} instead of named volume - Add backups/ to .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fix: resolve 17 bugs found during comprehensive code review
* fix: resolve multiple bugs found during comprehensive code review - Fix shared-settings merge order so per-job values override shared defaults - Fix parse_schedule failure silently producing broken crontab entries - Fix broken shebang (#\!) in generated job scripts - Add null command guard in make_image_cmd (parity with make_container_cmd) - Add temp file cleanup trap on error during script generation - Clean up intermediate crontab file after copying to crontabs directory - Downgrade actions/checkout@v6 to @v4 (v6 does not exist) - Downgrade docker/metadata-action@v6 to @v5 (v6 does not exist) - Remove -d flag from sample dockerargs (defeats error propagation) - Rename "null" key to "logrotate" in mapping config samples - Replace @every examples with valid cron syntax in README - Fix stale GitLab registry path in README Dockerfile example - Remove invalid --it flag from README dockerargs example - Add depends_on to docker-compose.yml to prevent race condition Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * revert: restore correct GitHub Actions versions (v6 is valid) The previous commit incorrectly downgraded actions/checkout@v6 and docker/metadata-action@v6 — these versions exist and were correct. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * revert: restore -d and --it Docker flags in samples and README These are valid Docker flags (-d for detached, --it for interactive terminal) that were incorrectly removed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: change --it to -it in README dockerargs examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update docs, add badges, fix grammar, document missing config fields - Update README badges to centered div style with Build, License, pre-commit, Docker, Shell, Alpine, and Claude Code badges - Fix grammar: "to all" → "to allow", "probably has" → "probably have", "run on in" → "run in", "images name" → "image name" - Document undocumented config fields: environment, expose, networks, ports, volumes - Document all supported schedule shortcuts: @yearly/@annually, @monthly, @Weekly, @daily/@midnight, @hourly, @random - Remove stale @every reference from CLAUDE.md - Add owner field to cleanup-images workflow (matches discogsography) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: handle empty crontab and fix missing closing quote - Add touch before cat to prevent crash when no valid jobs exist (all jobs skipped due to missing schedule/command/unsupported syntax) - Fix missing closing quote in 'schedule missing' error message Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: quote container name in docker args to handle spaces Mapping config keys like 'map a volume' are injected as the job name by normalize_config. Without quoting, --name map a volume produces a broken docker command. Now generates --name "map a volume". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: Docker Hub API query missing dind-alpine tags, remove dead code - Add name=dind-alpine filter to Docker Hub API query in update-project.sh so dind-alpine tags appear in results (previously, page_size=100 without filtering missed them) - Remove unused skip_next variable and associated dead code from start_app in entrypoint.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: update alpine references from 3.21 to 3.23 Update all sample configs, docker-compose.yml, and README to reference alpine:3.23 which matches the Dockerfile base image. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: sort schedule shortcuts from most to least frequent Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security: add SHA256 checksum verification for rq binary download Add per-platform SHA256 checksums for rq v1.0.2 binaries and verify the download integrity with sha256sum before extraction. This prevents supply chain attacks via compromised releases or MITM. Also add SHELL pipefail directive to builder stage to satisfy hadolint. Closes #17 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add comment noting rq checksums were computed offline Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: replace abandoned rq with yq for config parsing rq (last release: 2019) has been replaced with yq (mikefarah/yq), an actively maintained tool available from Alpine repos. Changes: - Remove entire Dockerfile builder stage (rq download, upx, checksums) - Remove gcompat from release stage (only needed for rq glibc binaries) - Add yq-go to Alpine packages - Update entrypoint.sh to use yq for YAML and TOML conversion - Remove rq version update logic from update-project.sh - Update CLAUDE.md references This also fixes the arm64/arm glibc-on-musl issue since yq is a native Alpine package built for all supported architectures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: route cron job output to docker logs via /proc/1/fd/1 BusyBox crond swallows pipe output (tries to mail it), so the previous 2>&1 | cat approach silently lost all job output. Now redirects to /proc/1/fd/1 and /proc/1/fd/2 (PID 1's stdout/stderr) which is what docker logs reads. Also adds timestamps to job start/end log messages for observability. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: formatted startup table showing scheduled jobs Replace raw crontab dump with a clean table showing schedule, job name, and onstart flag. Also route onstart job output to /proc/1/fd/1 for docker logs visibility, and clean up status messages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: update-project workflow and script for single-stage Dockerfile - Fix update-project.yml: remove builder image grep (builder stage no longer exists), only check docker dind base image - Fix update-project.sh: remove Alpine FROM grep and stale Alpine tag lookup (no standalone Alpine stage anymore) - Fix CLAUDE.md: "multi-stage" → "single-stage", add all platforms Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: update-project workflow now uses update-project.sh script Eliminates duplicate logic between the CI workflow and local script. The workflow now runs the script with --no-backup --skip-tests, checks for git changes, then handles PR creation and Discord notification. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.