Compare commits

...

63 Commits

Author SHA1 Message Date
30996cccfe Merge pull request '1.0.5' (#11) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #11
2024-05-05 17:15:49 +00:00
0c88445407 Merge branch 'main' into develop
All checks were successful
continuous-integration/drone/push Build is passing
2024-05-05 17:11:35 +00:00
ce8bc4a03d Ignore outcome of chown /app & /config
All checks were successful
continuous-integration/drone Build is passing
2024-05-05 16:27:40 +00:00
ab0667e0a7 Merge pull request '1.0.4' (#8) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #8
2023-08-02 11:45:34 +00:00
44dbbdd396 tweak worker first run config logic
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-21 10:50:30 +00:00
e99cb9c5dd better permission detection 2023-07-21 10:50:05 +00:00
242902aef6 fix init folder permissions on creation 2023-07-21 10:44:01 +00:00
28ec5906ac fix not running multiple scripts in /config/init 2023-07-21 10:11:17 +00:00
73ef869c30 fix /config/init permissions 2023-07-20 11:39:23 +00:00
f2a90445c0 remove init scripts from cronicle-prepare.sh
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-16 16:56:46 +00:00
64571c49f0 run init scripts as root
Some checks reported errors
continuous-integration/drone/push Build was killed
2023-07-16 16:55:34 +00:00
c9e168a2d5 remove sample config keys
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-08 19:29:04 +00:00
f27a36c5c0 add ca-certificates package
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-08 16:29:40 +00:00
7812c5f6e6 change linking of config in worker mode
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-08 16:12:13 +00:00
cb8f69cca7 tidy up more files 2023-07-08 16:11:55 +00:00
0729a4454b add ssl compatibility
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-03 22:46:41 +00:00
a123d0fecd Merge pull request 'add reverse-proxy details' (#7) from develop into main [CI SKIP]
Reviewed-on: #7
2023-06-26 20:12:28 +00:00
1286d2053a add reverse-proxy details [CI SKIP] 2023-06-26 20:11:19 +00:00
1a9addf796 Merge pull request 'update to cronicle-edge 1.6.3' (#6) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #6
2023-06-25 13:33:44 +00:00
4019df3cce add period to cronicle-edge version
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-25 13:28:58 +00:00
0774624fbc update to cronicle-edge 1.6.3
Some checks failed
continuous-integration/drone/push Build is failing
2023-06-25 13:25:25 +00:00
8c21c43bfd add new pipeline for better building [CI SKIP] 2023-06-05 21:52:50 +00:00
504aa38362 Merge pull request 'typo correction on readme [CI SKIP]' (#5) from develop into main [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
Reviewed-on: #5
2023-06-05 21:19:16 +00:00
5fcb0c0e08 typo correction on readme [CI SKIP] 2023-06-05 21:18:31 +00:00
aace951501 Merge pull request 'fix drone release build dependency graph' (#4) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: #4
2023-06-05 21:09:47 +00:00
193f104408 fix drone release build dependency graph
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-05 21:04:42 +00:00
c4e8faff3b Merge pull request '1.0.2' (#3) from develop into main
Some checks reported errors
continuous-integration/drone/push Build was killed
Reviewed-on: #3
2023-06-05 20:50:04 +00:00
0080d188ab update readme [CI SKIP] 2023-06-05 20:49:35 +00:00
eefaba12cb fix drone dependency graph
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-05 20:43:23 +00:00
114c87fefe drone build and public to ghcr also 2023-06-05 20:43:23 +00:00
a8eb04c76b expose log dir to /config volume 2023-06-05 20:43:23 +00:00
debd509868 add cronicle info to readme [CI SKIP] 2023-06-05 20:43:23 +00:00
e8d9f7c8cd add LOG_LEVEL env var 2023-06-05 20:43:23 +00:00
98ab91f73f update readme [CI SKIP] 2023-06-05 20:43:23 +00:00
694ba8f5ce add nano, change editor to it 2023-06-05 20:43:23 +00:00
c232595f36 Merge pull request '1.0.1' (#2) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #2
2023-05-27 22:10:46 +00:00
6ac07ec9a0 cleanup misc files in app dir
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 22:05:58 +00:00
ab73132553 set permissions to 1000 at build
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 21:58:31 +00:00
76cdb2640e fix to defined cronicle version 2023-05-27 21:53:40 +00:00
f1f322d58a rename user to cronicle 2023-05-27 18:46:23 +00:00
bfbc0e22d7 fix not hooking conf in if already setup
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 18:15:12 +00:00
f3dc829111 get correct s6 for architecture
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 17:49:19 +00:00
9c3caf751e Merge pull request '1.0.0' (#1) from develop into main
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
Reviewed-on: #1
2023-05-27 16:53:07 +00:00
1ac78908ad tweak build behaviour [CI SKIP] 2023-05-27 16:49:13 +00:00
f990871798 updated readme [CI SKIP] 2023-05-27 16:46:47 +00:00
2ecac58414 add .gitignore [CI SKIP] 2023-05-27 15:37:58 +00:00
613393f328 redesign around s6-overlay
All checks were successful
continuous-integration/drone/push Build is passing
2023-05-27 13:43:46 +00:00
30026b4e17 update readme [CI SKIP] 2023-05-27 13:42:38 +00:00
580845afe0 add goreleaser [CI SKIP] 2023-05-27 13:40:53 +00:00
d4aa8ff410 update drone behaviour [CI SKIP] 2023-05-27 13:40:44 +00:00
b3436f3b2c create cronicle user at build
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-29 23:49:45 +00:00
4541df4c8a Merge branch 'main' of https://git.mrmeeb.stream/MrMeeb/cronicle-docker
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-29 20:36:16 +00:00
26c3a15c81 logic fixes 2022-12-29 20:36:15 +00:00
e10acf4e46 Update '.drone.yml'
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-29 19:41:42 +00:00
2d8fb52b23 Update '.drone.yml'
Some checks failed
continuous-integration/drone/push Build is failing
2022-12-29 19:03:26 +00:00
511704a90f drone notify on failure
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-12-29 17:51:38 +00:00
70d6215ca3 Add logic to detect if config is missing as worker
Some checks failed
continuous-integration/drone/push Build is failing
2022-12-29 17:46:57 +00:00
d759db2bb0 Update '.drone.yml'
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-27 11:48:39 +00:00
c04d6febad Merge branch 'main' of https://git.mrmeeb.stream/MrMeeb/cronicle-docker
Some checks reported errors
continuous-integration/drone/push Build was killed
2022-12-27 11:44:58 +00:00
cad9b48ab9 add drone, add logic for init scripts 2022-12-27 11:44:51 +00:00
327208391b Update 'README.md' 2022-12-26 22:31:41 +00:00
ee7034cba3 more dev 2022-12-26 22:30:42 +00:00
78f681fb41 first commit 2022-12-26 18:21:10 +00:00
23 changed files with 853 additions and 2 deletions

240
.drone.yml Normal file
View File

@ -0,0 +1,240 @@
kind: pipeline
type: docker
name: build-release-images
trigger:
event:
exclude:
- pull_request
ref:
- refs/tags/**
platform:
os: linux
arch: amd64
steps:
- name: get-tags
image: docker:git
commands:
- git fetch --tags
depends_on:
- clone
- name: make-tags
image: node
commands:
- echo -n "${DRONE_TAG}, latest" > .tags
depends_on:
- get-tags
- name: build-gitea
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: git.mrmeeb.stream
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: git.mrmeeb.stream/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: build-github
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: ghcr.io
username:
from_secret: docker_username
password:
from_secret: github_token
repo: ghcr.io/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: release-gitea
image: goreleaser/goreleaser
environment:
GITEA_TOKEN:
from_secret: gitea_token
commands:
- goreleaser release -f .goreleaser-gitea.yaml
depends_on:
- build-gitea
- name: release-github
image: goreleaser/goreleaser
environment:
GITHUB_TOKEN:
from_secret: github_token
commands:
- goreleaser release -f .goreleaser-github.yaml
depends_on:
- build-github
- name: notify
image: plugins/slack
when:
status:
- success
- failure
settings:
webhook:
from_secret: slack_webhook
depends_on:
- release-gitea
- release-github
---
kind: pipeline
type: docker
name: build-main-images
trigger:
event:
exclude:
- pull_request
ref:
- refs/heads/main
platform:
os: linux
arch: amd64
steps:
- name: make-tags
image: node
commands:
- echo -n "${DRONE_COMMIT_SHA:0:8}, latest" > .tags
when:
ref:
- refs/heads/main
depends_on:
- clone
- name: build-gitea
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: git.mrmeeb.stream
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: git.mrmeeb.stream/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: build-github
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: ghcr.io
username:
from_secret: docker_username
password:
from_secret: github_token
repo: ghcr.io/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: notify
image: plugins/slack
when:
status:
- success
- failure
settings:
webhook:
from_secret: slack_webhook
depends_on:
- build-github
- build-gitea
---
kind: pipeline
type: docker
name: build-develop-images
trigger:
event:
exclude:
- pull_request
branch:
- develop
platform:
os: linux
arch: amd64
steps:
# Set tags for develop branch - git commit SHA and 'develop'
- name: make-tags
image: node
commands:
- echo -n "develop-${DRONE_COMMIT_SHA:0:8}, develop" > .tags
# Build containers from develop branch
- name: build-gitea
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: git.mrmeeb.stream
username:
from_secret: docker_username
password:
from_secret: docker_password
repo: git.mrmeeb.stream/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: build-github
image: thegeeklab/drone-docker-buildx
privileged: true
settings:
provenance: false
registry: ghcr.io
username:
from_secret: docker_username
password:
from_secret: github_token
repo: ghcr.io/mrmeeb/cronicle
platforms:
- linux/arm64
- linux/amd64
depends_on:
- make-tags
- name: notify
image: plugins/slack
when:
status:
- success
- failure
settings:
webhook:
from_secret: slack_webhook
depends_on:
- build-gitea
- build-github

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
dist-gitea/
dist-github/
.tags

27
.goreleaser-gitea.yaml Normal file
View File

@ -0,0 +1,27 @@
dist: dist-gitea
build:
skip: true
archives:
- format: binary
release:
draft: true
gitea:
owner: MrMeeb
name: cronicle-docker
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
# .goreleaser.yaml
gitea_urls:
api: https://git.mrmeeb.stream/api/v1
download: https://git.mrmeeb.stream
# set to true if you use a self-signed certificate
skip_tls_verify: false

20
.goreleaser-github.yaml Normal file
View File

@ -0,0 +1,20 @@
dist: dist-github
build:
skip: true
archives:
- format: binary
release:
draft: true
github:
owner: MrMeeb
name: cronicle-docker
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

67
Dockerfile Normal file
View File

@ -0,0 +1,67 @@
FROM alpine:latest as base
ARG TARGETARCH
FROM base AS base-amd64
ENV S6_OVERLAY_ARCH=x86_64
FROM base AS base-arm64
ENV S6_OVERLAY_ARCH=aarch64
FROM base-${TARGETARCH}${TARGETVARIANT}
ARG S6_OVERLAY_VERSION=3.1.5.0
ARG CRONICLE_EDGE_VERSION=.1.6.3
ENV CRONICLE_foreground=1
ENV CRONICLE_echo=1
ENV CRONICLE_color=1
ENV EDITOR=nano
ENV MODE=manager
ENV PUID=1000
ENV PGID=1000
ENV TZ=UTC
ENV LOG_LEVEL=9
#Get required packages
RUN apk update && apk add --no-cache tzdata curl shadow bash xz git procps nodejs npm nano openssl ca-certificates
#Make folders
RUN mkdir /config && \
mkdir /app && \
#Create default user
useradd -u 1000 -U -d /config -s /bin/false cronicle && \
usermod -G users cronicle
#Install s6-overlay
RUN curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" | tar Jpxf - -C / && \
curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${S6_OVERLAY_ARCH}.tar.xz" | tar Jpxf - -C / && \
curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz" | tar Jpxf - -C / && \
curl -fsSL "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-arch.tar.xz" | tar Jpxf - -C /
ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2 S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 S6_VERBOSITY=1
#Install Cronicle & tidy up things I don't want
RUN apk add --no-cache --virtual .jq jq && \
mkdir /app/cronicle && \
cd /app/cronicle && \
wget https://github.com/cronicle-edge/cronicle-edge/archive/refs/tags/v${CRONICLE_EDGE_VERSION}.tar.gz && \
tar -xf v${CRONICLE_EDGE_VERSION}.tar.gz --strip-components 1 && \
rm -rf Docker* .gitignore Readme.md .vscode sample_conf/examples/backup sample_conf/examples/docker.sh && \
jq 'del(.storage[] | select(contains(["global/conf_keys"])))' sample_conf/setup.json >> sample_conf/setup-new.json && \
rm sample_conf/setup.json && \
mv sample_conf/setup-new.json sample_conf/setup.json && \
rm -rf v${CRONICLE_EDGE_VERSION}.tar.gz && \
apk del .jq
WORKDIR /app/cronicle
RUN npm install && \
node bin/build dist
COPY root/ /
RUN chmod +x /cronicle-prepare.sh && \
chmod +x /container-init.sh && \
chown -R ${PUID}:${PGID} /app /config
EXPOSE 3012
EXPOSE 3013
ENTRYPOINT [ "/init" ]

146
README.md
View File

@ -1,3 +1,145 @@
# cronicle-docker # Cronicle Docker
Dockerised Cronicle, based on the Cronicle-Edge fork ![Drone (self-hosted) with branch](https://img.shields.io/drone/build/MrMeeb/cronicle-docker/main?label=latest&server=https%3A%2F%2Fdrone.mrmeeb.stream&style=for-the-badge) ![Drone (self-hosted) with branch](https://img.shields.io/drone/build/MrMeeb/cronicle-docker/develop?label=develop&server=https%3A%2F%2Fdrone.mrmeeb.stream&style=for-the-badge)
Dockerised Cronicle, based on the [Cronicle-Edge](https://github.com/cronicle-edge/cronicle-edge) fork of [Cronicle](https://github.com/jhuckaby/Cronicle). This container was built to include features I value in containers, namely logging to `stdout` and configurable `PUID` and `PGID`.
This container can function in both the **manager** and **worker** role.
## Links
- :tea: [Gitea Repo (source)](https://git.mrmeeb.stream/MrMeeb/cronicle-docker)
- :whale2: [Containers](https://git.mrmeeb.stream/MrMeeb/-/packages/container/cronicle/latest) (also published to GHCR)
- :mirror: [GitHub mirror](https://github.com/MrMeeb/cronicle-docker)
- :package: [Cronicle Repo](https://github.com/jhuckaby/Cronicle)
- :package: [Cronicle-Edge Repo](https://github.com/cronicle-edge/cronicle-edge)
*This repo is mirrored to GitHub*
## Overview
[**Cronicle**](https://github.com/jhuckaby/Cronicle) is a multi-server task scheduler and runner, with a web based front-end UI. It handles both scheduled, repeating and on-demand jobs, targeting any number of worker servers, with real-time stats and live log viewer. It's basically a fancy [Cron](https://en.wikipedia.org/wiki/Cron) replacement written in [Node.js](https://nodejs.org/). You can give it simple shell commands, or write Plugins in virtually any language.
![Main Screenshot](https://pixlcore.com/software/cronicle/screenshots-new/job-details-complete.png)
## Features at a Glance
* Single or multi-server setup.
* Automated failover to backup servers.
* Auto-discovery of nearby servers.
* Real-time job status with live log viewer.
* Plugins can be written in any language.
* Schedule events in multiple timezones.
* Optionally queue up long-running events.
* Track CPU and memory usage for each job.
* Historical stats with performance graphs.
* Simple JSON messaging system for Plugins.
* Web hooks for external notification systems.
* Simple REST API for scheduling and running events.
* API Keys for authenticating remote apps.
## Tags
|Tag |Description|
|-------|-----------|
|latest |Latest image built from the main branch. Usually coincides with a tagged release.|
|develop|Latest image built from the develop branch. Commits are made to the develop branch before being merged to main. Old versions of `develop` are removed after 14 days.|
Tags relating to releases are also available, for locking in on a specific version.
## Running
`config.json`, located in `/config/cronicle/conf/config.json`, is automatically generated on the first run of Cronicle in 'manager' mode. This file must be kept identical between the manager and any workers it controls.
If you want to configure Cronicle before first run (e.g to use a different storage engine), download `config_sample.json` and adjust accordingly before placing in `/config/cronicle/conf/config.json`. Make sure to change the `secret`!
:exclamation: You must define the hostname of the container. Cronicle expects the hostname to remain the same, so the randomly-generated container hostname can cause problems if it changes. :exclamation:
### Docker CLI
```
docker run -d --name cronicle \
--hostname cronicle-manager \
-p 3012:3012 \
-e MODE=manager \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Europe/London \
-v {path on host}:/config
git.mrmeeb.stream/mrmeeb/cronicle:latest
```
### Docker Compose
```
version: '3'
services:
cronicle:
container_name: cronicle
image: git.mrmeeb.stream/mrmeeb/cronicle:latest
restart: unless-stopped
hostname: cronicle-manager
ports:
- 3012:3012
volumes:
- {path on host}:/config
environment:
- MODE=manager
- PUID=1000
- PGID=1000
- TZ=Europe/London
```
## Custom Scripts
This container automatically checks for scripts in `/config/init` and runs them at startup. This could be useful if you need to install additional applications into a worker container so it can execute jobs.
Note that any scripts will be run as `root` before permissions are altered in `/app` and `/config`. Anything that an init script does in either of these folders will be owned by `cronicle` when the container continues.
## Reverse Proxying
For a single manager behind a reverse proxy, you may need to specify a specific route for the web-socket connections.
An example using nginx:
```
location /socket.io/ {
client_max_body_size 2048m;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_redirect off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://localhost:3012/socket.io/;
}
```
Source: https://github.com/jhuckaby/Cronicle/issues/535
Load-balancing between multiple managers, as described [here](https://github.com/jhuckaby/Cronicle/blob/master/docs/Setup.md#load-balancers), has not been tested, and could behave strangely due to docker DNS.
## Ports
|Port |Description|
|-----|-----------|
|3012 |WebUI and communication between manager and workers|
## Volumes
|Mount |Description|
|------|-----------|
|/config |Persistent config file and job configurations|
## Environment Variables
|Variable|Options|Default|Description|
|--------|-------|-------|-------|
|MODE |manager, worker|manager|Determines what mode Cronicle runs in
|PUID |int |1000 |Sets the UID of the user Cronicle runs under
|PGID |int |1000 |Sets the GID of the user Cronicle runs under
|TZ |[List of valid TZs](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) |UTC |Sets the timezone of the container and by extension Cronicle
|LOG_LEVEL|1-10 |9 |Sets log level from `1` (quietest) to `10` (loudest)|

149
config_sample.json Normal file
View File

@ -0,0 +1,149 @@
{
"base_app_url": "http://localhost:3012",
"email_from": "admin@cronicle.com",
"smtp_hostname": "mailrelay.cronicle.com",
"smtp_port": 25,
"secret_key": "f5cb3d08bad903c6a12b84f666070630",
"ad_domain": "corp.cronicle.com",
"log_dir": "logs",
"log_filename": "[component].log",
"log_columns": ["hires_epoch", "date", "hostname", "pid", "component", "category", "code", "msg", "data"],
"log_archive_path": "logs/archives/[yyyy]/[mm]/[dd]/[filename]-[yyyy]-[mm]-[dd].log.gz",
"log_crashes": true,
"pid_file": "logs/cronicled.pid",
"copy_job_logs_to": "",
"queue_dir": "queue",
"debug_level": 6,
"maintenance": "04:00",
"list_row_max": 10000,
"job_data_expire_days": 180,
"child_kill_timeout": 10,
"dead_job_timeout": 120,
"manager_ping_freq": 20,
"manager_ping_timeout": 60,
"udp_broadcast_port": 3014,
"scheduler_startup_grace": 10,
"universal_web_hook": "",
"track_manual_jobs": false,
"max_jobs": 0,
"server_comm_use_hostnames": true,
"web_direct_connect": false,
"web_socket_use_hostnames": true,
"job_memory_max": 1073741824,
"job_memory_sustain": 0,
"job_cpu_max": 0,
"job_cpu_sustain": 0,
"job_log_max_size": 0,
"job_env": {},
"web_hook_text_templates": {
"job_start": "🚀 *[event_title]* started on [hostname] <[job_details_url] | More details>",
"job_complete": "✔️ *[event_title]* completed successfully on [hostname] <[job_details_url] | More details>",
"job_warning": "⚠️ *[event_title]* completed with warning on [hostname]:\nWarning: _*[description]*_\n <[job_details_url] | More details>",
"job_failure": "❌ *[event_title]* failed on [hostname]:\nError: _*[description]*_\n <[job_details_url] | More details>",
"job_launch_failure": "💥 Failed to launch *[event_title]*:\n*[description]*\n<[edit_event_url] | More details>"
},
"client": {
"name": "Cronicle",
"debug": 1,
"default_password_type": "password",
"privilege_list": [
{ "id": "admin", "title": "Administrator" },
{ "id": "create_events", "title": "Create Events" },
{ "id": "edit_events", "title": "Edit Events" },
{ "id": "delete_events", "title": "Delete Events" },
{ "id": "run_events", "title": "Run Events" },
{ "id": "abort_events", "title": "Abort Events" },
{ "id": "state_update", "title": "Toggle Scheduler" }
],
"new_event_template": {
"enabled": 1,
"params": {},
"timing": { "minutes": [0] },
"max_children": 1,
"timeout": 3600,
"catch_up": 0,
"queue_max": 1000
}
},
"git": {
"enabled": false,
"auto": false,
"user": "cronicle",
"email": "croncile@cronicle.com",
"remote": "origin",
"branch": "master"
},
"Storage": {
"engine": "Filesystem",
"list_page_size": 50,
"concurrency": 4,
"log_event_types": { "get": 1, "put": 1, "head": 1, "delete": 1, "expire_set": 1 },
"Filesystem": {
"base_dir": "data",
"key_namespaces": 1
}
},
"WebServer": {
"http_port": 3012,
"http_htdocs_dir": "htdocs",
"http_max_upload_size": 104857600,
"http_static_ttl": 3600,
"http_static_index": "index.html",
"http_server_signature": "Cronicle 1.0",
"http_gzip_text": true,
"http_timeout": 30,
"http_regex_json": "(text|javascript|js|json)",
"http_response_headers": {
"Access-Control-Allow-Origin": "*"
},
"https": false,
"https_port": 3013,
"https_cert_file": "conf/ssl.crt",
"https_key_file": "conf/ssl.key",
"https_force": false,
"https_timeout": 30,
"https_header_detect": {
"Front-End-Https": "^on$",
"X-Url-Scheme": "^https$",
"X-Forwarded-Protocol": "^https$",
"X-Forwarded-Proto": "^https$",
"X-Forwarded-Ssl": "^on$"
}
},
"User": {
"session_expire_days": 30,
"max_failed_logins_per_hour": 5,
"max_forgot_passwords_per_hour": 3,
"free_accounts": false,
"sort_global_users": true,
"use_bcrypt": true,
"email_templates": {
"welcome_new_user": "conf/emails/welcome_new_user.txt",
"changed_password": "conf/emails/changed_password.txt",
"recover_password": "conf/emails/recover_password.txt"
},
"default_privileges": {
"admin": 0,
"create_events": 1,
"edit_events": 1,
"delete_events": 1,
"run_events": 0,
"abort_events": 0,
"state_update": 0
}
}
}

69
root/container-init.sh Normal file
View File

@ -0,0 +1,69 @@
#!/command/with-contenv bash
# shellcheck shell=bash
echo ""
echo ""
echo "================================================"
echo "| __ _______ __ ___________________ |"
echo "| / |/ / __ \/ |/ / ____/ ____/ __ ) |"
echo "| / /|_/ / /_/ / /|_/ / __/ / __/ / __ | |"
echo "| / / / / _, _/ / / / /___/ /___/ /_/ / |"
echo "| /_/ /_/_/ |_/_/ /_/_____/_____/_____/ |"
echo "| |"
echo "================================================"
echo ""
echo "Initialising container"
echo "
----------------------------------------------------------------------
ENVIRONMENT
----------------------------------------------------------------------
PUID=${PUID}
PGID=${PGID}
TZ=${TZ}
MODE=${MODE}
LOG_LEVEL=${LOG_LEVEL}
----------------------------------------------------------------------
"
#Setting UID and GID as configured
if [[ ! "${PUID}" -eq 0 ]] && [[ ! "${PGID}" -eq 0 ]]; then
echo "Executing usermod..."
mkdir "/tmp/temphome"
usermod -d "/tmp/temphome" cronicle
usermod -o -u "${PUID}" cronicle
usermod -d /config cronicle
rm -rf "/tmp/temphome"
groupmod -o -g "${PGID}" cronicle
else
echo "Running as root is not supported, please fix your PUID and PGID!"
exit 1
fi
#Importing and running additional scripts placed in /config/init
if [ -d /config/init ]; then
if [ "$(ls -A /config/init)" ]; then
echo "Running additional startup scripts."
for f in /config/init/*.sh; do
bash "$f"
done
else
echo "/config/init is empty - no additional startup scripts detected."
fi
else
echo "Directory /config/init not found. Creating."
mkdir /config/init && chown -R cronicle:cronicle /config/init
fi
echo "Checking permissions in /config and /app."
if [ -n "$(find /app \! -user ${PUID})" ] || [ -n "$(find /app \! -group ${PGID})" ]
then
echo "Fixing permissions for /app (this can take some time)."
chown -R cronicle:cronicle /app || true
fi
if [ -n "$(find /config \! -user ${PUID})" ] || [ -n "$(find /config \! -group ${PGID})" ]
then
echo "Fixing permissions for /config (this can take some time)."
chown -R cronicle:cronicle /config || true
fi

125
root/cronicle-prepare.sh Normal file
View File

@ -0,0 +1,125 @@
#!/command/with-contenv bash
# shellcheck shell=bash
echo "Preparing Cronicle"
if [ ! -d /config/cronicle ]
then
echo "Directory /config/cronicle not found. Creating."
mkdir /config/cronicle
fi
#Detecting what mode Cronicle should be started in
if [ $MODE == "manager" ]
then
echo "Cronicle is running in 'manager' mode."
#Copying config directory to /config/cronicle/conf if not already there, then linking back into Cronicle
if [ ! -d /config/cronicle/conf ]
then
echo "Config dir is missing, creating."
cp -r /app/cronicle/conf /config/cronicle/conf
rm -rf /app/cronicle/conf
ln -s /config/cronicle/conf /app/cronicle/conf
else
echo "Config dir already exists. Doesn't need creating."
echo "Linking persistent config dir back into Cronicle."
rm -rf /app/cronicle/conf
ln -s /config/cronicle/conf /app/cronicle/conf
fi
if [ ! -f /config/cronicle/conf/ssl.crt ] || [ ! -f /config/cronicle/conf/ssl.key ]
then
echo "One or both SSL components are missing. Generating."
rm -f /config/cronicle/conf/ssl.crt /config/cronicle/conf/ssl.key
openssl req -x509 -newkey rsa:4096 -keyout /config/cronicle/conf/ssl.key -out /config/cronicle/conf/ssl.crt -sha256 -days 3650 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"
fi
if [ ! -f /config/cronicle/data/.setup_done ]
then
echo "Setup needed - running now."
/app/cronicle/bin/control.sh setup
touch /app/cronicle/data/.setup_done
#Moving data dir to /config, then linking it back into Cronicle
mv -n /app/cronicle/data /config/cronicle/data
rm -rf /app/cronicle/data
ln -s /config/cronicle/data /app/cronicle/data
else
echo "Setup already completed."
rm -rf /app/cronicle/data
ln -s /config/cronicle/data /app/cronicle/data
fi
elif [ $MODE == "worker" ]
then
echo "Cronicle is running in 'worker' mode."
#Copying config directory to /config/cronicle/conf if not already there, then linking back into Cronicle
if [ ! -f /config/cronicle/conf/config.json ]
then
echo "No config found. Copy config.json from the manager server and place it in /config/cronicle/conf dir."
cp -R /app/cronicle/conf /config/cronicle/conf
rm -rf /config/cronicle/conf/config.json
echo ''
echo ''
echo '*************************************'
exit 1
else
echo "Config is present."
echo "Linking persistent config dir back into Cronicle."
rm -rf /app/cronicle/conf
ln -s /config/cronicle/conf /app/cronicle/conf
fi
else
echo "'$MODE' is not a recognised appion for the MODE environment variable. Accepted options are 'manager' and 'worker'."
exit 1
fi
#Expose log directory
if [ ! -d /config/cronicle/logs ]
then
echo "Logs dir is missing, creating."
cp -r /app/cronicle/logs /config/cronicle/logs
rm -rf /app/cronicle/logs
ln -s /config/cronicle/logs /app/cronicle/logs
else
echo "Logs dir already exists. Doesn't need creating."
echo "Linking persistent logs dir back into Cronicle."
rm -rf /app/cronicle/logs
ln -s /config/cronicle/logs /app/cronicle/logs
fi

View File

@ -0,0 +1 @@
oneshot

View File

@ -0,0 +1 @@
/container-init.sh

View File

@ -0,0 +1 @@
oneshot

View File

@ -0,0 +1 @@
exec s6-setuidgid cronicle /cronicle-prepare.sh

View File

@ -0,0 +1 @@
echo "$e" > /run/s6-linux-init-container-results/exitcode

View File

@ -0,0 +1,3 @@
#!/command/with-contenv bash
# shellcheck shell=bash
exec s6-setuidgid cronicle node /app/cronicle/lib/main.js --debug_level ${LOG_LEVEL} --color ${CRONICLE_color}

View File

@ -0,0 +1 @@
longrun