{"id":29251705,"url":"https://github.com/macrat/concron","last_synced_at":"2025-07-04T01:08:13.528Z","repository":{"id":65193717,"uuid":"441906446","full_name":"macrat/concron","owner":"macrat","description":"Cron for Container","archived":false,"fork":false,"pushed_at":"2023-02-25T11:53:06.000Z","size":143,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-20T12:47:42.842Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","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/macrat.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":"2021-12-26T14:11:11.000Z","updated_at":"2022-01-08T10:25:59.000Z","dependencies_parsed_at":"2024-06-20T12:11:42.182Z","dependency_job_id":null,"html_url":"https://github.com/macrat/concron","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/macrat/concron","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macrat%2Fconcron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macrat%2Fconcron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macrat%2Fconcron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macrat%2Fconcron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macrat","download_url":"https://codeload.github.com/macrat/concron/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macrat%2Fconcron/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263427316,"owners_count":23464845,"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":[],"created_at":"2025-07-04T01:08:12.172Z","updated_at":"2025-07-04T01:08:13.509Z","avatar_url":"https://github.com/macrat.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Concron - Cron for Container\n============================\n\n- :heavy_check_mark: Dashboard included.\n- :heavy_check_mark: Prometheus/OpenMetrics exporter included.\n\n\n## Quickstart\n\n### via Docker command\n\nPlace your crontab file to `./crontab`, and run the below command.\n\n``` shell\n$ docker run -v $(pwd)/crontab:/etc/crontab:ro -p 8000:80 ghcr.io/macrat/concron:latest\n```\n\n### via Docker Compose\n\nYou can make `docker-compose.yml` like below,\n\n``` yaml\nversion: \"3\"\n\nservices:\n  concron:\n    image: ghcr.io/macrat/concron:latest\n    environment:\n      CRON_TZ: Asia/Tokyo\n      CONCRON_CRONTAB: |\n        45 */3 * * *  docker run --rm busybox echo \"you can do your task here!\"\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n      - ./cron-files:/etc/cron.d:ro\n    ports:\n      - \"8000:80\"\n    restart: always\n```\n\nAnd then, start via `docker-compose up -d` command.\n\nMore examples are in [examples directory](./examples).\n\n### without container\n\nYou can get Concron binary from [releases page](https://github.com/macrat/concron/releases), or can install using below command.\n\n``` shell\n$ curl -sLf https://raw.github.com/macrat/concron/main/assets/install.sh | sh -\n```\n\nAfter install, you can execute `concron` command.\n\n``` shell\n$ export CONCRON_PATH=/etc/crontab:/etc/cron.d CONCRON_LISTEN=\":8000\"  # These are default values.\n\n$ concron\n```\n\n\n## Image variants\n\n- `latest`, `docker`: Based on [Docker](https://hub.docker.com/_/docker) image. To run Docker containers. This image supports less architectures than others.\n- `busybox`: Minimal image based on [Busybox (glibc)](https://hub.docker.com/_/busybox). To execute simple shell scripts or your own binaries.\n- `slim`: Based on [Debian slim](https://hub.docker.com/_/debian) image. To execute complex scripts or programs that can not execute on busybox image.\n\nAll images are generated by [the same Dockerfile](./Dockerfile).\n\n\n## Crontab\n\nConcron searches crontab files from `/etc/crontab` or under the `/etc/cron.d`.\nThese path is specified by `CONCRON_PATH` environment variable.\nYou can also use `CONCRON_CRONTAB` environment variable instead of file.\n\nIn Windows, Concron searches `C:\\crontab`, `C:\\cron.d`, `C:\\%USERPROFILE%\\crontab`, and `C:\\%USERPROFILE%\\cron.d`.\n\nCrontab file is like below.\n\n``` crontab\nSHELL=/bin/sh\nCRON_TZ=Asia/Tokyo\n\n#    schedule           command\n# |------------| |--------------------|\n   */10 * * * *   echo your-command\n   @daily         echo another command\n```\n\nThis file format is the same as common crontab.\n\nBut, there are two differences about the username column;\n\n1. The username column is omitted in default, regardless of the file path. If you want to change execution user, please set `yes` to `ENABLE_USER_COLUMN` of environment variables.\n2. You can omit the username using `*` instead of an actual username, even if you set `ENABLE_USER_COLUMN`.\n\nTasks that omitted username, will be executed as the same user as the execution user of Concron.\n\nThe crontab file that included username column is like below.\n\n``` crontab\n# This row is important!\nENABLE_USER_COLUMN = yes\n\n#    schedule     user         command\n# |------------| |----| |--------------------|\n   */10 * * * *   root   echo your-command\n   @daily         *      echo another command\n```\n\nThe container has users that have the same name as UID, 1000 to 1010.\nSo you can use specify UID in crontab like `1000` as user name.\n\nConcron uses `/bin/sh -c` in Unix, `%COMSPEC% /C` in Windows, to execute command.\nYou can change shell using `SHELL` and `SHELL_OPTS`.\n`SHELL` is `/bin/sh` or `%COMSPEC%` part, and `SHELL_OPTS` is `-c` or `/C` part.\n\nIn below example, all tasks will executed in the docker container.\n\n``` crontab\n# This is too long and ugly.\n0 0 * * *  /usr/bin/docker run --rm busybox echo hello world\n\n\n# Use docker command as a shell.\nSHELL = /usr/bin/docker\nSHELL_OPTS = run --rm\nPARSE_COMMAND = yes\n\n# This is short and cool!\n0 0 * * *  busybox echo hello world\n```\n\nWhen the `PARSE_COMMAND` option in the above example is enabled, Concron executes comannd as `\"/usr/bin/docker\" \"run\" \"--rm\" \"busybox\" \"echo\" \"hello\" \"world\"` instead of `\"/usr/bin/docker\" \"run\" \"--rm\" \"busybox echo hello world\"`.\nThis option is useful if you want to use non-shell program as `SHELL`.\n\n\n## Dashboard\n\nYou can see dashboard on \u003chttp://localhost:8000\u003e in default.\nThe listen address can change using `CONCRON_LISTEN` environment variable.\n\n![dashboard example](./assets/dashboard.jpg)\n\n\n## Metrics and Logging\n\nThe metrics for Prometheus in the OpenMetrics format is on \u003chttp://localhost:8000/metrics\u003e.\nThis listen address can change using `CONCRON_LISTEN` environment variable as the same as the address of dashboard.\n\nIn default, log level set to `info`.\nIf you want get more information, please set `debug` to `CONCRON_LOGLEVEL`. Or, you can set `warn` or `error` to suppress log.\n\nThe Concron only writes log to the stdout.\nPlease collect them using container engine's log collector or something.\n\n\n## Health check\n\nConcron has 3 endpoints to check the status.\n\n`/healthz` and `/livez` always return 200 OK while Concron running.\n\n`/readyz` returns 200 OK while Concron is running and ready to execute tasks.\nOtherwise, it returns 503 Service Unavailable. For example, before done to load all tasks, or after receive interrupt signal.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacrat%2Fconcron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmacrat%2Fconcron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacrat%2Fconcron/lists"}