Skip to content

Commit fb3370b

Browse files
committed
v1.1.0
1 parent 1cf4012 commit fb3370b

File tree

12 files changed

+157
-94
lines changed

12 files changed

+157
-94
lines changed

.github/workflows/docker-publish.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: HolyClaude — Build & Push to Docker Hub
1+
name: HolyClaude — Build & Push to Docker Hub + GHCR
22

33
on:
44
workflow_dispatch:
@@ -12,17 +12,19 @@ concurrency:
1212

1313
env:
1414
DOCKERHUB_IMAGE: coderluii/holyclaude
15+
GHCR_IMAGE: ghcr.io/coderluii/holyclaude
1516

1617
jobs:
1718
build-and-push:
1819
runs-on: ubuntu-latest
1920
permissions:
2021
contents: read
22+
packages: write
2123

2224
strategy:
2325
max-parallel: 1
2426
matrix:
25-
variant: [full, slim]
27+
variant: [slim, full]
2628

2729
steps:
2830
- name: Checkout
@@ -47,19 +49,25 @@ jobs:
4749
username: ${{ secrets.DOCKERHUB_USERNAME }}
4850
password: ${{ secrets.DOCKERHUB_TOKEN }}
4951

52+
- name: Login to GHCR
53+
uses: docker/login-action@v4
54+
with:
55+
registry: ghcr.io
56+
username: ${{ github.actor }}
57+
password: ${{ secrets.GHCR_TOKEN }}
58+
5059
- name: Extract metadata
5160
id: meta
5261
uses: docker/metadata-action@v6
5362
with:
5463
images: |
5564
${{ env.DOCKERHUB_IMAGE }}
65+
${{ env.GHCR_IMAGE }}
5666
tags: |
5767
type=raw,value=latest,enable=${{ matrix.variant == 'full' }}
5868
type=raw,value=slim,enable=${{ matrix.variant == 'slim' }}
5969
type=semver,pattern={{version}},enable=${{ matrix.variant == 'full' }}
6070
type=semver,pattern={{version}}-slim,enable=${{ matrix.variant == 'slim' }}
61-
type=semver,pattern={{major}}.{{minor}},enable=${{ matrix.variant == 'full' }}
62-
type=semver,pattern={{major}}.{{minor}}-slim,enable=${{ matrix.variant == 'slim' }}
6371
6472
- name: Build and push
6573
uses: docker/build-push-action@v7

Dockerfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
FROM node:22-bookworm-slim
1111

12+
LABEL org.opencontainers.image.source=https://github.com/CoderLuii/HolyClaude
13+
1214
# ---------- Build args ----------
1315
ARG S6_OVERLAY_VERSION=3.2.0.2
1416
ARG TARGETARCH
@@ -124,7 +126,8 @@ RUN pip install --no-cache-dir --break-system-packages \
124126
openpyxl python-docx \
125127
jinja2 pyyaml python-dotenv markdown \
126128
rich click tqdm \
127-
playwright
129+
playwright \
130+
apprise
128131

129132
# ---------- Python packages (full only) ----------
130133
RUN if [ "$VARIANT" = "full" ]; then \
@@ -163,13 +166,13 @@ RUN echo "${VARIANT}" > /etc/holyclaude-variant
163166
# ---------- Copy config files ----------
164167
COPY scripts/entrypoint.sh /usr/local/bin/entrypoint.sh
165168
COPY scripts/bootstrap.sh /usr/local/bin/bootstrap.sh
166-
COPY scripts/notify.sh /usr/local/bin/notify.sh
169+
COPY scripts/notify.py /usr/local/bin/notify.py
167170
COPY config/settings.json /usr/local/share/holyclaude/settings.json
168171
COPY config/claude-memory-full.md /usr/local/share/holyclaude/claude-memory-full.md
169172
COPY config/claude-memory-slim.md /usr/local/share/holyclaude/claude-memory-slim.md
170173
RUN chmod +x /usr/local/bin/entrypoint.sh \
171174
/usr/local/bin/bootstrap.sh \
172-
/usr/local/bin/notify.sh
175+
/usr/local/bin/notify.py
173176

174177
# ---------- s6-overlay service definitions ----------
175178
COPY s6-overlay/s6-rc.d/cloudcli/type /etc/s6-overlay/s6-rc.d/cloudcli/type

README.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,10 @@ Two flavors. Same quality. Pick your weight class.
219219

220220
```bash
221221
# Full — batteries included (recommended)
222-
docker pull CoderLuii/HolyClaude
222+
docker pull coderluii/holyclaude
223223

224224
# Slim — lean and mean
225-
docker pull CoderLuii/HolyClaude:slim
225+
docker pull coderluii/holyclaude:slim
226226
```
227227

228228
> **`latest` is always the full image.** Slim users: don't worry — when you ask Claude to do something that needs a missing tool, it installs it in seconds. You get the same capabilities, just with a smaller initial download.
@@ -246,7 +246,7 @@ The "I just want it running" template. Copy this entire block into a `docker-com
246246

247247
services:
248248
holyclaude:
249-
image: CoderLuii/HolyClaude:latest # Full image (use :slim for smaller download)
249+
image: coderluii/holyclaude:latest # Full image (use :slim for smaller download)
250250
container_name: holyclaude
251251
hostname: holyclaude
252252
restart: unless-stopped
@@ -308,7 +308,7 @@ Same image, every knob exposed. Copy this entire block into a `docker-compose.ya
308308

309309
services:
310310
holyclaude:
311-
image: CoderLuii/HolyClaude:latest # Full image (use :slim for smaller download)
311+
image: coderluii/holyclaude:latest # Full image (use :slim for smaller download)
312312
container_name: holyclaude
313313
hostname: holyclaude
314314
restart: unless-stopped
@@ -374,13 +374,18 @@ services:
374374
# - CHOKIDAR_USEPOLLING=1
375375
# - WATCHFILES_FORCE_POLLING=true
376376
#
377-
# PUSH NOTIFICATIONS (optional)
378-
# Get notified on your phone when Claude finishes a task or hits an error.
379-
# Uses Pushover (https://pushover.net). Also requires creating a flag file
377+
# NOTIFICATIONS (optional)
378+
# Get notified when Claude finishes a task or hits an error.
379+
# Uses Apprise — supports 100+ services. Also requires creating a flag file
380380
# inside the container: touch ~/.claude/notify-on
381381
#
382-
# - PUSHOVER_APP_TOKEN=your_token
383-
# - PUSHOVER_USER_KEY=your_key
382+
# - NOTIFY_DISCORD=discord://webhook_id/webhook_token
383+
# - NOTIFY_TELEGRAM=tg://bot_token/chat_id
384+
# - NOTIFY_PUSHOVER=pover://user_key@app_token
385+
# - NOTIFY_SLACK=slack://token_a/token_b/token_c
386+
# - NOTIFY_EMAIL=mailto://user:pass@gmail.com?to=you@gmail.com
387+
# - NOTIFY_GOTIFY=gotify://hostname/token
388+
# - NOTIFY_URLS= # catch-all: comma-separated Apprise URLs
384389
#
385390
# AI PROVIDER API KEYS (optional)
386391
# These are for the OTHER AI CLIs — not Claude Code itself.
@@ -406,7 +411,7 @@ docker compose up -d
406411
| **Performance** | Node.js memory ceiling | Only if you hit OOM errors on large projects |
407412
| **User mapping** | File permissions between container and host | If you get "permission denied" (`id -u` and `id -g` on your host) |
408413
| **SMB/CIFS** | File watcher polling mode | Only if your volumes live on a NAS or network share |
409-
| **Notifications** | Push alerts to your phone via Pushover | If you want to walk away and know when Claude is done |
414+
| **Notifications** | Push alerts via Apprise (Discord, Telegram, Slack, Email, 100+ services) | If you want to walk away and know when Claude is done |
410415
| **AI providers** | API keys for Gemini, Codex, Cursor | If you want to use AI CLIs other than Claude |
411416

412417
> **Every single environment variable is optional.** The container runs perfectly with just `TZ=UTC`. Everything else has sensible defaults or is handled through the web UI.
@@ -431,8 +436,13 @@ The complete reference. Every variable, what it defaults to, what it does.
431436
| `GIT_USER_EMAIL` | `noreply@holyclaude.local` | Git commit email (set once on first boot) |
432437
| `CHOKIDAR_USEPOLLING` | *(unset)* | Set to `1` for SMB/CIFS — enables polling file watchers |
433438
| `WATCHFILES_FORCE_POLLING` | *(unset)* | Set to `true` for SMB/CIFS — enables Python polling |
434-
| `PUSHOVER_APP_TOKEN` | *(unset)* | Pushover app token for push notifications |
435-
| `PUSHOVER_USER_KEY` | *(unset)* | Pushover user key for push notifications |
439+
| `NOTIFY_DISCORD` | *(unset)* | Discord webhook URL for notifications |
440+
| `NOTIFY_TELEGRAM` | *(unset)* | Telegram bot URL for notifications |
441+
| `NOTIFY_PUSHOVER` | *(unset)* | Pushover URL for notifications |
442+
| `NOTIFY_SLACK` | *(unset)* | Slack webhook URL for notifications |
443+
| `NOTIFY_EMAIL` | *(unset)* | Email (SMTP) URL for notifications |
444+
| `NOTIFY_GOTIFY` | *(unset)* | Gotify URL for notifications |
445+
| `NOTIFY_URLS` | *(unset)* | Catch-all — comma-separated [Apprise URLs](https://github.com/caronc/apprise/wiki) |
436446
| `GEMINI_API_KEY` | *(unset)* | Google Gemini API key |
437447
| `OPENAI_API_KEY` | *(unset)* | OpenAI API key (for Codex CLI — NOT ChatGPT) |
438448
| `CURSOR_API_KEY` | *(unset)* | Cursor API key |
@@ -661,7 +671,7 @@ holyclaude/
661671
├── scripts/ # Container lifecycle scripts
662672
│ ├── bootstrap.sh # First-run setup
663673
│ ├── entrypoint.sh # Container entrypoint
664-
│ └── notify.sh # Notification helper
674+
│ └── notify.py # Notification helper (Apprise)
665675
├── s6-overlay/ # Process supervision (s6-rc services)
666676
├── Dockerfile # Single-stage build
667677
├── docker-compose.yaml # Quick start (minimal config)
@@ -742,17 +752,19 @@ This is how I personally run it. Edit `./data/claude/settings.json` on your host
742752

743753
## :bell: Notifications
744754

745-
Walk away from your computer and know when Claude is done. Uses [Pushover](https://pushover.net/) for push notifications to your phone.
755+
Walk away from your computer and know when Claude is done. Uses [Apprise](https://github.com/caronc/apprise) for notifications — supports 100+ services including Discord, Telegram, Slack, Email, Pushover, Gotify, and more.
746756

747757
**To enable:**
748758

749-
1. Add to your compose `environment`:
759+
1. Add one or more `NOTIFY_*` variables to your compose `environment`:
750760
```yaml
751-
- PUSHOVER_APP_TOKEN=your_token
752-
- PUSHOVER_USER_KEY=your_key
761+
- NOTIFY_DISCORD=discord://webhook_id/webhook_token
762+
- NOTIFY_TELEGRAM=tg://bot_token/chat_id
753763
```
754764
2. Inside the container: `touch ~/.claude/notify-on`
755765

766+
See [configuration docs](docs/configuration.md#notifications-apprise) for all supported variables and URL formats.
767+
756768
**To disable:** `rm ~/.claude/notify-on`
757769

758770
**Events that trigger notifications:**
@@ -761,7 +773,7 @@ Walk away from your computer and know when Claude is done. Uses [Pushover](https
761773
| `stop` | Claude finished the current task |
762774
| `error` | A tool use failure occurred |
763775

764-
> Completely silent when not configured. No tokens set? No flag file? Zero network calls. Zero log spam. Zero overhead.
776+
> Completely silent when not configured. No `NOTIFY_*` vars set? No flag file? Zero network calls. Zero log spam. Zero overhead.
765777

766778
<p align="right">
767779
<a href="#top">↑ back to top</a>
@@ -784,7 +796,7 @@ Your data persists in `./data/claude` and `./workspace` — upgrading only repla
784796
To pin a specific version instead of `latest`:
785797

786798
```yaml
787-
image: CoderLuii/HolyClaude:1.0.0 # instead of :latest
799+
image: coderluii/holyclaude:1.1.0 # instead of :latest
788800
```
789801

790802
<p align="right">
@@ -877,7 +889,7 @@ These are not HolyClaude bugs — they're upstream issues or intentional trade-o
877889
| "Continue in Shell" button broken | CloudCLI upstream bug (race condition in terminal init) | Use the **Web Terminal** plugin instead (pre-installed) |
878890
| Cursor CLI "Command timeout" | No API key configured — cosmetic only, doesn't affect anything | Set `CURSOR_API_KEY` or ignore |
879891
| CloudCLI account lost on rebuild | SQLite can't persist on network mounts — intentional trade-off | Re-create account (~10 seconds) |
880-
| Web push notifications "not supported" | Browser limitation in CloudCLI, standard behavior | Use Pushover notifications instead |
892+
| Web push notifications "not supported" | Browser limitation in CloudCLI, standard behavior | Use Apprise notifications instead (see [Notifications](#bell-notifications)) |
881893

882894
<p align="right">
883895
<a href="#top">↑ back to top</a>
@@ -903,7 +915,7 @@ docker build --build-arg VARIANT=slim -t holyclaude:slim .
903915
docker buildx build --platform linux/arm64 -t holyclaude .
904916
```
905917

906-
Then use `image: holyclaude` instead of `image: CoderLuii/HolyClaude:latest` in your compose file.
918+
Then use `image: holyclaude` instead of `image: coderluii/holyclaude:latest` in your compose file.
907919

908920
<p align="right">
909921
<a href="#top">↑ back to top</a>
@@ -938,7 +950,8 @@ What's coming next:
938950
| Status | Feature |
939951
|--------|---------|
940952
| 🔜 | **ARM-native builds** — optimized native ARM64 images, not just emulated |
941-
| 🔜 | **Webhook notifications** — Discord, Slack, and custom webhook alerts alongside Pushover |
953+
| 🔜 | **VS Code tunnel integration** — built-in VS Code Server or tunnel for connecting from VS Code desktop |
954+
| 🔜 | **Notification routing** — different notification destinations per event type (errors to Telegram, completions to Discord) |
942955

943956
Have an idea? [Start a discussion](https://github.com/CoderLuii/HolyClaude/discussions) or [request a feature](https://github.com/CoderLuii/HolyClaude/issues/new?template=feature_request.yml).
944957

config/claude-memory-full.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ gh issue list
119119
gh pr merge
120120
```
121121

122-
## Notifications (Pushover)
122+
## Notifications (Apprise)
123123

124-
Optional push notifications to your phone. Disabled by default.
124+
Optional push notifications via [Apprise](https://github.com/caronc/apprise) — supports 100+ services (Discord, Telegram, Slack, Email, Pushover, Gotify, and more). Disabled by default.
125125

126126
**To enable:**
127-
1. Set `PUSHOVER_APP_TOKEN` and `PUSHOVER_USER_KEY` environment variables
127+
1. Set one or more `NOTIFY_*` environment variables (e.g. `NOTIFY_DISCORD`, `NOTIFY_TELEGRAM`, `NOTIFY_PUSHOVER`)
128128
2. Create the flag file: `touch ~/.claude/notify-on`
129129

130130
**To disable:** `rm ~/.claude/notify-on`

config/claude-memory-slim.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ gh issue list
157157
gh pr merge
158158
```
159159

160-
## Notifications (Pushover)
160+
## Notifications (Apprise)
161161

162-
Optional push notifications to your phone. Disabled by default.
162+
Optional push notifications via [Apprise](https://github.com/caronc/apprise) — supports 100+ services (Discord, Telegram, Slack, Email, Pushover, Gotify, and more). Disabled by default.
163163

164164
**To enable:**
165-
1. Set `PUSHOVER_APP_TOKEN` and `PUSHOVER_USER_KEY` environment variables
165+
1. Set one or more `NOTIFY_*` environment variables (e.g. `NOTIFY_DISCORD`, `NOTIFY_TELEGRAM`, `NOTIFY_PUSHOVER`)
166166
2. Create the flag file: `touch ~/.claude/notify-on`
167167

168168
**To disable:** `rm ~/.claude/notify-on`

config/settings.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"hooks": [
1313
{
1414
"type": "command",
15-
"command": "/usr/local/bin/notify.sh stop"
15+
"command": "/usr/local/bin/notify.py stop"
1616
}
1717
]
1818
}
@@ -22,7 +22,7 @@
2222
"hooks": [
2323
{
2424
"type": "command",
25-
"command": "/usr/local/bin/notify.sh error"
25+
"command": "/usr/local/bin/notify.py error"
2626
}
2727
]
2828
}

docker-compose.full.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,14 @@ services:
4343
# - CHOKIDAR_USEPOLLING=1
4444
# - WATCHFILES_FORCE_POLLING=true
4545

46-
# --- Notifications (Pushover — optional) ---
47-
# - PUSHOVER_APP_TOKEN=
48-
# - PUSHOVER_USER_KEY=
46+
# --- Notifications (uncomment services you want) ---
47+
# - NOTIFY_DISCORD=discord://webhook_id/webhook_token
48+
# - NOTIFY_TELEGRAM=tg://bot_token/chat_id
49+
# - NOTIFY_PUSHOVER=pover://user_key@app_token
50+
# - NOTIFY_SLACK=slack://token_a/token_b/token_c
51+
# - NOTIFY_EMAIL=mailto://user:pass@gmail.com?to=you@gmail.com
52+
# - NOTIFY_GOTIFY=gotify://hostname/token
53+
# - NOTIFY_URLS= # catch-all: comma-separated Apprise URLs
4954

5055
# --- AI provider API keys (optional — can also set via web UI) ---
5156
# - GEMINI_API_KEY=

docs/CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ All notable changes to HolyClaude will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
66

7-
## [1.0.0] - 2026-03-21
7+
## [1.1.0] - 03/25/2026
8+
9+
### Added
10+
- Apprise notification engine with support for 100+ services (Discord, Telegram, Slack, Email, Gotify, and more)
11+
- Individual `NOTIFY_*` environment variables for easy per-service configuration
12+
- Catch-all `NOTIFY_URLS` for any Apprise-supported service
13+
14+
### Changed
15+
- Notification backend replaced from Pushover to Apprise
16+
17+
### Removed
18+
- **BREAKING:** `PUSHOVER_APP_TOKEN` and `PUSHOVER_USER_KEY` environment variables removed. Migrate to `NOTIFY_PUSHOVER=pover://user_key@app_token`. See [configuration docs](configuration.md#notifications-apprise) for details.
19+
20+
## [1.0.0] - 03/21/2026
821

922
Initial public release.

docs/configuration.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,24 @@ Only needed if your volumes are on a network share (Samba, NAS, etc.):
4949
| `CHOKIDAR_USEPOLLING` | (unset) | Set to `1` — enables polling for file watchers |
5050
| `WATCHFILES_FORCE_POLLING` | (unset) | Set to `true` — enables polling for Python watchers |
5151

52-
### Notifications (Pushover)
52+
### Notifications (Apprise)
53+
54+
HolyClaude uses [Apprise](https://github.com/caronc/apprise) for notifications, supporting 100+ services including Discord, Telegram, Slack, Email, Pushover, Gotify, and more.
5355

5456
| Variable | Default | Description |
5557
|----------|---------|-------------|
56-
| `PUSHOVER_APP_TOKEN` | (unset) | Your Pushover application token |
57-
| `PUSHOVER_USER_KEY` | (unset) | Your Pushover user key |
58+
| `NOTIFY_DISCORD` | *(unset)* | Discord webhook — `discord://webhook_id/webhook_token` |
59+
| `NOTIFY_TELEGRAM` | *(unset)* | Telegram bot — `tg://bot_token/chat_id` |
60+
| `NOTIFY_PUSHOVER` | *(unset)* | Pushover — `pover://user_key@app_token` |
61+
| `NOTIFY_SLACK` | *(unset)* | Slack webhook — `slack://token_a/token_b/token_c` |
62+
| `NOTIFY_EMAIL` | *(unset)* | Email (SMTP) — `mailto://user:pass@gmail.com?to=you@gmail.com` |
63+
| `NOTIFY_GOTIFY` | *(unset)* | Gotify — `gotify://hostname/token` |
64+
| `NOTIFY_URLS` | *(unset)* | Catch-all — comma-separated [Apprise URLs](https://github.com/caronc/apprise/wiki) |
5865

5966
Notifications also require the flag file `~/.claude/notify-on` to exist inside the container. Create it with `touch ~/.claude/notify-on`.
6067

68+
**Migrating from Pushover (v1.0.0):** Replace `PUSHOVER_APP_TOKEN` and `PUSHOVER_USER_KEY` with a single variable: `NOTIFY_PUSHOVER=pover://user_key@app_token`
69+
6170
### AI Provider API Keys
6271

6372
These can also be set through the CloudCLI web UI.

docs/dockerhub-description.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ Credentials stored locally in your bind-mounted `./data/claude` directory. We do
7878
| `PUID` | Container user UID | `1000` |
7979
| `PGID` | Container user GID | `1000` |
8080
| `CHOKIDAR_USEPOLLING` | Enable polling for NAS/SMB mounts | unset |
81+
| `NOTIFY_DISCORD` | Discord webhook URL for notifications | unset |
82+
| `NOTIFY_TELEGRAM` | Telegram bot URL for notifications | unset |
83+
| `NOTIFY_PUSHOVER` | Pushover URL for notifications | unset |
84+
| `NOTIFY_SLACK` | Slack webhook URL for notifications | unset |
85+
| `NOTIFY_URLS` | Catch-all Apprise notification URLs | unset |
8186

8287
## Volumes
8388

0 commit comments

Comments
 (0)