{"id":18731368,"url":"https://github.com/christopher-besch/docker_cron","last_synced_at":"2026-04-09T16:54:50.007Z","repository":{"id":57836519,"uuid":"528088512","full_name":"christopher-besch/docker_cron","owner":"christopher-besch","description":"Scheduling container tasks with docker-compose.","archived":false,"fork":false,"pushed_at":"2024-11-12T16:26:28.000Z","size":27,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-17T05:02:56.070Z","etag":null,"topics":["containerization","cron","docker","docker-compose","scheduling"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/chrisbesch/docker_cron","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christopher-besch.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}},"created_at":"2022-08-23T17:06:43.000Z","updated_at":"2024-11-12T16:26:32.000Z","dependencies_parsed_at":"2025-02-19T05:39:41.678Z","dependency_job_id":null,"html_url":"https://github.com/christopher-besch/docker_cron","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/christopher-besch/docker_cron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopher-besch%2Fdocker_cron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopher-besch%2Fdocker_cron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopher-besch%2Fdocker_cron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopher-besch%2Fdocker_cron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christopher-besch","download_url":"https://codeload.github.com/christopher-besch/docker_cron/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christopher-besch%2Fdocker_cron/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270807934,"owners_count":24649346,"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","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["containerization","cron","docker","docker-compose","scheduling"],"created_at":"2024-11-07T14:57:27.207Z","updated_at":"2026-04-09T16:54:49.995Z","avatar_url":"https://github.com/christopher-besch.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# docker_cron\nScheduling container tasks with docker-compose.\n\nI also wrote [an article](https://chris-besch.com/articles/technical_compromises/) about this project.\n\nDocker_cron is a docker container used to control as many other containers as you like.\n```yaml\nversion: \"3.9\"\n\nservices:\n    example:\n        image: chrisbesch/docker_cron_example\n        environment:\n            # this container's task runs every day at 03:00\n            - \"CRON_TIME=0 3 * * *\"\n            # it receives a HUP signal (since this is the default, this env variable can be omitted)\n            # all signals here: https://github.com/fsouza/go-dockerclient/blob/01804dec8a84d0a77e63611f2b62d33e9bb2b64a/signal.go\n            - CRON_SIGNAL=0x1\n      \n    docker_cron:\n        image: chrisbesch/docker_cron\n        volumes:\n            - \"/var/run/docker.sock:/var/run/docker.sock:rw\"\n        environment:\n            - TZ=Europe/Berlin\n```\nThis example can be found [here](https://github.com/christopher-besch/docker_cron/tree/main/example).\n\n## The `docker_cron` container\nAll you have to do is add the `docker_cron` container to your `docker-compose.yaml`, give it read/write access to the docker socket and specify your timezone.\nNow all containers that defined the `CRON_TIME` environment variable [receive a HUP signal](#the-hup-signal) whenever [their `CRON_TIME`](#cron_time) matches the current minute.\n(This magic is performed by [docker-gen](https://github.com/nginx-proxy/docker-gen).)\n\n## `CRON_TIME`\n`CRON_TIME` consists out of five fields separated by \u003cblank\u003e characters:\n1. Minute [0,59]\n2. Hour [0,23]\n3. Day of the month [1,31]\n4. Month of the year [1,12]\n5. Day of the week ([0,6] with 0=Sunday)\nEach field can also be an `*`, meaning all valid values.\nThis is from an [extract from `man crontab`](#man-crontab-extract).\n\n## The HUP Signal\nWhen the current minute matches the `CRON_TIME` of a container, that container receives a HUP signal.\nThis is equivalent to `docker kill -s HUP \u003ccontainer name\u003e` (which can also be used to force running your task for debugging).\nThe container is not restarted or otherwise nonconsensually touched.\nIt's your container's job to trap this HUP signal and do with it as it likes.\nHere is a bash example doing this:\n```bash\n#!/bin/bash\ntrap 'bash /actual_job.sh' HUP\nwhile :; do\n    sleep 10 \u0026 wait ${!}\ndone\n```\nMake sure that you don't `set -e` because that causes the trap to exit the script.\n\nAnd here is a python example:\n```python\n#!/bin/python3\n\nimport signal\nimport os\n\ndef actual_job(sig, frame):\n    del sig, frame\n    print(\"doing something very important...\")\n\nsignal.signal(signal.SIGHUP, actual_job)\nprint(f\"listening for SIGHUP, test with: kill -s HUP {os.getpid()}\")\nwhile True:\n    signal.pause()\n```\n\n## Sending Other Signals\nIf you want your container to receive a different signal, set the `CRON_SIGNAL` environment variable of the target container to the integer that identifies your desired signal.\nUse this table to reference the correct one (from [here](https://github.com/fsouza/go-dockerclient/blob/01804dec8a84d0a77e63611f2b62d33e9bb2b64a/signal.go)):\n| Signal    | int    |\n|:--------- |:------ |\n| SIGABRT   | `0x6`  |\n| SIGALRM   | `0xe`  |\n| SIGBUS    | `0x7`  |\n| SIGCHLD   | `0x11` |\n| SIGCLD    | `0x11` |\n| SIGCONT   | `0x12` |\n| SIGFPE    | `0x8`  |\n| SIGHUP    | `0x1`  |\n| SIGILL    | `0x4`  |\n| SIGINT    | `0x2`  |\n| SIGIO     | `0x1d` |\n| SIGIOT    | `0x6`  |\n| SIGKILL   | `0x9`  |\n| SIGPIPE   | `0xd`  |\n| SIGPOLL   | `0x1d` |\n| SIGPROF   | `0x1b` |\n| SIGPWR    | `0x1e` |\n| SIGQUIT   | `0x3`  |\n| SIGSEGV   | `0xb`  |\n| SIGSTKFLT | `0x10` |\n| SIGSTOP   | `0x13` |\n| SIGSYS    | `0x1f` |\n| SIGTERM   | `0xf`  |\n| SIGTRAP   | `0x5`  |\n| SIGTSTP   | `0x14` |\n| SIGTTIN   | `0x15` |\n| SIGTTOU   | `0x16` |\n| SIGUNUSED | `0x1f` |\n| SIGURG    | `0x17` |\n| SIGUSR1   | `0xa`  |\n| SIGUSR2   | `0xc`  |\n| SIGVTALRM | `0x1a` |\n| SIGWINCH  | `0x1c` |\n| SIGXCPU   | `0x18` |\n| SIGXFSZ   | `0x19` |\n\n# `man crontab` extract\n```\n1. Minute [0,59]\n\n2. Hour [0,23]\n\n3. Day of the month [1,31]\n\n4. Month of the year [1,12]\n\n5. Day of the week ([0,6] with 0=Sunday)\n\nEach of these patterns can be either an \u003casterisk\u003e (meaning all valid values), an  ele‐\nment, or a list of elements separated by \u003ccomma\u003e characters. An element shall be either\na number or two numbers separated by a \u003chyphen-minus\u003e (meaning an inclusive range). The\nspecification of days can be made by two fields (day of the month and day of the week).\nIf month, day of month, and day of week are all \u003casterisk\u003e characters, every day  shall\nbe matched. If either the month or day of month is specified as an element or list, but\nthe day of week is an \u003casterisk\u003e, the month and day of month fields shall  specify  the\ndays that match. If both month and day of month are specified as an \u003casterisk\u003e, but day\nof week is an element or list, then only the specified days of the week match. Finally,\nif  either the month or day of month is specified as an element or list, and the day of\nweek is also specified as an element or list, then any day matching  either  the  month\nand day of month, or the day of week, shall be matched.\n```\n\n# Building Multiarch Docker Image\n```\ndocker build --platform linux/amd64 -t chrisbesch/docker_cron:amd64 . \u0026\u0026\ndocker build --platform linux/arm64 -t chrisbesch/docker_cron:arm64 . \u0026\u0026\ndocker push chrisbesch/docker_cron:amd64 \u0026\u0026\ndocker push chrisbesch/docker_cron:arm64 \u0026\u0026\ndocker manifest create chrisbesch/docker_cron \\\n    chrisbesch/docker_cron:amd64 \\\n    chrisbesch/docker_cron:arm64 \u0026\u0026\ndocker manifest inspect chrisbesch/docker_cron \u0026\u0026\ndocker manifest push chrisbesch/docker_cron\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopher-besch%2Fdocker_cron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristopher-besch%2Fdocker_cron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristopher-besch%2Fdocker_cron/lists"}