├── .gitignore ├── alpine ├── Dockerfile ├── start-cron └── README.md ├── README.md ├── debian ├── Dockerfile ├── start-cron └── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | # Jetbrains 2 | *.iml 3 | .idea/ 4 | 5 | # Vagrant 6 | .vagrant/ 7 | -------------------------------------------------------------------------------- /alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN set -ex \ 4 | # install bash 5 | && apk add --no-cache \ 6 | bash \ 7 | # making logging pipe 8 | && mkfifo -m 0666 /var/log/cron.log \ 9 | && ln -s /var/log/cron.log /var/log/crond.log 10 | 11 | COPY start-cron /usr/sbin 12 | 13 | CMD ["start-cron"] 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cron-docker-image 2 | 3 | [![Docker Automated buil](https://img.shields.io/docker/automated/renskiy/cron.svg)](https://hub.docker.com/r/renskiy/cron/) 4 | 5 | Docker images to run `cron` inside the Docker container 6 | 7 | ## Tags 8 | 9 | * [debian, latest](debian) (~170Mb) 10 | * [alpine](alpine) (~8Mb) 11 | -------------------------------------------------------------------------------- /debian/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:latest 2 | 3 | RUN set -ex \ 4 | && apt-get clean && apt-get update \ 5 | # install cron 6 | && apt-get install -y cron \ 7 | && rm -rf /var/lib/apt/lists/* \ 8 | # making logging pipe 9 | && mkfifo --mode 0666 /var/log/cron.log \ 10 | # make pam_loginuid.so optional for cron 11 | # see https://github.com/docker/docker/issues/5663#issuecomment-42550548 12 | && sed --regexp-extended --in-place \ 13 | 's/^session\s+required\s+pam_loginuid.so$/session optional pam_loginuid.so/' \ 14 | /etc/pam.d/cron 15 | 16 | COPY start-cron /usr/sbin 17 | 18 | CMD ["start-cron"] 19 | -------------------------------------------------------------------------------- /alpine/start-cron: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # setting user for additional cron jobs 4 | case $1 in 5 | -u=*|--user=*) 6 | crontab_user="-u ${1#*=}" 7 | shift 8 | ;; 9 | -u|--user) 10 | crontab_user="-u $2" 11 | shift 2 12 | ;; 13 | -*) 14 | echo "Unknown option: ${1%=*}" > /dev/stderr 15 | exit 1 16 | ;; 17 | *) 18 | crontab_user="" 19 | ;; 20 | esac 21 | 22 | # adding additional cron jobs passed by arguments 23 | # every job must be a single quoted string and have standard crontab format, 24 | # e.g.: start-cron --user user "0 \* \* \* \* env >> /var/log/cron.log 2>&1" 25 | { for cron_job in "$@"; do echo -e ${cron_job}; done } \ 26 | | sed --regexp-extended 's/\\(.)/\1/g' \ 27 | | crontab ${crontab_user} - 28 | 29 | # start cron 30 | default_crontabs_dir=/etc/crontabs 31 | crond -L /var/log/cron.log -c ${CRONTABS_DIR:-$default_crontabs_dir} 32 | 33 | # trap SIGINT and SIGTERM signals and gracefully exit 34 | trap "echo \"stopping cron\"; kill \$!; exit" SIGINT SIGTERM 35 | 36 | # start "daemon" 37 | while true 38 | do 39 | cat /var/log/cron.log & wait $! 40 | done 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Rinat Khabibiev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /debian/start-cron: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # make link to custom location of /etc/cron.d if provided 4 | if [ "${CRON_PATH}" ]; then 5 | rm -rf /etc/cron.d 6 | ln -sfTv "${CRON_PATH}" /etc/cron.d 7 | fi 8 | 9 | # remove write permission for (g)roup and (o)ther (required by cron) 10 | chmod -R go-w /etc/cron.d 11 | 12 | # setting user for additional cron jobs 13 | case $1 in 14 | -u=*|--user=*) 15 | crontab_user="-u ${1#*=}" 16 | shift 17 | ;; 18 | -u|--user) 19 | crontab_user="-u $2" 20 | shift 2 21 | ;; 22 | -*) 23 | echo "Unknown option: ${1%=*}" > /dev/stderr 24 | exit 1 25 | ;; 26 | *) 27 | crontab_user="" 28 | ;; 29 | esac 30 | 31 | # adding additional cron jobs passed by arguments 32 | # every job must be a single quoted string and have standard crontab format, 33 | # e.g.: start-cron --user user "0 \* \* \* \* env >> /var/log/cron.log 2>&1" 34 | { for cron_job in "$@"; do echo -e ${cron_job}; done } \ 35 | | sed --regexp-extended 's/\\(.)/\1/g' \ 36 | | crontab ${crontab_user} - 37 | 38 | # update default values of PAM environment variables (used by CRON scripts) 39 | env | while read -r line; do # read STDIN by line 40 | # split LINE by "=" 41 | IFS="=" read var val <<< ${line} 42 | # remove existing definition of environment variable, ignoring exit code 43 | sed --in-place "/^${var}[[:blank:]=]/d" /etc/security/pam_env.conf || true 44 | # append new default value of environment variable 45 | echo "${var} DEFAULT=\"${val}\"" >> /etc/security/pam_env.conf 46 | done 47 | 48 | # start cron 49 | service cron start 50 | 51 | # trap SIGINT and SIGTERM signals and gracefully exit 52 | trap "service cron stop; kill \$!; exit" SIGINT SIGTERM 53 | 54 | # start "daemon" 55 | while true 56 | do 57 | # watch /var/log/cron.log restarting if necessary 58 | cat /var/log/cron.log & wait $! 59 | done 60 | -------------------------------------------------------------------------------- /debian/README.md: -------------------------------------------------------------------------------- 1 | # Docker image with cron (Debian-based) 2 | 3 | Docker image to run cron inside the Docker container 4 | 5 | ## Adding cron jobs 6 | 7 | Suppose you have folder `cron.d` with your cron scripts. The only thing you have to do is copying this folder into the Docker image: 8 | 9 | ```Dockerfile 10 | # Dockerfile 11 | 12 | FROM renskiy/cron:debian 13 | 14 | COPY cron.d /etc/cron.d 15 | ``` 16 | 17 | Then build and create container: 18 | 19 | ```bash 20 | docker build --tag my_cron . 21 | docker run --detach --name cron my_cron 22 | ``` 23 | 24 | ## Logs 25 | 26 | To view logs use Docker [logs](https://docs.docker.com/engine/reference/commandline/logs/) command: 27 | 28 | ```bash 29 | docker logs --follow cron 30 | ``` 31 | 32 | *All you cron scripts should write logs to `/var/log/cron.log`. Otherwise you won't be able to view any log using this way.* 33 | 34 | ## Passing cron jobs by arguments 35 | 36 | Additionally you can pass any cron job by argument(s) using custom `start-cron` command at the moment of container creation (providing optional user with `-u`/`--user` option): 37 | 38 | ```bash 39 | docker run --detach --name cron renskiy/cron:debian start-cron --user www-data \ 40 | "0 1 \* \* \* echo '01:00 AM' >> /var/log/cron.log 2>&1" \ 41 | "0 0 1 1 \* echo 'Happy New Year!!' >> /var/log/cron.log 2>&1" 42 | ``` 43 | 44 | ## Environ variables 45 | 46 | Almost any environ variable you passed to the Docker will be visible to your cron scripts. With the exception of `$SHELL`, `$PATH`, `$PWD`, `$USER`, etc. 47 | 48 | ```bash 49 | docker run --tty --rm --interactive --env MY_VAR=foo renskiy/cron:debian start-cron \ 50 | "\* \* \* \* \* env >> /var/log/cron.log 2>&1" 51 | ``` 52 | 53 | ## Special Environ variables 54 | 55 | ### `CRON_PATH` 56 | 57 | This Environ variable let you provide custom directory for your `cron.d` scripts which will be placed instead of default `/etc/cron.d`: 58 | 59 | ```bash 60 | docker run --detach --name cron --env CRON_PATH=/etc/my_app/cron.d renskiy/cron:debian 61 | ``` 62 | 63 | This may be very useful when you create more then one Docker container from a single image with different cron jobs per container. 64 | -------------------------------------------------------------------------------- /alpine/README.md: -------------------------------------------------------------------------------- 1 | # Docker image with cron (Alpine-based) 2 | 3 | Docker image to run cron inside the Docker container 4 | 5 | ## Adding cron jobs 6 | 7 | Suppose you have folder `crontabs` with your cron scripts. The only thing you have to do is copying this folder into the Docker image: 8 | 9 | ```Dockerfile 10 | # Dockerfile 11 | 12 | FROM renskiy/cron:alpine 13 | 14 | COPY crontabs /etc/crontabs 15 | ``` 16 | 17 | Then build and create container: 18 | 19 | ```bash 20 | docker build --tag my_cron . 21 | docker run --detach --name cron my_cron 22 | ``` 23 | 24 | ## Logs 25 | 26 | To view logs use Docker [logs](https://docs.docker.com/engine/reference/commandline/logs/) command: 27 | 28 | ```bash 29 | docker logs --follow cron 30 | ``` 31 | 32 | *All you cron scripts should write logs to `/var/log/cron.log`. Otherwise you won't be able to view any log using this way.* 33 | 34 | ## Passing cron jobs by arguments 35 | 36 | Additionally you can pass any cron job by argument(s) using custom `start-cron` command at the moment of container creation (providing optional user with `-u`/`--user` option): 37 | 38 | ```bash 39 | docker run --detach --name cron renskiy/cron:alpine start-cron --user www-data \ 40 | "0 1 \* \* \* echo '01:00 AM' >> /var/log/cron.log 2>&1" \ 41 | "0 0 1 1 \* echo 'Happy New Year!!' >> /var/log/cron.log 2>&1" 42 | ``` 43 | 44 | ## Environ variables 45 | 46 | Almost any environ variable you passed to the Docker will be visible to your cron scripts. With the exception of `$SHELL`, `$PATH`, `$PWD`, `$USER`, etc. 47 | 48 | ```bash 49 | docker run --tty --rm --interactive --env MY_VAR=foo renskiy/cron:alpine start-cron \ 50 | "\* \* \* \* \* env >> /var/log/cron.log 2>&1" 51 | ``` 52 | 53 | ## Special Environ variables 54 | 55 | ### `CRONTABS_DIR` 56 | 57 | This Environ variable let you provide custom `crontabs` directory location which will be used instead of default one (`/etc/crontabs`): 58 | 59 | ```bash 60 | docker run --detach --name cron --env CRONTABS_DIR=/etc/my_app/crontabs renskiy/cron:alpine 61 | ``` 62 | 63 | This may be very useful when you create more then one Docker container from a single image with different cron jobs per container. 64 | --------------------------------------------------------------------------------