{"id":21698642,"url":"https://github.com/theohbrothers/docker-alpine-cron","last_synced_at":"2025-07-01T16:08:26.970Z","repository":{"id":62291132,"uuid":"150846508","full_name":"theohbrothers/docker-alpine-cron","owner":"theohbrothers","description":"Dockerized alpine with busybox crond and useful tools. 🐳","archived":false,"fork":false,"pushed_at":"2025-06-06T01:57:55.000Z","size":161,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-21T10:41:57.264Z","etag":null,"topics":["alpine","buildx","busybox","cron","crond","docker","generate-dockerimagevariants"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/theohbrothers.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-09-29T09:08:10.000Z","updated_at":"2025-06-06T01:56:05.000Z","dependencies_parsed_at":"2024-03-02T18:26:42.205Z","dependency_job_id":"b8357a2a-0f59-4987-92c7-a0cfc022e070","html_url":"https://github.com/theohbrothers/docker-alpine-cron","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/theohbrothers/docker-alpine-cron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theohbrothers%2Fdocker-alpine-cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theohbrothers%2Fdocker-alpine-cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theohbrothers%2Fdocker-alpine-cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theohbrothers%2Fdocker-alpine-cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/theohbrothers","download_url":"https://codeload.github.com/theohbrothers/docker-alpine-cron/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/theohbrothers%2Fdocker-alpine-cron/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262996405,"owners_count":23396903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpine","buildx","busybox","cron","crond","docker","generate-dockerimagevariants"],"created_at":"2024-11-25T19:35:44.319Z","updated_at":"2025-07-01T16:08:26.946Z","avatar_url":"https://github.com/theohbrothers.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docker-alpine-cron\n\n[![github-actions](https://github.com/theohbrothers/docker-alpine-cron/actions/workflows/ci-master-pr.yml/badge.svg?branch=master)](https://github.com/theohbrothers/docker-alpine-cron/actions/workflows/ci-master-pr.yml)\n[![github-release](https://img.shields.io/github/v/release/theohbrothers/docker-alpine-cron?style=flat-square)](https://github.com/theohbrothers/docker-alpine-cron/releases/)\n[![docker-image-size](https://img.shields.io/docker/image-size/theohbrothers/docker-alpine-cron/latest)](https://hub.docker.com/r/theohbrothers/docker-alpine-cron)\n\nDockerized alpine with busybox crond and useful tools.\n\nPackages included for all images: `curl`, `wget`\n\n## Tags\n\n| Tag | Dockerfile Build Context |\n|:-------:|:---------:|\n| `:3.20`, `:latest` | [View](variants/3.20) |\n| `:3.20-mysqlclient` | [View](variants/3.20-mysqlclient) |\n| `:3.20-openssl` | [View](variants/3.20-openssl) |\n| `:3.20-mysqlclient-openssl` | [View](variants/3.20-mysqlclient-openssl) |\n| `:3.17`, `:latest` | [View](variants/3.17) |\n| `:3.17-mysqlclient` | [View](variants/3.17-mysqlclient) |\n| `:3.17-openssl` | [View](variants/3.17-openssl) |\n| `:3.17-mysqlclient-openssl` | [View](variants/3.17-mysqlclient-openssl) |\n| `:3.15`, `:latest` | [View](variants/3.15) |\n| `:3.15-mysqlclient` | [View](variants/3.15-mysqlclient) |\n| `:3.15-openssl` | [View](variants/3.15-openssl) |\n| `:3.15-mysqlclient-openssl` | [View](variants/3.15-mysqlclient-openssl) |\n| `:3.12`, `:latest` | [View](variants/3.12) |\n| `:3.12-mysqlclient` | [View](variants/3.12-mysqlclient) |\n| `:3.12-openssl` | [View](variants/3.12-openssl) |\n| `:3.12-mysqlclient-openssl` | [View](variants/3.12-mysqlclient-openssl) |\n\n## Usage\n\nExample 1: Create one cron that runs as `root`\n\n```sh\ndocker run -it \\\n    -e CRON='* * * * * /bin/echo \"hello\"' \\\n    theohbrothers/docker-alpine-cron:3.20\n```\n\nExample 2: Create two crons that run as `root`\n\n```sh\ndocker run -it \\\n    -e CRON='* * * * * /bin/echo \"hello\"\\n* * * * * /bin/echo \"world\"' \\\n    theohbrothers/docker-alpine-cron:3.20\n```\n\nExample 3: Create two crons that run as UID `3000` and GID `4000`\n\n```sh\ndocker run -it \\\n    -e CRON='* * * * * /bin/echo \"hello\"\\n* * * * * /bin/echo \"world\"' \\\n    -e CRON_UID=3000 \\\n    -e CRON_GID=4000 \\\n    theohbrothers/docker-alpine-cron:3.20\n```\n\n### Environment variables\n\n| Name | Default value | Description\n|:-------:|:---------------:|:---------:|\n| `CRON` | '' | Required: The cron expression. For multiple cron expressions, use `\\n`. Use [crontab.guru](https://crontab.guru/) to customize crons. This will be set as the content of the crontab at `/etc/crontabs/$CRON_USER`\n| `CRON_UID` | `0` | Optional: The UID of the user that the cron should run under. Default is `0` which is `root`\n| `CRON_GID` | `0` | Optional: The GID of the user that the cron should run under. Default is `0` which is `root`\n\n### Entrypoint: `docker-entrypoint.sh`\n\n1. A `/etc/environment` file is created at the beginning of the entrypoint script, which makes environment variables available to everyone, including crond.\n1. A user of `CRON_UID` is created if it does not exist.\n1. A group of `CRON_GID` is created if it does not exist.\n1. The user of `CRON_UID` is added to the group of `CRON_GID` if membership does not exist.\n1. Crontab is created in `/etc/crontabs/\u003cCRON_USER\u003e`\n\n### Secrets\n\nSince a `/etc/environment` file is created automatically to make environment variables available to every cron, any sensitive environment variables will get written to the disk. To avoid that:\n\n1. Add [shell functions like this](https://github.com/startersclan/docker-hlstatsxce-daemon/blob/v1.6.19/variants/alpine/cron/docker-entrypoint.sh#L7-L58) at the beginning of your cron-called script\n1. Optional: Specify the secrets folder by using environment variable `ENV_SECRETS_DIR`. By default, its value is `/run/secrets`\n1. Declare environment variables using syntax `MY_ENV_VAR=DOCKER-SECRET:my_docker_secret_name`, where `my_docker_secret_name` is the secret mounted on `$ENV_SECRETS_DIR/my_docker_secret_name`\n1. When the cron script is run, the env var `MY_ENV_VAR` gets populated with the contents of the secret file `$ENV_SECRETS_DIR/my_docker_secret_name`\n\n## FAQ\n\n### Q: Why use a cron container?\n\nThis image is only needed if there is no container orchestrator (E.g. Docker in standalone mode), or if there is a container orchestrator but without a cron scheduler (E.g. Docker in Swarm mode).\n\nIf your orchestrator already provides an external scheduler (E.g. Kubernetes via `CronJob`), there's no need to use this image.\n\n### Q: Why use `CRON` environment variable? Just use `crontab -`\n\nRight. If the cron command is complex, and there is no need for customizing `CRON_UID` and `CRON_GID`, it is better to skip this image altogether and simply write everything in the entrypoint of the container manifest. For example, in Compose:\n\n```yaml\nversion: '2.2'\nservices:\n  some-cron:\n    image: alpine\n    tty: true\n    entrypoint:\n      - /bin/sh\n    command:\n      - -c\n      - |\n          set -eu\n\n          crontab - \u003c\u003c'EOF'\n          * * * * * /bin/echo \"My super 'complex' cron command with quotes is better written in shell\"\n          EOF\n\n          exec crond -f\n```\n\n### Q: My cron is not running!\n\n- Use `docker logs` to check whether `crond` has spit out any messages about the syntax of your cron\n- If bind-mouting your own crontab in `/etc/crontabs`, ensure:\n  - the crontab is owned by `root:root` with `0600` permissions. See [here](https://unix.stackexchange.com/questions/642827/how-to-run-a-cronjob-as-a-non-root-user-in-a-docker-container-for-alpine-linux)\n  - the crontab has a newline at the end of the file\n\n## Development\n\nRequires Windows `powershell` or [`pwsh`](https://github.com/PowerShell/PowerShell).\n\n```powershell\n# Install Generate-DockerImageVariants module: https://github.com/theohbrothers/Generate-DockerImageVariants\nInstall-Module -Name Generate-DockerImageVariants -Repository PSGallery -Scope CurrentUser -Force -Verbose\n\n# Edit ./generate templates\n\n# Generate the variants\nGenerate-DockerImageVariants .\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheohbrothers%2Fdocker-alpine-cron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheohbrothers%2Fdocker-alpine-cron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheohbrothers%2Fdocker-alpine-cron/lists"}