├── .github └── FUNDING.yml ├── .all-contributorsrc ├── docker-compose.yml ├── LICENSE ├── docker-build.sh ├── Dockerfile ├── docker └── entrypoint.sh ├── .gitignore └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [bluet] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: bluet 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "winstonspencer", 10 | "name": "Winston Spencer", 11 | "avatar_url": "https://avatars.githubusercontent.com/u/3476702?v=4", 12 | "profile": "https://www.winstonspencer.com/", 13 | "contributions": [ 14 | "code" 15 | ] 16 | }, 17 | { 18 | "login": "TheBestMoshe", 19 | "name": "Moshe Grunwald", 20 | "avatar_url": "https://avatars.githubusercontent.com/u/34072688?v=4", 21 | "profile": "https://moshegrunwald.com", 22 | "contributions": [ 23 | "code" 24 | ] 25 | } 26 | ], 27 | "contributorsPerLine": 7, 28 | "projectName": "docker-cronicle-docker", 29 | "projectOwner": "bluet", 30 | "repoType": "github", 31 | "repoHost": "https://github.com", 32 | "skipCi": true 33 | } 34 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | services: 3 | cronicle: 4 | image: bluet/cronicle-docker:latest 5 | container_name: cronicle 6 | hostname: cronicle 7 | # environment: 8 | # - TZ=Asia/Taipei 9 | # - CRONICLE_base_app_url=http://cronicle/ 10 | ports: 11 | - "3012:3012" 12 | volumes: 13 | - /var/run/docker.sock:/var/run/docker.sock 14 | - /data/docker/cronicle/data:/opt/cronicle/data 15 | - /data/docker/cronicle/logs:/opt/cronicle/logs 16 | - /data/docker/cronicle/plugins:/opt/cronicle/plugins 17 | - /data/docker/cronicle/workloads/app:/app 18 | restart: unless-stopped 19 | # dns-proxy-server helps mapping http://cronicle/ to your container IP http://172.16.xx.xx/ 20 | # dps: 21 | # image: defreitas/dns-proxy-server 22 | # container_name: 'dps' 23 | # ports: 24 | # - '0.0.0.0:5380:5380' 25 | # hostname: dps 26 | # environment: 27 | # - MG_RESOLVCONF=/host/resolve/stub-resolv.conf 28 | # volumes: 29 | # - /var/run/docker.sock:/var/run/docker.sock 30 | # - /run/systemd/resolve:/host/resolve 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 BlueT - Matthew Lien - 練喆明 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 | -------------------------------------------------------------------------------- /docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | VERSION=0.9.99 4 | 5 | docker build --pull --build-arg CRONICLE_VERSION=${VERSION} -t bluet/cronicle-docker . 6 | #docker scan bluet/cronicle-docker:latest 7 | docker scout quickview bluet/cronicle-docker:latest 8 | grype bluet/cronicle-docker:latest | grep -i -E '(High|Critical)' 9 | 10 | docker tag bluet/cronicle-docker:latest bluet/cronicle-docker:${VERSION} 11 | 12 | # move git tag to last step 13 | #git tag "${VERSION}" -a -m "cronicle ${VERSION}" 14 | #git push 15 | #git push --tags 16 | 17 | # Fixes busybox trigger error https://github.com/tonistiigi/xx/issues/36#issuecomment-926876468 18 | #docker run --privileged -it --rm tonistiigi/binfmt --install all 19 | 20 | #docker buildx create --use 21 | 22 | while true; do 23 | read -p "Is VERSION=${VERSION} the current latest version? (We're going to build multi-platform images and push) [y/N]" yn 24 | case $yn in 25 | [Yy]* ) docker buildx build --build-arg CRONICLE_VERSION=${VERSION} --builder cloud-bluet-test -t bluet/cronicle-docker:latest -t bluet/cronicle-docker:${VERSION} --platform linux/amd64,linux/arm64/v8 --pull --push .; break;; 26 | [Nn]* ) break;; 27 | * ) echo "";; 28 | esac 29 | done 30 | 31 | read -p "Tag the version of code as ${VERSION} in git? [y/N]" yn 32 | case $yn in 33 | [Yy]* ) git tag "${VERSION}" -a -m "cronicle ${VERSION}" && git push --tags;; 34 | * ) echo "";; 35 | esac 36 | 37 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker:28 2 | LABEL maintainer="BlueT - Matthew Lien - 練喆明 " 3 | 4 | # Docker defaults 5 | ARG CRONICLE_VERSION 6 | ENV CRONICLE_VERSION=$CRONICLE_VERSION 7 | ENV CRONICLE_base_app_url='http://localhost:3012' 8 | ENV CRONICLE_WebServer__http_port=3012 9 | ENV CRONICLE_WebServer__https_port=443 10 | ENV EDITOR=nano 11 | 12 | RUN if [ -z "$CRONICLE_VERSION" ]; then \ 13 | echo 'Build argument CRONICLE_VERSION must be specified. Exiting.'; \ 14 | exit 1; \ 15 | fi 16 | 17 | # install updates and security patches while installing new packages 18 | # Ref: https://github.com/docker/docs/pull/12571 19 | RUN apk add --no-cache --upgrade \ 20 | nodejs npm git curl perl bash perl-pathtools tar procps nano tini python3 21 | RUN mkdir -p /opt/cronicle \ 22 | && cd /opt/cronicle \ 23 | && curl -L https://github.com/jhuckaby/Cronicle/archive/v${CRONICLE_VERSION}.tar.gz | tar zxvf - --strip-components 1 \ 24 | && npm install \ 25 | && node bin/build.js dist \ 26 | && rm -Rf /root/.npm 27 | 28 | # Runtime user 29 | # RUN adduser cronicle -D -h /opt/cronicle 30 | # RUN adduser cronicle docker 31 | WORKDIR /opt/cronicle/ 32 | ADD docker/entrypoint.sh /entrypoint.sh 33 | 34 | EXPOSE 3012 35 | 36 | # data volume is also configured in entrypoint.sh 37 | VOLUME ["/opt/cronicle/data", "/opt/cronicle/logs", "/opt/cronicle/plugins"] 38 | 39 | ENTRYPOINT ["/sbin/tini", "--"] 40 | CMD ["sh", "/entrypoint.sh"] 41 | -------------------------------------------------------------------------------- /docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ROOT_DIR=/opt/cronicle 4 | CONF_DIR=$ROOT_DIR/conf 5 | BIN_DIR=$ROOT_DIR/bin 6 | # DATA_DIR needs to be the same as the exposed Docker volume in Dockerfile 7 | DATA_DIR=$ROOT_DIR/data 8 | # LOGS_DIR needs to be the same as the exposed Docker volume in Dockerfile 9 | LOGS_DIR=$ROOT_DIR/logs 10 | # PLUGINS_DIR needs to be the same as the exposed Docker volume in Dockerfile 11 | PLUGINS_DIR=$ROOT_DIR/plugins 12 | 13 | # The env variables below are needed for Docker and cannot be overwritten 14 | export CRONICLE_Storage__Filesystem__base_dir=${DATA_DIR} 15 | export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt 16 | export CRONICLE_echo=1 17 | export CRONICLE_foreground=1 18 | 19 | # Only run setup when setup needs to be done 20 | if [ ! -f $DATA_DIR/.setup_done ] 21 | then 22 | cp $CONF_DIR/config.json $CONF_DIR/config.json.origin 23 | 24 | if [ -f $DATA_DIR/config.json.import ] 25 | then 26 | # Move in custom configuration 27 | cp $DATA_DIR/config.json.import $CONF_DIR/config.json 28 | fi 29 | 30 | $BIN_DIR/control.sh setup 31 | 32 | # Create plugins directory 33 | mkdir -p $PLUGINS_DIR 34 | 35 | # Marking setup done 36 | touch $DATA_DIR/.setup_done 37 | fi 38 | 39 | # Run cronicle with unprivileged user 40 | # chown -R cronicle:cronicle data/ logs/ 41 | 42 | # remove old lock file. resolves #9 43 | PID_FILE=$LOGS_DIR/cronicled.pid 44 | if [ -f "$PID_FILE" ]; then 45 | echo "Removing old PID file: $PID_FILE" 46 | rm -f $PID_FILE 47 | fi 48 | 49 | if [ -n "$1" ]; 50 | then 51 | # if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then 52 | # set -- cronicle "$@" 53 | # fi 54 | exec "$@" 55 | else 56 | # exec su cronicle -c "/opt/cronicle/bin/control.sh start" 57 | /opt/cronicle/bin/control.sh start 58 | fi 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-cronicle-docker 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) 4 | 5 | [![Docker Pulls](https://img.shields.io/docker/pulls/bluet/cronicle-docker.svg)](https://shields.io/) 6 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbluet%2Fdocker-cronicle-docker.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbluet%2Fdocker-cronicle-docker?ref=badge_shield) 7 | 8 | Workflow scheduler to run docker jobs just like cron, 9 | and *each job runs inside **its own containers***, 10 | with Cronicle in docker. 11 | 12 | Run dockerized Cronicle (corn) jobs in docker container. 13 | Or just *run a **prebuilt docker image*** as your task/job. 14 | 15 | - GitHub: https://github.com/bluet/docker-cronicle-docker 16 | - Docker Hub: https://hub.docker.com/r/bluet/cronicle-docker 17 | 18 | # Supported tags 19 | 20 | * [Tags](https://hub.docker.com/r/bluet/cronicle-docker/tags) 21 | * [Dockerfile](https://raw.githubusercontent.com/bluet/docker-cronicle-docker/master/docker/Dockerfile) 22 | 23 | # Usage 24 | 25 | ## Install 26 | ```sh 27 | docker pull bluet/cronicle-docker:latest 28 | ``` 29 | 30 | ## Running 31 | ```sh 32 | docker run -v /var/run/docker.sock:/var/run/docker.sock --hostname localhost -p 3012:3012 --name cronicle bluet/cronicle-docker:latest 33 | ``` 34 | 35 | Alternatively with persistent data and logs: 36 | ```sh 37 | docker run \ 38 | -v /var/run/docker.sock:/var/run/docker.sock:rw \ 39 | -v $PWD/data:/opt/cronicle/data:rw \ 40 | -v $PWD/logs:/opt/cronicle/logs:rw \ 41 | -v $PWD/plugins:/opt/cronicle/plugins:rw \ 42 | -v $PWD/app:/app:rw \ 43 | --hostname localhost \ 44 | -p 3012:3012\ 45 | --name cronicle \ 46 | bluet/cronicle-docker:latest 47 | ``` 48 | 49 | The web UI will be available at: http://localhost:3012 50 | 51 | > NOTE: please replace the hostname `localhost`, this is only for testing 52 | > purposes! If you rename the hostname also consider setting the environmental 53 | > variable `CRONICLE_base_app_url`. 54 | > e.g `docker run --name cronicle --hostname cronicle-host -p 3012:3012 -e CRONICLE_base_app_url='http://cronicle-host:3012' bluet/cronicle-docker:latest` 55 | 56 | ## Volumes 57 | 58 | | Path | Description | 59 | |--------|--------| 60 | | /opt/cronicle/data | Volume for data | 61 | | /opt/cronicle/logs | Volume for logs | 62 | | /opt/cronicle/plugins | Volume for plugins | 63 | | /app | Volume for additional files if needed by jobs | 64 | 65 | ## Configuration 66 | 67 | ### Environmental variables 68 | Cronicle supports a special environment variable syntax, which can specify command-line options as well as override any configuration settings. The variable name syntax is `CRONICLE_key` where `key` is one of several command-line options (see table below) or a JSON configuration property path. 69 | 70 | For a list of latest default values, please check [Official documment](https://github.com/jhuckaby/Cronicle/blob/master/docs/Configuration.md). 71 | 72 | For overriding configuration properties by environment variable, you can specify any top-level JSON key from `config.json`, or a *path* to a nested property using double-underscore (`__`) as a path separator. For boolean properties, you can specify `1` for true and `0` for false. Here is an example of some of the possibilities available: 73 | 74 | | Environmental variable | Description | Default value | 75 | |--------|--------|--------| 76 | | CRONICLE_base_app_url | A fully-qualified URL to Cronicle on your server, including the port if non-standard. This is used for self-referencing URLs. | http://localhost:3012 | 77 | | CRONICLE_WebServer__http_port | The HTTP port for the web UI of your Cronicle server. (Keep default value, unless you know what you are doing) | 3012 | 78 | | CRONICLE_WebServer__https_port | The SSL port for the web UI of your Cronicle server. (Keep default value, unless you know what you are doing) | 443 | 79 | | CRONICLE_web_socket_use_hostnames | Setting this parameter to `1` will force Cronicle's Web UI to connect to the back-end servers using their hostnames rather than IP addresses. This includes both AJAX API calls and Websocket streams. | 0 | 80 | | CRONICLE_server_comm_use_hostnames | Setting this parameter to `1` will force the Cronicle servers to connect to each other using hostnames rather than LAN IP addresses. | 0 | 81 | | CRONICLE_web_direct_connect | When this property is set to `0`, the Cronicle Web UI will connect to whatever hostname/port is on the URL. It is expected that this hostname/port will always resolve to your master server. This is useful for single server setups, situations when your users do not have direct access to your Cronicle servers via their IPs or hostnames, or if you are running behind some kind of reverse proxy. If you set this parameter to `1`, then the Cronicle web application will connect directly to your individual Cronicle servers. This is more for multi-server configurations, especially when running behind a load balancer with multiple backup servers. The Web UI must always connect to the master server, so if you have multiple backup servers, it needs a direct connection. | 0 | 82 | | CRONICLE_socket_io_transports | This allows you to customize the socket.io transports used to connect to the server for real-time updates. If you are trying to run Cronicle in an environment where WebSockets are not allowed (perhaps an ancient firewall or proxy), you can change this array to contain the `polling` transport first. Otherwise set it to `["websocket"]` | ["websocket"] | 83 | 84 | ### Custom configuration file 85 | A custom configuration file can be provide in the following location: 86 | ```sh 87 | /path-to-cronicle-storage/data/config.json.import 88 | ``` 89 | The file will get loaded the very first time Cronicle is started. If afterwards 90 | a forced reload of the custom configuration is needed remove the following file 91 | and restart the Docker container: 92 | ```sh 93 | /path-to-cronicle-storage/data/.setup_done 94 | ``` 95 | 96 | ## Web UI credentials 97 | The default credentials for the web interface are: `admin` / `admin` 98 | 99 | 100 | 101 | # Reference 102 | - Docker Hub: https://hub.docker.com/r/bluet/cronicle-docker 103 | - https://github.com/jhuckaby/Cronicle 104 | - https://github.com/belsander/docker-cronicle 105 | 106 | ## License 107 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbluet%2Fdocker-cronicle-docker.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbluet%2Fdocker-cronicle-docker?ref=badge_large) 108 | 109 | ## Contributors ✨ 110 | 111 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 |

Winston Spencer

💻

Moshe Grunwald

💻
122 | 123 | 124 | 125 | 126 | 127 | 128 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 129 | --------------------------------------------------------------------------------