diff --git a/Dockerfile b/Dockerfile index 6205966..1d4f55b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ FROM library/alpine:3.5 ENV HOME_DIR=/opt/crontab -RUN apk add --no-cache --virtual .run-deps bash curl jq \ - && mkdir -p ${HOME_DIR} +RUN apk add --no-cache --virtual .run-deps bash jq \ + && mkdir -p ${HOME_DIR}/projects COPY docker-entrypoint / ENTRYPOINT ["/docker-entrypoint"] diff --git a/README.md b/README.md index f13a7f5..74522dd 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ A great project, don't get me wrong. It was just missing certain key enterprise - `container`: Full container name or container alias if `project` is set. Ignored if `image` is included. Optional. - `dockerargs`: Command line docker `run`/`exec` arguments for full control. Defaults to ` `. - `trigger`: Array of docker-crontab subset objects. Subset includes: `image`,`project`,`container`,`command`,`dockerargs` +- `onstart`: run the command on `crontab` container start. Default `false`. See [`config.sample.json`](https://github.com/willfarrell/docker-crontab/blob/master/config.sample.json) for examples. @@ -65,7 +66,7 @@ CMD ["crond", "-f"] ## TODO - [ ] Make smaller by using busybox? -- [ ] Have ability to auto regenerate crontab on file change +- [ ] Have ability to auto regenerate crontab on file change (signal HUP?) - [ ] Run commands on host machine (w/ --privileged?) - [ ] Write tests - [ ] Setup TravisCI \ No newline at end of file diff --git a/config.sample.json b/config.sample.json index dd25c2c..6e72e00 100644 --- a/config.sample.json +++ b/config.sample.json @@ -29,4 +29,19 @@ "command":"echo world", "container":"crontab_myapp_1" }] +},{ + "schedule":"*/5 * * * *", + "command":"/usr/sbin/logrotate /etc/logrotate.conf" +},{ + "comment":"Regenerate Certificate then reload nginx", + "schedule":"43 6,18 * * *", + "command":"sh -c 'dehydrated --cron --out /etc/ssl --domain ${LE_DOMAIN} --challenge dns-01 --hook dehydrated-dns'", + "dockerargs":"--env-file /opt/crontab/env/letsencrypt.env -v webapp_nginx_tls_cert:/etc/ssl -v webapp_nginx_acme_challenge:/var/www/.well-known/acme-challenge", + "image":"willfarrell/letsencrypt", + "trigger":[{ + "command":"sh -c '/etc/scripts/make_hpkp ${NGINX_DOMAIN} && /usr/sbin/nginx -t && /usr/sbin/nginx -s reload'", + "project":"conduit", + "container":"nginx" + }], + "onstart":true }] \ No newline at end of file diff --git a/docker-entrypoint b/docker-entrypoint index 0381a48..c406ccb 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -6,7 +6,7 @@ set -e CONFIG=${HOME_DIR}/config.json DOCKER_SOCK=/var/run/docker.sock -CRONTAB_FILE=${HOME_DIR}/docker +CRONTAB_FILE=/etc/crontabs/docker make_image_cmd() { DOCKERARGS=$(echo ${1} | jq -r .dockerargs) @@ -29,18 +29,16 @@ make_container_cmd() { # create bash script to detect all running containers SCRIPT_NAME=$(cat /proc/sys/kernel/random/uuid) -cat << EOF > ${HOME_DIR}/${SCRIPT_NAME} +cat << EOF > ${HOME_DIR}/projects/${SCRIPT_NAME}.sh #!/usr/bin/env bash set -e -CONTAINERS=\$(docker ps --format '{{.Names}}') +CONTAINERS=\$(docker ps --format '{{.Names}}' | grep -E "^${PROJECT}_${CONTAINER}_[0-9]+") for CONTAINER_NAME in \$CONTAINERS; do - if [[ "\${CONTAINER_NAME}" =~ ^${PROJECT}_${CONTAINER}.+ ]]; then - docker exec ${DOCKERARGS} \${CONTAINER_NAME} ${TMP_COMMAND} - fi + docker exec ${DOCKERARGS} \${CONTAINER_NAME} ${TMP_COMMAND} done EOF - echo "/bin/bash ${HOME_DIR}/${SCRIPT_NAME}" + echo "/bin/bash ${HOME_DIR}/projects/${SCRIPT_NAME}.sh" else echo "docker exec ${DOCKERARGS} ${CONTAINER} ${TMP_COMMAND}" fi @@ -107,6 +105,8 @@ parse_schedule() { function build_crontab() { rm -rf ${CRONTAB_FILE} + + ONSTART=() while read i ; do SCHEDULE=$(jq -r .[$i].schedule ${CONFIG} | sed 's/\*/\\*/g') @@ -142,10 +142,19 @@ function build_crontab() { fi echo "${SCHEDULE} ${COMMAND}" >> ${CRONTAB_FILE} + + if [ "$(jq -r .[$i].onstart ${CONFIG})" == "true" ]; then + ONSTART+=("${COMMAND}") + fi done < <(jq -r '.|keys[]' ${CONFIG}) echo "crontab generation complete" cat ${CRONTAB_FILE} + + # Run onstart commands + for COMMAND in "${ONSTART}"; do + ${COMMAND} + done } if [ "$1" = "crond" ]; then