116 lines
4.4 KiB
Markdown
116 lines
4.4 KiB
Markdown
# cronicle-docker
|
|
|
|
Container image for [vanilla upstream Cronicle](https://github.com/jhuckaby/Cronicle),
|
|
built from the GitHub release tarball.
|
|
|
|
Produces `git.lerch.org/lobo/cronicle`.
|
|
|
|
## Why this repo exists
|
|
|
|
The `cronicle/cronicle` image on Docker Hub is effectively abandoned: `:latest`
|
|
is `:0.9.74`, last pushed 2025-02-24, while upstream Cronicle releases roughly
|
|
monthly. It is published by the [cronicle-edge](https://github.com/cronicle-edge/cronicle-edge)
|
|
project, whose own fork (`cronicle/edge`) ships regularly -- the "classic"
|
|
variant just stopped getting rebuilt.
|
|
|
|
The surveyed alternatives were all worse for this purpose:
|
|
|
|
| Image | Cronicle version | Last built | Notes |
|
|
| --- | --- | --- | --- |
|
|
| `cronicle/cronicle` | 0.9.74 | 2025-02-24 | vanilla, abandoned tag |
|
|
| `soulteary/cronicle` | 0.9.80 | 2025-06-02 | vanilla, stale |
|
|
| `cronicle/edge` | fork v1.14.x | current | actively maintained, but a fork |
|
|
| `intelliops`, `bluet`, `nicholasamorim` | 0.8.x | 2019-2021 | ancient |
|
|
|
|
Staying on vanilla keeps the MIT license, the existing on-disk data format, and
|
|
local-time log annotation. This repo is the minimum needed to do that: the
|
|
Dockerfile mirrors `cronicle/cronicle:0.9.74`'s layout (recovered from
|
|
`docker history`), with deviations documented inline.
|
|
|
|
## Concrete problem it solved
|
|
|
|
Cronicle v0.9.74's `package-lock.json` pins `pixl-json-stream` **1.0.9**, which
|
|
drops the trailing newline from the last complete line of every read chunk.
|
|
Because `bin/shell-plugin.js` appends the line verbatim and relies on the
|
|
library for the terminator, job logs silently concatenate:
|
|
|
|
```
|
|
[2026/08/11 14:00:02] EDGAR company ticker map okinfo(...): provider data lag ...
|
|
```
|
|
|
|
Upstream fixed the library in 1.0.10, and Cronicle v0.9.126's lockfile pins it.
|
|
Building current releases therefore fixes the bug -- but since a *lockfile*
|
|
delivered it in the first place, `test/newline-regression.js` runs during
|
|
`docker build` and fails the build if it ever comes back. See that file for the
|
|
full write-up.
|
|
|
|
## Build
|
|
|
|
`CRONICLE_VERSION` is required and takes no leading `v`:
|
|
|
|
```sh
|
|
docker build --build-arg CRONICLE_VERSION=0.9.126 -t cronicle:local .
|
|
```
|
|
|
|
## Tags
|
|
|
|
CI publishes three tags per build:
|
|
|
|
| Tag | Mutability | Use |
|
|
| --- | --- | --- |
|
|
| `0.9.126-a1b2c3d` | immutable | **pin this in deployments** |
|
|
| `0.9.126` | moves | latest build of that Cronicle release |
|
|
| `latest` | moves | latest build of anything |
|
|
|
|
The immutable tag is `<cronicle-version>-<short-sha-of-this-repo>`.
|
|
|
|
## CI
|
|
|
|
`.forgejo/workflows/build.yaml` runs on push to `master`, on manual dispatch,
|
|
and nightly at 13:00 UTC.
|
|
|
|
It resolves upstream's latest release, then checks whether the immutable tag
|
|
already exists in the registry and skips the build if so. Because that tag
|
|
encodes both the upstream version and this repo's commit, a rebuild is triggered
|
|
by either a new Cronicle release or a change here -- with no state file to keep
|
|
in sync.
|
|
|
|
Note: the nightly does **not** rebuild for base-image security patches alone,
|
|
since nothing about the tag would change. Force one with a manual dispatch or an
|
|
empty commit if a relevant Alpine CVE lands.
|
|
|
|
## Running
|
|
|
|
No `CMD` is set, matching upstream. Start it with `control.sh start`:
|
|
|
|
```sh
|
|
docker run -d --name cronicle \
|
|
-h cronicle-master \
|
|
-e TZ="America/Los_Angeles" \
|
|
-v /data/cronicle/data:/opt/cronicle/data \
|
|
-v /data/cronicle/conf:/opt/cronicle/conf \
|
|
git.lerch.org/lobo/cronicle:0.9.126-a1b2c3d control.sh start
|
|
```
|
|
|
|
The image defaults to **UTC**, unlike `cronicle/cronicle` which hardcoded
|
|
`America/New_York`. Set `TZ` explicitly.
|
|
|
|
`CRONICLE_foreground=1` and `CRONICLE_echo=1` are baked in, so the process stays
|
|
in the foreground and streams its log to `docker logs`.
|
|
|
|
### Behind a reverse proxy
|
|
|
|
If the proxy sets `X-Forwarded-Proto: https`, Cronicle reports its `https_port`
|
|
in `/api/app/config`, and the live log watcher will try to reach a worker
|
|
directly on that port -- which fails when the address is a container-internal IP.
|
|
Set `custom_live_log_socket_url` at the **top level** of `config.json` (not
|
|
inside `client`, where it is silently overwritten by the server-side default):
|
|
|
|
```json
|
|
"custom_live_log_socket_url": "https://cronicle.example.org"
|
|
```
|
|
|
|
Cronicle polls `config.json` every 10 seconds and hot-reloads it, so this
|
|
particular key takes effect without a restart. That is inherited
|
|
`pixl-server` behaviour and applies only to values read per-request; anything
|
|
consumed at startup (bound ports, storage engine) still needs a restart.
|