Compare commits

..

58 Commits

Author SHA1 Message Date
alexbelgium
fc98bacb5d Updater bot : openproject updated to 17.7.2 (upstream 17.7.2) 2026-08-13 14:41:37 +02:00
alexbelgium
12ab3792e7 Updater bot : nextcloud updated to 34.0.3 (upstream 34.0.3) 2026-08-13 14:41:22 +02:00
Alexandre
d70a76298a fix(ci): retry a failed add-on build once before auto-reverting the push (#2971)
A single failing matrix leg in the builder reverts the entire push, so any
transient error inside a build silently undoes a good version bump.

Observed on zoneminder 1.38.4 (run 31678876409, attempt 1): the aarch64 leg
failed after 44 s inside the ha_autoapps.sh layer with

  curl: (92) HTTP/2 stream 1 was not closed cleanly: REFUSED_STREAM (err 7)
  gzip: stdin: unexpected end of file
  tar: Error is not recoverable: exiting now

while the amd64 leg built and pushed 1.38.4 to GHCR. revert-on-failure then
pushed 0ee26fc72 reverting the bump; a manual re-run of the same source went
fully green. Because that re-run flips the run conclusion to success, these
incidents do not even show up in run-conclusion statistics.

The build-image step is now run tolerantly (continue-on-error) and repeated
once when the first attempt fails. Only a second failure reaches
revert-on-failure, so genuinely broken add-ons are still reverted, one build
later than before.

The retry is unconditional rather than gated on the log text looking
transient: BuildKit reformats error strings and registry/runner failures
spell themselves many different ways, so a text classifier would eventually
stop reverting real breakage. It is also cheap - the add-ons that fail
deterministically on every push (ente, comixed, binance-trading-bot) each
fail in 16-34 s.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 11:55:05 +02:00
Alexandre
2ea7fb0d90 Update updater.json 2026-08-13 10:15:43 +02:00
Alexandre
4976085482 nobuild 2026-08-13 10:15:02 +02:00
Alexandre
91a307d15f Update Dockerfile 2026-08-13 10:14:44 +02:00
Alexandre
78aa719ad7 Update CHANGELOG.md 2026-08-13 10:14:24 +02:00
GitHub Actions
0ee26fc22d Revert "Updater bot : zoneminder updated to 1.38.4 (upstream 1.38.4)"
This reverts commit af7d00cd6f.
2026-08-13 07:45:25 +00:00
alexbelgium
f5cd090828 Updater bot : zzz_archived_code-server updated to 4.132.0 (upstream 4.132.0) 2026-08-13 09:42:31 +02:00
alexbelgium
af7d00cd6f Updater bot : zoneminder updated to 1.38.4 (upstream 1.38.4) 2026-08-13 09:42:23 +02:00
alexbelgium
61d78286f4 Updater bot : scrutiny_original updated to v0.9.3 (upstream v0.9.3) 2026-08-13 09:40:34 +02:00
alexbelgium
c355017a8f Updater bot : scrutiny_fa_original updated to v0.9.3 (upstream v0.9.3) 2026-08-13 09:40:29 +02:00
alexbelgium
391155d5a6 Updater bot : sabnzbd updated to 5.1.0 (upstream 5.1.0) 2026-08-13 09:40:17 +02:00
alexbelgium
eaf03eccab Updater bot : prowlarr updated to 2.6.2.5548.10 (upstream nightly-2.6.2.5548-ls10) 2026-08-13 09:39:56 +02:00
alexbelgium
39e8c884ba Updater bot : plex updated to 1.43.3.10861.319 (upstream 1.43.3.10861-07dfddaeb-ls319) 2026-08-13 09:39:43 +02:00
alexbelgium
7ef17e2111 Updater bot : obsidian_syncserver_ssl updated to 3.5.2.1 (upstream 3.5.2.1-nouveau) 2026-08-13 09:39:26 +02:00
alexbelgium
17b5843cc6 Updater bot : obsidian_syncserver_solo updated to 3.5.2.1 (upstream 3.5.2.1-nouveau) 2026-08-13 09:39:23 +02:00
alexbelgium
d2b251f08a Updater bot : maintainerr updated to 3.22.1 (upstream 3.22.1) 2026-08-13 09:38:48 +02:00
alexbelgium
28bd43338a Updater bot : komga updated to 1.26.3 (upstream 1.26.3) 2026-08-13 09:38:34 +02:00
alexbelgium
e1f16686f9 Updater bot : kometa updated to 2.4.7 (upstream 2.4.7) 2026-08-13 09:38:29 +02:00
alexbelgium
aef1e190b1 Updater bot : jackett updated to 0.24.2404 (upstream 0.24.2404) 2026-08-13 09:38:07 +02:00
alexbelgium
d897b8ac0c Updater bot : grav updated to 2.0.18 (upstream 2.0.18) 2026-08-13 09:37:38 +02:00
alexbelgium
33504ac4b2 Updater bot : epicgamesfree updated to 2026.08.13 (upstream debian-2026-08-13) 2026-08-13 09:37:01 +02:00
alexbelgium
239e5cffe7 Updater bot : ente updated to 4.4.26 (upstream 1.3.61) 2026-08-13 09:36:58 +02:00
alexbelgium
7b498b6b63 Updater bot : emby_beta updated to 4.10.0.24 (upstream 4.10.0.24) 2026-08-13 09:36:46 +02:00
alexbelgium
b7ae483be0 Updater bot : elasticsearch updated to 8.19.20 (upstream 8.19.20) 2026-08-13 09:36:39 +02:00
alexbelgium
7a79f9738d Updater bot : collabora updated to 26.04.3.1.1 (upstream 26.04.3.1.1) 2026-08-13 09:36:33 +02:00
alexbelgium
73ab4dfe7c Updater bot : cleanuparr updated to 2.10.5 (upstream 2.10.5) 2026-08-13 09:36:24 +02:00
alexbelgium
d4270df3f5 Updater bot : claude_desktop updated to 07308544 (upstream v3.2.2+claude1.28929.0) 2026-08-13 09:36:19 +02:00
alexbelgium
a2669e79d5 Updater bot : calibre_web updated to 0.6.27 (upstream 0.6.27) 2026-08-13 09:36:11 +02:00
alexbelgium
b0477779f9 Updater bot : browserless_chrome updated to 2.55.4 (upstream 2.55.4) 2026-08-13 09:36:03 +02:00
alexbelgium
338a08a3a5 Updater bot : browser_chromium updated to 2026.08.13 (upstream version-e8713bf7) 2026-08-13 09:35:58 +02:00
alexbelgium
46dd762e4c Updater bot : browser_brave updated to 1.93.136-ls122 (upstream 1.93.136-ls122) 2026-08-13 09:35:46 +02:00
alexbelgium
87c442d2bc Updater bot : birdnet-pipy updated to 0.8.6 (upstream 0.8.6) 2026-08-13 09:34:58 +02:00
alexbelgium
382db1d401 Updater bot : aurral updated to 2.4.0 (upstream 2.4.0) 2026-08-13 09:34:34 +02:00
github-actions
8e7c087a49 Github bot : issues linked to readme 2026-08-13 06:10:42 +00:00
Alexandre
19d36c2d33 fix(qbittorrent): allow ::/0 so WireGuard stops dropping IPv6 traffic (#2970)
* fix(qbittorrent): allow ::/0 so WireGuard stops dropping IPv6

_wireguard_up() sets allowed_ip_types[0.0.0.0/0] when the config declares an IPv4 Address, but the IPv6 branch never sets ::/0. The peer therefore only accepts the tunnel's own /128, while _routing_add() installs a default IPv6 route into the interface, so every outbound IPv6 packet is routed into WireGuard and dropped.

Regression from 7af8610a25; the pre-refactor code appended ::/0 in the same place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Update config.yaml

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 08:10:23 +02:00
Alexandre
57cbc726f6 docs(skill): terse chat replies in the add-on workflow (#2969)
Adds a short answer-style rule to the hassio-addon-workflow skill: no
pleasantries, no tool-call narration, no dumped logs, no re-printing what
is already in context. Uncertainty markers, negations, numbers and
verbatim technical text are explicitly exempt, so the Verified / Checked /
Assumed discipline in step 9 is not compressed away. Persisted text
(commits, CHANGELOG, PR bodies, review replies, the report) stays prose.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 22:42:36 +02:00
Alexandre
312c4cc949 Update updater.json 2026-08-12 19:58:40 +02:00
github-actions
eec248c9d0 GitHub bot : README updated 2026-08-12 17:19:26 +00:00
github-actions
a6c87588ad GitHub bot: changelog [nobuild] 2026-08-12 15:25:10 +00:00
Enrique
dbd74e0391 Obsidian Sync Server add-ons (CouchDB LiveSync backend) - three flavours (#2965)
* full commit obsidian

* updates on readme and clarification for addons community for easy tag on
issues

* becouse of https://github.com/alexbelgium/hassio-addons/issues/2966

* restore build.yaml for obsidian addons

---------

Co-authored-by: ToledoEM <8144940+ToledoEM@users.noreply.github.com>
2026-08-12 17:21:14 +02:00
github-actions
8d04564f94 Github bot : issues linked to readme 2026-08-12 12:33:50 +00:00
Alexandre
3af76ebb7a fix: wait for the Supervisor API before running add-on startup scripts (#2967)
* fix: wait for the Supervisor API before running startup scripts

48 add-ons build their nginx ingress config out of bashio::addon.ip_address
and bashio::addon.ingress_port. Both come from one GET /addons/self/info, and
when that is answered before the Supervisor is ready bashio prints nothing.
Nine add-ons paste the result straight into a sed and end up writing
"listen : default_server;", which nginx rejects with `invalid port in ":"`;
the other 39 assign first and abort under set -e, leaving %%port%%
placeholders. Either way ingress is dead for that boot.

ha_entrypoint.sh now polls /addons/self/info once before the cont-init loop
and waits until it reports this add-on's ip_address (and, for ingress
add-ons, a non-zero ingress_port). Bounded at 30s via HA_SUPERVISOR_WAIT,
never fatal, and skipped entirely without SUPERVISOR_TOKEN or curl. When the
Supervisor is already up -- the normal case -- it costs one request.

qBittorrent is bumped so the change is actually built and reaches the add-on
with the open report; the other add-ons pick it up on their next rebuild.

Refs #2949, #2962

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix: harden the Supervisor wait after bot review

- HA_SUPERVISOR_WAIT=08 was accepted by test -gt but read as octal by
  arithmetic expansion, leaving deadline empty; the comparison then errored
  every iteration and the loop never exited, hanging start-up. Digits-only
  validation plus base-10 forcing.
- A request started near the deadline could run --max-time past it. The
  per-request timeout is now capped to the time remaining, and the retry
  sleep is skipped once the budget is gone, so the ceiling is exact.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* refactor: probe the Supervisor through bashio instead of curl + sed

The wait reimplemented what the 48 consumers already do: it called
/addons/self/info with curl and picked the fields out with sed. That parallel
implementation was where one of the review findings landed, and it left a
residual race -- proving the API answered a moment ago says nothing about the
bashio call that runs next.

Probing through bashio removes both. bashio caches a successful
/addons/self/info under ${CACHE_DIR:-/tmp/.bashio}, so once the probe returns,
every bashio::addon.* call in every cont-init script reads that file rather
than asking the Supervisor again. Verified: one bashio::addon.ip_address call
writes a 26 KB addons.self.info.cache.

One call also settles all the fields, so the separate ingress/ingress_port
branch was redundant and is gone: a populated ip_address means the whole object
is cached. 36 -> 31 code lines.

Two consequences handled: bashio's own curl carries no --max-time (api.sh:41),
so each attempt is bounded with timeout; and bashio-standalone.sh answers these
calls from environment variables without ever contacting the Supervisor, so
BASHIO_LIB_FULL gates the probe to images carrying the real library.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:33:28 +02:00
Alexandre
fa348c7051 Refactor addon build-args to use yq for YAML files
https://github.com/alexbelgium/hassio-addons/issues/2966
2026-08-12 14:29:41 +02:00
github-actions
ac205b7901 Github bot : issues linked to readme 2026-08-12 12:05:59 +00:00
Alexandre
295efe88e2 Update onpr_check-pr.yaml 2026-08-12 13:45:45 +02:00
Alexandre
4c7c1f99a4 Update onpush_builder.yaml 2026-08-12 13:45:39 +02:00
Alexandre
1e3ec448df Update build.json 2026-08-12 13:31:00 +02:00
github-actions
3e384fb068 GitHub bot: changelog [nobuild] 2026-08-12 09:09:39 +00:00
Alexandre
843a909366 Update config.yaml 2026-08-12 11:07:53 +02:00
Alexandre
c7d48baba1 Update config.yaml 2026-08-12 11:07:33 +02:00
Alexandre
c53342f2e8 fix(komga): rewrite the cookie path onto the ingress entry (#2964)
Komga scopes its cookies to its servlet context path, so the browser never
sent them back from the ingress url and every request after a successful
login was anonymous (401).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 09:33:27 +02:00
Alexandre
bb1f7c302b fix(komga): ship an apparmor profile so local disks can be mounted (#2963)
* fix(komga): ship an apparmor profile so local disks can be mounted

Without apparmor.txt Supervisor adds no apparmor security_opt, so Docker's
default profile applies and denies mount() and raw block device access:
mount reported 'cannot mount /dev/sda1 read-only' and the kernel logged
'/dev/disk/by-label/NAS: Can't open blockdev'.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-08-12 08:41:36 +02:00
Alexandre
cfcdd94ae6 fix(komga): bound the nginx readiness probes (#2961)
* fix(komga): bound the nginx readiness probes and log an exhausted wait

Follow-up to #2960, which merged one commit before this landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(komga): use a wall clock deadline for the readiness wait

An attempt count plus a per probe timeout stretched the wait to roughly twice
the advertised 15 minute ceiling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 08:14:28 +02:00
github-actions
985f570263 Github bot : issues linked to readme 2026-08-12 04:01:32 +00:00
github-actions
e7a07b1d15 GitHub bot : README updated 2026-08-11 17:19:27 +00:00
Alexandre
44c58ba22b Update config.yaml nobuild 2026-08-11 18:59:23 +02:00
149 changed files with 2189 additions and 107 deletions

View File

@@ -11,6 +11,16 @@ description: >-
# Home Assistant add-on workflow
**Answer style.** Chat replies are terse: no pleasantries, no tool-call narration, no decorative
tables or emoji, no dumped logs — quote the shortest decisive line, and don't re-read or re-print
what is already in context. Fragments and dropped articles are fine. Never compressed: uncertainty
markers ("likely", "assumed", "not verified"), negations (`not`/`never`/`no`/`only`), numbers,
units, technical terms, code blocks, error strings — step 9's Verified/Checked/Assumed distinction
outranks brevity every time. Write in full prose, not fragments, for security warnings,
irreversible-action confirmations, and any multi-step sequence a fragment could make ambiguous.
Persisted text is prose too: commits, CHANGELOG entries, PR bodies, review-thread replies, the
step 10 report.
Triage first, then one of two paths:
- **Light** — typo/doc fixes, CHANGELOG edits, version bumps, one-file edits at ladder levels

View File

@@ -1,5 +1,6 @@
{
"aurral": "petruknw",
"bentopdf": "ToledoEM",
"cleanuparr": "PierreNa",
"gitea": "baldarn",
"kometa": "akrigator",
@@ -8,7 +9,10 @@
"manyfold": "ToledoEM",
"navidrome": "baldarn",
"netalertx": "jokob-sk",
"nginx proxy manager": "ToledoEM",
"nginx_webserver_proxy": "ToledoEM",
"obsidian_syncserver_npm": "ToledoEM",
"obsidian_syncserver_solo": "ToledoEM",
"obsidian_syncserver_ssl": "ToledoEM",
"openproject": "baldarn",
"resiliosync": "tyjtyj",
"spotweb": "woutercoppens",

View File

@@ -91,7 +91,7 @@ jobs:
uses: actions/checkout@v7.0.1
- name: 🔎 Run Home Assistant Add-on Lint
uses: frenck/action-addon-linter@f6bef06a4cee6c67924b0a70be643aacb8500a43
uses: frenck/action-addon-linter@v2
with:
path: "./${{ matrix.addon }}"
@@ -193,15 +193,15 @@ jobs:
- name: 💽 Create addon build-args
id: build_args
shell: bash
run: |
{
echo "armhf=BUILD_FROM=$(jq -r .build_from.armhf // empty ${{ steps.information.outputs.build }})"
echo "armv7=BUILD_FROM=$(jq -r .build_from.armv7 // empty ${{ steps.information.outputs.build }})"
echo "aarch64=BUILD_FROM=$(jq -r .build_from.aarch64 // empty ${{ steps.information.outputs.build }})"
echo "amd64=BUILD_FROM=$(jq -r .build_from.amd64 // empty ${{ steps.information.outputs.build }})"
echo "i386=BUILD_FROM=$(jq -r .build_from.i386 // empty ${{ steps.information.outputs.build }})"
} >> "$GITHUB_OUTPUT"
build_file="${{ steps.information.outputs.build }}"
case "$build_file" in
*.yaml|*.yml) build_json="$(yq -o=json '.' "$build_file")" ;;
*) build_json="$(cat "$build_file")" ;;
esac
for arch in armhf armv7 aarch64 amd64 i386; do
echo "${arch}=BUILD_FROM=$(printf '%s' "$build_json" | jq -r --arg a "$arch" '.build_from[$a] // empty')"
done >> "$GITHUB_OUTPUT"
- name: 🏗️ Set up QEMU
uses: docker/setup-qemu-action@v4

View File

@@ -114,7 +114,7 @@ jobs:
steps:
- uses: actions/checkout@v7.0.1
- name: Run Home Assistant Add-on Lint
uses: frenck/action-addon-linter@f6bef06a4cee6c67924b0a70be643aacb8500a43
uses: frenck/action-addon-linter@v2
with:
path: "./${{ matrix.addon }}"
@@ -285,8 +285,52 @@ jobs:
echo "${{ matrix.arch }} is not a valid architecture for ${{ matrix.addon }}, skipping build."
fi
# A single failing leg here auto-reverts the whole push (revert-on-failure
# below), so a transient error inside the build - a truncated download in
# a RUN layer, a registry hiccup - silently undoes a perfectly good
# version bump. Seen on zoneminder 1.38.4 (run 31678876409): the aarch64
# leg died on "curl: (92) HTTP/2 stream 1 was not closed cleanly:
# REFUSED_STREAM", the commit was reverted, and a manual re-run of the
# identical source then went green. (A lost runner or a cancelled job is
# not covered by this - no later step gets to run at all.)
#
# So: build once tolerantly, and only let a second failure reach the
# revert. A genuinely broken add-on fails twice and is still reverted,
# one build later. Retrying is unconditional rather than gated on the
# log text looking "transient" - BuildKit reformats error strings and
# registry/runner failures spell themselves a dozen ways, so classifying
# by log text would silently stop reverting real breakage. It is also
# cheap: the add-ons that fail deterministically on every push each fail
# in 16-34 s.
- name: Build ${{ matrix.addon }} add-on
id: build
if: steps.info.outputs.build_arch == 'true' && steps.info.outputs.has_dockerfile == 'true'
continue-on-error: true
uses: home-assistant/builder/actions/build-image@2026.06.0
with:
arch: ${{ matrix.arch }}
cache-gha: "false"
cache-gha-scope: ${{ matrix.addon }}-${{ matrix.arch }}
context: ./${{ matrix.addon }}
file: ${{ steps.info.outputs.dockerfile }}
image: ${{ steps.info.outputs.image }}
image-tags: |
${{ steps.info.outputs.version }}
latest
version: ${{ steps.info.outputs.version }}
push: "true"
cosign: "false"
container-registry-password: ${{ secrets.GITHUB_TOKEN }}
labels: ${{ steps.info.outputs.labels }}
build-args: ${{ steps.info.outputs.build_args }}
# Keep these inputs identical to the first attempt above - this step is
# that attempt, run a second time, and nothing else. There is deliberately
# no pause in between: re-running the earlier layers already spaces the
# two network windows apart, and a sleep step would only add somewhere
# else for the retry to be skipped from.
- name: Build ${{ matrix.addon }} add-on (retry after failed attempt)
if: steps.build.outcome == 'failure'
uses: home-assistant/builder/actions/build-image@2026.06.0
with:
arch: ${{ matrix.arch }}

View File

@@ -173,9 +173,13 @@ fi
####################################
BASHIO_LIB=""
BASHIO_LIB_FULL=false
for f in /usr/lib/bashio/bashio.sh /usr/lib/bashio/lib.sh /usr/src/bashio/bashio.sh /usr/local/lib/bashio/bashio.sh; do
if [ -f "$f" ]; then
BASHIO_LIB="$f"
# The real library, which talks to the Supervisor. The standalone shim below only reads
# environment variables, which matters to wait_for_supervisor().
BASHIO_LIB_FULL=true
break
fi
done
@@ -188,6 +192,83 @@ if [ -z "$BASHIO_LIB" ]; then
done
fi
##############################
# Wait for the Supervisor API #
##############################
# Many cont-init scripts build their nginx ingress config out of bashio::addon.ip_address and
# bashio::addon.ingress_port. Both come from one GET /addons/self/info, and when that is answered
# before the Supervisor is ready bashio prints nothing: the add-on then either writes
# "listen : default_server;" -- which nginx rejects with `invalid port in ":"` -- or aborts under
# set -e and leaves the %%port%% placeholders in place. Either way the add-on cannot serve ingress.
# Ask for the same values here, through the same bashio calls, until they come back usable --
# rather than making 48 add-ons defend themselves against the same empty answer.
#
# Going through bashio rather than curl is what makes this reliable rather than merely likely:
# bashio caches a successful /addons/self/info under ${CACHE_DIR:-/tmp/.bashio}, so once this
# returns, every later bashio::addon.* call in every cont-init script reads that file instead of
# asking the Supervisor again. A probe that only proved the API was up a moment ago would leave
# the very next call free to fail.
#
# Bounded and never fatal: an add-on with no SUPERVISOR_TOKEN, or a Supervisor that stays
# unreachable, still has to start. HA_SUPERVISOR_WAIT (seconds, default 30) sets the ceiling; 0
# skips the wait. When the Supervisor is already up -- the normal case -- this costs one request.
wait_for_supervisor() {
local max="${HA_SUPERVISOR_WAIT:-30}"
local started deadline remaining attempt announced=0
# Nothing to wait for without a token. The standalone shim is excluded too: it answers these
# calls from environment variables and never contacts the Supervisor, so it can never satisfy
# the probe and would burn the whole ceiling on every boot.
[ -n "${SUPERVISOR_TOKEN:-}" ] || return 0
[ "${BASHIO_LIB_FULL:-false}" = "true" ] || return 0
# bashio's own curl carries no --max-time, so each attempt is bounded from the outside.
command -v timeout >/dev/null 2>&1 || return 0
# Digits only, then forced to base 10: `test -gt` accepts a zero-padded override like 08, but
# arithmetic expansion reads it as octal and fails, which would leave the deadline empty and
# spin the loop below forever.
case "$max" in '' | *[!0-9]*) return 0 ;; esac
max=$((10#$max))
[ "$max" -gt 0 ] || return 0
started=$SECONDS
deadline=$((started + max))
while :; do
remaining=$((deadline - SECONDS))
if [ "$remaining" -le 0 ]; then
echo -e "\e[38;5;214m$(date) WARNING: Supervisor API did not report this add-on's network details within ${max}s, continuing anyway\e[0m"
return 0
fi
# No single attempt may outlive the ceiling it is bounded by.
attempt=5
[ "$remaining" -lt "$attempt" ] && attempt="$remaining"
# One call is enough to settle all of them: bashio fetches the whole /addons/self/info object
# and caches it, so a populated ip_address means ingress_port and the rest are cached too.
# Run in a child shell so bashio's globals and traps stay out of the entrypoint; its own error
# logging is dropped because a failed attempt here is expected, not news.
# shellcheck disable=SC2016
if timeout "$attempt" bash -c '. "$1" && [ -n "$(bashio::addon.ip_address)" ]' \
_ "$BASHIO_LIB" >/dev/null 2>&1; then
[ "$announced" -eq 0 ] || echo "Supervisor API ready after $((SECONDS - started))s"
return 0
fi
if [ "$announced" -eq 0 ]; then
echo "Waiting for the Supervisor API to report this add-on's network details..."
announced=1
fi
# Skipped when the attempt already consumed what was left, so the sleep cannot overshoot.
[ "$((deadline - SECONDS))" -gt 0 ] && sleep 1
done
}
wait_for_supervisor
####################
# Starting scripts #
####################

View File

@@ -8,6 +8,7 @@ When an issue mentions one of these add-ons (in the title or body), a GitHub Act
| Add-on folder | Initial submitter |
| --- | --- |
| `bentopdf` | [@ToledoEM](https://github.com/ToledoEM) |
| `emby` | [@petersendev](https://github.com/petersendev) |
| `gitea` | [@baldarn](https://github.com/baldarn) |
| `kometa` | [@akrigator](https://github.com/akrigator) |
@@ -15,6 +16,10 @@ When an issue mentions one of these add-ons (in the title or body), a GitHub Act
| `manyfold` | [@ToledoEM](https://github.com/ToledoEM) |
| `navidrome` | [@baldarn](https://github.com/baldarn) |
| `netalertx` | [@jokob-sk](https://github.com/jokob-sk) |
| `nginx_webserver_proxy` | [@ToledoEM](https://github.com/ToledoEM) |
| `obsidian_syncserver_npm` | [@ToledoEM](https://github.com/ToledoEM) |
| `obsidian_syncserver_solo` | [@ToledoEM](https://github.com/ToledoEM) |
| `obsidian_syncserver_ssl` | [@ToledoEM](https://github.com/ToledoEM) |
| `openproject` | [@baldarn](https://github.com/baldarn) |
| `resiliosync` | [@tyjtyj](https://github.com/tyjtyj) |
| `spotweb` | [@woutercoppens](https://github.com/woutercoppens) |

View File

@@ -56,7 +56,7 @@ If you want to do add the repository manually, please follow the procedure highl
### Number of addons
- In the repository : 137
- In the repository : 141
- Installed : 325872
### Top 3
@@ -567,6 +567,16 @@ If you want to do add the repository manually, please follow the procedure highl
![aarch64][aarch64-badge]
![amd64][amd64-badge]
&#10003; ![image](https://api.iconify.design/mdi/book-open-page-variant.svg) [Komga](komga/) : Free and open source comics/mangas media server
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fkomga%2Fconfig.yaml)
![Update](https://img.shields.io/badge/dynamic/json?label=Updated&query=%24.last_update&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fkomga%2Fupdater.json)
![aarch64][aarch64-badge]
![amd64][amd64-badge]
![ingress][ingress-badge]
![smb][smb-badge]
![localdisks][localdisks-badge]
&#10003; ![image](https://api.iconify.design/mdi/speedometer.svg) [LibreSpeed](librespeed/) : A very lightweight speed test implemented in Javascript, using XMLHttpRequest and Web Workers
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Flibrespeed%2Fconfig.yaml)
@@ -708,6 +718,27 @@ If you want to do add the repository manually, please follow the procedure highl
![smb][smb-badge]
![localdisks][localdisks-badge]
&#10003; [Obsidian Sync Server](obsidian_syncserver_solo/) : Self-hosted Obsidian LiveSync backend on CouchDB. Plain HTTP — put your own reverse proxy in front for TLS.
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_solo%2Fconfig.yaml)
![Update](https://img.shields.io/badge/dynamic/json?label=Updated&query=%24.last_update&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_solo%2Fupdater.json)
![aarch64][aarch64-badge]
![amd64][amd64-badge]
&#10003; [Obsidian Sync Server NPM](obsidian_syncserver_npm/) : Self-hosted Obsidian LiveSync backend on CouchDB, bundled with Nginx Proxy Manager for TLS and certificate management.
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_npm%2Fconfig.yaml)
![Update](https://img.shields.io/badge/dynamic/json?label=Updated&query=%24.last_update&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_npm%2Fupdater.json)
![aarch64][aarch64-badge]
![amd64][amd64-badge]
&#10003; [Obsidian Sync Server SSL](obsidian_syncserver_ssl/) : Self-hosted Obsidian LiveSync backend on CouchDB, serving HTTPS with your own certificates from /ssl. Supports mobile Obsidian.
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_ssl%2Fconfig.yaml)
![Update](https://img.shields.io/badge/dynamic/json?label=Updated&query=%24.last_update&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_ssl%2Fupdater.json)
![aarch64][aarch64-badge]
![amd64][amd64-badge]
&#10003; [Omada (obsolete)](zzz_archived_omada/) : TP-Link Omada Controller (obsolete, use https://github.com/jkunczik/home-assistant-omada)
&emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fzzz_archived_omada%2Fconfig.yaml)

View File

@@ -1,4 +1,7 @@
## 2.4.0 (2026-08-13)
- Update to latest version from lklynet/aurral (changelog : https://github.com/lklynet/aurral/releases)
## 2.1.0 (2026-08-08)
- Update to latest version from lklynet/aurral (changelog : https://github.com/lklynet/aurral/releases)

View File

@@ -1,5 +1,5 @@
name: Aurral
version: "2.1.0"
version: "2.4.0"
slug: aurral
description: >-
Self-hosted music discovery, request management, flows, and playlist

View File

@@ -1,9 +1,9 @@
{
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "aurral",
"source": "github",
"upstream_repo": "lklynet/aurral",
"upstream_version": "2.1.0",
"upstream_version": "2.4.0",
"github_beta": false
}

View File

@@ -1,4 +1,7 @@
## 0.8.6 (2026-08-13)
- Update to latest version from Suncuss/BirdNET-PiPy (changelog : https://github.com/Suncuss/BirdNET-PiPy/releases)
## 0.8.5 (2026-08-01)
- Update to latest version from Suncuss/BirdNET-PiPy (changelog : https://github.com/Suncuss/BirdNET-PiPy/releases)

View File

@@ -96,4 +96,4 @@ schema:
ssl: bool?
slug: birdnet-pipy
url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pipy
version: "0.8.5"
version: "0.8.6"

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-08-01",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "birdnet-pipy",
"source": "github",
"upstream_repo": "Suncuss/BirdNET-PiPy",
"upstream_version": "0.8.5"
"upstream_version": "0.8.6"
}

View File

@@ -1,4 +1,7 @@
## 1.93.136-ls122 (2026-08-13)
- Update to latest version from linuxserver/docker-brave (changelog : https://github.com/linuxserver/docker-brave/releases)
## 1.93.134-ls121 (2026-08-08)
- Update to latest version from linuxserver/docker-brave (changelog : https://github.com/linuxserver/docker-brave/releases)

View File

@@ -69,5 +69,5 @@ slug: brave
tmpfs: true
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "1.93.134-ls121"
version: "1.93.136-ls122"
video: true

View File

@@ -1,9 +1,9 @@
{
"github_fulltag": "true",
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "brave",
"source": "github",
"upstream_repo": "linuxserver/docker-brave",
"upstream_version": "1.93.134-ls121"
"upstream_version": "1.93.136-ls122"
}

View File

@@ -1,4 +1,8 @@
## 2026.08.13 (2026-08-13)
- Update to latest version from linuxserver/docker-chromium (changelog : https://github.com/linuxserver/docker-chromium/releases)
- Upstream tag : version-e8713bf7
## 2026.08.01.1 (2026-08-01)
- Update to latest version from linuxserver/docker-chromium (changelog : https://github.com/linuxserver/docker-chromium/releases)
- Upstream tag : version-e2e1ec9c

View File

@@ -71,5 +71,5 @@ slug: chromium
tmpfs: true
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2026.08.01.1"
version: "2026.08.13"
video: true

View File

@@ -1,9 +1,9 @@
{
"github_fulltag": "true",
"last_update": "2026-08-01",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "chromium",
"source": "github",
"upstream_repo": "linuxserver/docker-chromium",
"upstream_version": "version-e2e1ec9c"
"upstream_version": "version-e8713bf7"
}

View File

@@ -1,4 +1,7 @@
## 2.55.4 (2026-08-13)
- Update to latest version from browserless/chrome (changelog : https://github.com/browserless/chrome/releases)
## 2.55.3 (2026-08-08)
- Update to latest version from browserless/chrome (changelog : https://github.com/browserless/chrome/releases)

View File

@@ -86,5 +86,5 @@ schema:
slug: browserless_chrome
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/browserless_chrome
version: "2.55.3"
version: "2.55.4"
webui: "[PROTO:ssl]://[HOST]:[PORT:3000]/docs"

View File

@@ -1,9 +1,9 @@
{
"github_tagfilter": "v",
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "browserless_chrome",
"source": "github",
"upstream_repo": "browserless/chrome",
"upstream_version": "2.55.3"
"upstream_version": "2.55.4"
}

View File

@@ -1,3 +1,6 @@
## 0.6.27 (2026-08-13)
- Update to latest version from linuxserver/docker-calibre-web (changelog : https://github.com/linuxserver/docker-calibre-web/releases)
## 0.6.26-2 (2026-04-06)
- Fix: Install calibre (calibredb) at build time to fix 500 error when downloading books

View File

@@ -116,5 +116,5 @@ schema:
slug: calibre-web
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/calibre_web
version: "0.6.26-2"
version: "0.6.27"
video: true

View File

@@ -1,9 +1,9 @@
{
"last_update": "2026-02-07",
"last_update": "2026-08-13",
"paused": false,
"repository": "alexbelgium/hassio-addons",
"slug": "calibre-web",
"source": "github",
"upstream_repo": "linuxserver/docker-calibre-web",
"upstream_version": "0.6.26"
"upstream_version": "0.6.27"
}

View File

@@ -1,4 +1,8 @@
## 07308544 (2026-08-13)
- Update to latest version from aaddrick/claude-desktop-debian (changelog : https://github.com/aaddrick/claude-desktop-debian/releases)
- Upstream tag : v3.2.2+claude1.28929.0
## 07308543 (2026-08-08)
- Update to latest version from linuxserver/docker-baseimage-selkies (changelog : https://github.com/linuxserver/docker-baseimage-selkies/releases)
- Upstream tag : debiantrixie-version-07308543

View File

@@ -136,5 +136,5 @@ schema:
slug: claude_desktop
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "07308543"
version: "07308544"
video: true

View File

@@ -1,9 +1,9 @@
{
"source": "github",
"upstream_repo": "linuxserver/docker-baseimage-selkies",
"upstream_repo": "aaddrick/claude-desktop-debian",
"github_fulltag": true,
"slug": "claude_desktop",
"paused": false,
"upstream_version": "debiantrixie-version-07308543",
"last_update": "2026-08-08"
"upstream_version": "v3.2.2+claude1.28929.0",
"last_update": "2026-08-13"
}

View File

@@ -1,4 +1,7 @@
## 2.10.5 (2026-08-13)
- Update to latest version from Cleanuparr/Cleanuparr (changelog : https://github.com/Cleanuparr/Cleanuparr/releases)
## 2.10.3 (2026-08-08)
- Update to latest version from Cleanuparr/Cleanuparr (changelog : https://github.com/Cleanuparr/Cleanuparr/releases)

View File

@@ -11,7 +11,7 @@
#=== Home Assistant Addon ===#
# ARGs used in FROM must be declared before any FROM instruction
ARG BUILD_UPSTREAM="2.10.3"
ARG BUILD_UPSTREAM="2.10.5"
#################
# 1 Build Image #

View File

@@ -91,5 +91,5 @@ schema:
TZ: str?
slug: cleanuparr
url: https://github.com/alexbelgium/hassio-addons/tree/master/cleanuparr
version: "2.10.3"
version: "2.10.5"
webui: "[PROTO:ssl]://[HOST]:[PORT:11011]"

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "cleanuparr",
"source": "github",
"upstream_repo": "Cleanuparr/Cleanuparr",
"upstream_version": "2.10.3"
"upstream_version": "2.10.5"
}

View File

@@ -1,4 +1,7 @@
## 26.04.3.1.1 (2026-08-13)
- Update to latest version from collabora/code
## 26.04.2.4.1 (2026-07-26)
- Rebuild on a Debian base: upstream turned collabora/code into a distroless image with no shell, which broke the addon build entirely. collabora/code stays the tracked upstream image in build.json, but is now a build stage whose payload is copied onto ghcr.io/hassio-addons/debian-base, and the addon ships its own launcher in place of the removed /start-collabora-online.sh
- build.json names the architecture explicitly again (`collabora/code:latest-amd64` and `collabora/code:latest-arm64`). The builder never passes `--platform`, so the tag is the only thing that decides which binaries land in the addon

View File

@@ -48,5 +48,5 @@ schema:
username: str
slug: collabora
url: https://github.com/alexbelgium/hassio-addons
version: "26.04.2.4.1"
version: "26.04.3.1.1"
webui: "[PROTO:ssl]://[HOST]:[PORT:9980]/browser/dist/admin/admin.html"

View File

@@ -1,9 +1,9 @@
{
"github_exclude": "sha256",
"last_update": "2026-07-26",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "collabora",
"source": "dockerhub",
"upstream_repo": "collabora/code",
"upstream_version": "26.04.2.4.1"
"upstream_version": "26.04.3.1.1"
}

View File

@@ -1,3 +1,6 @@
## 8.19.20 (2026-08-13)
- Update to latest version from elastic/elasticsearch (changelog : https://github.com/elastic/elasticsearch/releases)
## 8.19.19.2 (21-07-2026)
- Minor bugs fixed

View File

@@ -14,7 +14,7 @@
# 1 Build Image #
#################
ARG BUILD_UPSTREAM="8.19.19"
ARG BUILD_UPSTREAM="8.19.20"
# Pull from Elastic's own registry (multi-arch, published atomically with the
# GitHub release the updater tracks) rather than the Docker Hub "library"
# mirror, whose arm64/aarch64 tag lags hours behind and breaks the aarch64

View File

@@ -90,4 +90,4 @@ slug: elasticsearch
startup: services
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/elasticsearch
version: "8.19.19.2"
version: "8.19.20"

View File

@@ -1,10 +1,10 @@
{
"github_fulltag": false,
"github_tagfilter": "v8.19",
"last_update": "2026-07-21",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "elasticsearch",
"source": "github",
"upstream_repo": "elastic/elasticsearch",
"upstream_version": "8.19.19"
"upstream_version": "8.19.20"
}

View File

@@ -1,4 +1,7 @@
## 4.10.0.24 (2026-08-13)
- Update to latest version from linuxserver/docker-emby (changelog : https://github.com/linuxserver/docker-emby/releases)
## 4.10.0.22 (2026-08-01)
- Update to latest version from linuxserver/docker-emby (changelog : https://github.com/linuxserver/docker-emby/releases)

View File

@@ -16,7 +16,7 @@
ARG BUILD_FROM
ARG BUILD_VERSION
ARG BUILD_UPSTREAM="4.10.0.22"
ARG BUILD_UPSTREAM="4.10.0.24"
FROM ${BUILD_FROM}
##################

View File

@@ -122,5 +122,5 @@ schema:
slug: emby_nas
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/emby
version: "4.10.0.22"
version: "4.10.0.24"
video: true

View File

@@ -1,9 +1,9 @@
{
"github_beta": "true",
"last_update": "2026-08-01",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "emby",
"source": "github",
"upstream_repo": "linuxserver/docker-emby",
"upstream_version": "4.10.0.22"
"upstream_version": "4.10.0.24"
}

View File

@@ -1,3 +1,7 @@
## 4.4.26 (2026-08-13)
- Update to latest version from ente/ente (changelog : https://github.com/ente/ente/releases)
- Upstream tag : 1.3.61
## 4.4.25 (2026-08-08)
- Update to latest version from ente/ente (changelog : https://github.com/ente/ente/releases)
- Fix build failure: upstream renamed the `ente-io` org to `ente`, so the base image is now `ghcr.io/ente/server` (GHCR does not follow the rename)

View File

@@ -131,6 +131,6 @@ schema:
slug: ente
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "4.4.25"
version: "4.4.26"
video: true
webui: http://[HOST]:[PORT:3000]

View File

@@ -1,9 +1,9 @@
{
"github_beta": "false",
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "ente",
"source": "github",
"upstream_repo": "ente/ente",
"upstream_version": "4.4.25"
"upstream_version": "1.3.61"
}

View File

@@ -1,4 +1,8 @@
## 2026.08.13 (2026-08-13)
- Update to latest version from charlocharlie/epicgames-freegames
- Upstream tag : debian-2026-08-13
## 2026.08.04 (2026-08-04)
- Update to latest version from charlocharlie/epicgames-freegames
- Upstream tag : debian-2026-08-04

View File

@@ -88,5 +88,5 @@ schema:
slug: epicgamesfree
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2026.08.04"
version: "2026.08.13"
webui: "[PROTO:ssl]://[HOST]:[PORT:3000]"

View File

@@ -2,10 +2,10 @@
"dockerhub_by_date": true,
"dockerhub_list_size": 2,
"github_exclude": "-",
"last_update": "2026-08-04",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "epicgamesfree",
"source": "dockerhub",
"upstream_repo": "charlocharlie/epicgames-freegames",
"upstream_version": "debian-2026-08-04"
"upstream_version": "debian-2026-08-13"
}

View File

@@ -1,4 +1,7 @@
## 2.0.18 (2026-08-13)
- Update to latest version from linuxserver/docker-grav (changelog : https://github.com/linuxserver/docker-grav/releases)
## 2.0.17 (2026-08-08)
- Update to latest version from linuxserver/docker-grav (changelog : https://github.com/linuxserver/docker-grav/releases)

View File

@@ -16,7 +16,7 @@
ARG BUILD_FROM
ARG BUILD_VERSION
ARG BUILD_UPSTREAM="2.0.17"
ARG BUILD_UPSTREAM="2.0.18"
FROM ${BUILD_FROM}
##################

View File

@@ -89,5 +89,5 @@ schema:
slug: grav
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2.0.17"
version: "2.0.18"
webui: "[PROTO:ssl]://[HOST]:[PORT:80]"

View File

@@ -1,9 +1,9 @@
{
"github_beta": false,
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "grav",
"source": "github",
"upstream_repo": "linuxserver/docker-grav",
"upstream_version": "2.0.17"
"upstream_version": "2.0.18"
}

View File

@@ -1,4 +1,7 @@
## 0.24.2404 (2026-08-13)
- Update to latest version from linuxserver/docker-jackett (changelog : https://github.com/linuxserver/docker-jackett/releases)
## 0.24.2342 (2026-08-08)
- Update to latest version from linuxserver/docker-jackett (changelog : https://github.com/linuxserver/docker-jackett/releases)

View File

@@ -106,5 +106,5 @@ schema:
slug: jackett_nas
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/jackett
version: "0.24.2342"
version: "0.24.2404"
webui: http://[HOST]:[PORT:9117]

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "jackett",
"source": "github",
"upstream_repo": "linuxserver/docker-jackett",
"upstream_version": "0.24.2342"
"upstream_version": "0.24.2404"
}

View File

@@ -1,4 +1,7 @@
## 2.4.7 (2026-08-13)
- Update to latest version from linuxserver/docker-kometa (changelog : https://github.com/linuxserver/docker-kometa/releases)
## 2.4.6 (2026-08-01)
- Update to latest version from linuxserver/docker-kometa (changelog : https://github.com/linuxserver/docker-kometa/releases)

View File

@@ -96,4 +96,4 @@ schema:
slug: kometa
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/kometa
version: "2.4.6"
version: "2.4.7"

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-08-01",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "kometa",
"source": "github",
"upstream_repo": "linuxserver/docker-kometa",
"upstream_version": "2.4.6"
"upstream_version": "2.4.7"
}

View File

@@ -1,3 +1,12 @@
## 1.26.3 (2026-08-13)
- Update to latest version from gotson/komga (changelog : https://github.com/gotson/komga/releases)
## 1.26.1.4 (12-08-2026)
- Minor bugs fixed
## 1.26.1.3 (2026-08-12)
- Fix : 401 errors after a successful login through ingress. Komga scopes its session cookies to its servlet context path (`Path=/komga`), which the browser never sends back from the ingress url, so every request after the login was anonymous. Nginx now rewrites the cookie path onto the ingress entry
## 1.26.1.2 (2026-08-12)
- Fix : local disks (`localdisks`) and SMB shares failed to mount with `cannot mount /dev/sdX read-only`. Without an `apparmor.txt` the add-on ran under Docker's default AppArmor profile, which denies `mount` and raw block device access. Ships the same profile as the other add-ons that mount disks

View File

@@ -16,7 +16,7 @@
ARG BUILD_FROM
ARG BUILD_VERSION
ARG BUILD_UPSTREAM="1.26.1"
ARG BUILD_UPSTREAM="1.26.3"
FROM ${BUILD_FROM}
ENV BASHIO_VERSION=0.14.3

View File

@@ -62,7 +62,7 @@ profile komga_addon flags=(attach_disconnected,mediate_deleted) {
# suppress ptrace denials when using 'docker ps' or using 'ps' inside a container
ptrace (trace,read) peer=docker-default,
# docker daemon confinement requires explict allow rule for signal
# docker daemon confinement requires explicit allow rule for signal
signal (receive) set=(kill,term) peer=/usr/bin/docker,
}

View File

@@ -1,6 +1,6 @@
{
"build_from": {
"aarch64": "gotson/komga:1.26.1",
"amd64": "gotson/komga:1.26.1"
"aarch64": "gotson/komga:latest",
"amd64": "gotson/komga:latest"
}
}

View File

@@ -66,7 +66,7 @@ devices:
- /dev/nvme2
image: ghcr.io/alexbelgium/komga-{arch}
ingress: true
ingress_entry: komga
ingress_entry: komga/next
init: false
map:
- addon_config:rw
@@ -101,4 +101,4 @@ schema:
slug: komga
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/komga
version: "1.26.1.2"
version: "1.26.3"

View File

@@ -33,6 +33,13 @@ server {
proxy_redirect http://127.0.0.1:25600/ %%ingress_entry%%/;
proxy_redirect / %%ingress_entry%%/;
# Komga scopes its cookies to the servlet context path
# (Set-Cookie: ...; Path=/komga). The browser lives under the ingress
# entry, so such a cookie is never sent back : login succeeds, then
# every following request arrives anonymous and Komga answers 401.
proxy_cookie_path /komga %%ingress_entry%%/komga;
proxy_cookie_path / %%ingress_entry%%/;
# Komga renders its index page with Thymeleaf @{...} link expressions,
# so every asset url and window.resourceBaseUrl carry the context path
# (/komga). Ingress strips its own prefix before forwarding, so the

View File

@@ -1,9 +1,9 @@
{
"github_beta": "false",
"last_update": "2026-08-11",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "komga",
"source": "github",
"upstream_repo": "gotson/komga",
"upstream_version": "1.26.1"
"upstream_version": "1.26.3"
}

View File

@@ -1,4 +1,7 @@
## 3.22.1 (2026-08-13)
- Update to latest version from maintainerr/maintainerr (changelog : https://github.com/maintainerr/maintainerr/releases)
## 3.22.0 (2026-08-08)
- Update to latest version from maintainerr/maintainerr (changelog : https://github.com/maintainerr/maintainerr/releases)

View File

@@ -11,7 +11,7 @@
#=== Home Assistant Addon ===#
# ARGs used in FROM must be declared before any FROM instruction
ARG BUILD_UPSTREAM="3.22.0"
ARG BUILD_UPSTREAM="3.22.1"
############################
# 0) Tools stage #

View File

@@ -88,5 +88,5 @@ schema:
TZ: str?
slug: maintainerr
url: https://github.com/alexbelgium/hassio-addons/tree/master/maintainerr
version: "3.22.0"
version: "3.22.1"
webui: "[PROTO:ssl]://[HOST]:[PORT:6246]"

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-08-08",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "maintainerr",
"source": "github",
"upstream_repo": "maintainerr/maintainerr",
"upstream_version": "3.22.0"
"upstream_version": "3.22.1"
}

View File

@@ -1,4 +1,7 @@
## 34.0.3 (2026-08-13)
- Update to latest version from linuxserver/docker-nextcloud (changelog : https://github.com/linuxserver/docker-nextcloud/releases)
## 34.0.2 (2026-07-25)
- Update to latest version from linuxserver/docker-nextcloud (changelog : https://github.com/linuxserver/docker-nextcloud/releases)

View File

@@ -151,5 +151,5 @@ slug: nextcloud_ocr
uart: true
udev: true
url: https://github.com/alexbelgium/hassio-addons/tree/master/nextcloud
version: "34.0.2"
version: "34.0.3"
webui: https://[HOST]:[PORT:443]

View File

@@ -1,8 +1,8 @@
{
"last_update": "2026-07-25",
"last_update": "2026-08-13",
"repository": "alexbelgium/hassio-addons",
"slug": "nextcloud",
"source": "github",
"upstream_repo": "linuxserver/docker-nextcloud",
"upstream_version": "34.0.2"
"upstream_version": "34.0.3"
}

View File

@@ -0,0 +1,19 @@
## 3.5.2.1 (12-08-2026)
- Minor bugs fixed
# Changelog
## 3.5.2.1
- Pin the Nginx Proxy Manager base image to 2.15.1 instead of tracking :latest, so builds are reproducible and the CouchDB runtime copied in from couchdb:3.5.2 keeps a known-compatible Debian trixie ABI
## 3.5.2
- Initial release: couchdb:3.5.2 as an Obsidian Self-hosted LiveSync backend, bundled with Nginx Proxy Manager for TLS and certificate management
- NPM admin UI on port 81; HTTPS on 443; CouchDB also reachable directly on 5984
- Seeds a default nginx host proxying to CouchDB with the settings LiveSync needs: Authorization header passthrough and WebSocket upgrade
- Applies the CouchDB configuration LiveSync requires on every start: single-node cluster, CORS for Obsidian app origins, mandatory authentication, 4 GB max request size, 50 MB max document size
- Creates the vault database automatically
- Generates and persists a strong admin password when none is set
- Stores data under /config/obsidian-syncserver/data so it survives reinstalls and is included in Home Assistant backups
- Symlinks /etc/letsencrypt to /data so NPM certificates persist across restarts

View File

@@ -0,0 +1,95 @@
# Obsidian Sync Server NPM
CouchDB set up as a backend for the [Self-hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync) plugin in Obsidian, with Nginx Proxy Manager bundled in for TLS and certificate handling.
## How it fits together
Both run in one container under s6 supervision. CouchDB listens on 5984 and holds the vault. Nginx Proxy Manager listens on 80, 81 and 443, and proxies HTTPS through to CouchDB.
On first start the add-on seeds a default nginx host, so port 80 reaches CouchDB before you have configured anything. Create a real proxy host in the admin UI and that takes over.
The seeded config includes the two things LiveSync depends on. `proxy_pass_request_headers on` keeps the `Authorization` header intact, which matters because CouchDB authenticates every request. The `Upgrade` and `Connection` headers allow the long-lived connections replication needs.
Build your own proxy host in the UI and you have to switch Websockets Support on for the same reason.
## Ports
| Port | Use |
| :--- | :--- |
| 443 | HTTPS, point Obsidian here |
| 81 | NPM admin UI |
| 80 | HTTP, certificate validation and redirect |
| 5984 | CouchDB directly |
Since this add-on binds 80, 81 and 443, it cannot run alongside the Nginx Proxy Manager + Static Web Server add-on or anything else holding those ports.
## First login
The admin UI on port 81 starts with well-known default credentials: `admin@example.com` and `changeme`. NPM forces a change on first login. Do it before this add-on is reachable by anything you do not control.
## Certificates
NPM keeps certificates in `/etc/letsencrypt`, which this add-on symlinks to `/data/letsencrypt` so they survive restarts and reinstalls.
For a domain that does not resolve publicly, use a DNS Challenge when requesting a Let's Encrypt certificate. HTTP validation needs the domain to reach port 80 from the internet.
## What the add-on configures in CouchDB
A stock CouchDB will not work as a LiveSync backend. On every start this add-on applies the settings the plugin needs, matching what upstream's own provisioning tool does:
| Setting | Value | Why |
| :--- | :--- | :--- |
| `chttpd/require_valid_user` | `true` | No anonymous access |
| `chttpd_auth/require_valid_user` | `true` | No anonymous access to the auth endpoints |
| `httpd/WWW-Authenticate` | `Basic realm="couchdb"` | Prompts for credentials |
| `httpd/enable_cors`, `chttpd/enable_cors` | `true` | Obsidian behaves like a browser client |
| `cors/credentials` | `true` | Lets it send the auth header cross-origin |
| `cors/origins` | `app://obsidian.md,capacitor://localhost,http://localhost` | Desktop and mobile app origins |
| `chttpd/max_http_request_size` | `4294967296` | Large vault batches |
| `couchdb/max_document_size` | `50000000` | Large notes and attachments |
These get re-applied on each start, so editing them by hand in Fauxton will not stick.
## Storage
The vault database lives in `/config/obsidian-syncserver/data` rather than the add-on's `/data` directory, so it survives a reinstall and **gets picked up by Home Assistant backups**. NPM's own database and certificates live in `/data`.
If you did not set a CouchDB password, the generated one is in `/config/obsidian-syncserver/admin_password`.
## Troubleshooting
Check CouchDB directly first. It separates a CouchDB problem from a proxy problem in one command:
```bash
curl -u admin:YOURPASSWORD http://homeassistant.local:5984/obsidian
```
If that works, CouchDB is fine and whatever is failing lives in the proxy layer.
If the add-on will not start, look for `ERROR` in the log. A malformed `database` name or an unwritable `/config` both stop startup with a message saying which.
If sync connects and then stalls, WebSocket upgrade is off. Turn on Websockets Support in the proxy host settings.
If everything returns 401 through the proxy but works on 5984, the proxy host is not passing the `Authorization` header through.
If desktop syncs but mobile does not, the certificate is either untrusted by the phone or issued for a different hostname. Check with:
```bash
openssl s_client -connect your-domain:443 </dev/null | openssl x509 -noout -subject -dates
```
If the add-on will not start because of a port conflict, something else holds 80, 81 or 443. Stop it, or switch to the plain Obsidian Sync Server behind the proxy you already have.
To see the applied CouchDB configuration:
```bash
curl -u admin:YOURPASSWORD http://homeassistant.local:5984/_node/_local/_config/cors
```
## Updates
This add-on tracks two upstream projects, CouchDB and Nginx Proxy Manager, and the repository's updater handles one upstream per add-on. Its version gets bumped by hand rather than by the weekly update workflow.
## Backups
Home Assistant backs up `/config`, which covers the vault database. For a copy you can move elsewhere, use CouchDB replication or export from Fauxton at `http://<host>:5984/_utils`.

View File

@@ -0,0 +1,48 @@
# Global build args must be declared before the first FROM to be usable there.
ARG BUILD_FROM=jc21/nginx-proxy-manager:2.15.1
ARG COUCHDB_FROM=couchdb:3.5.2
# Stage 1: source of the CouchDB runtime. CouchDB ships a self-contained
# release under /opt/couchdb, including its own Erlang runtime (erts-*), so
# it can be lifted into another image without installing Erlang separately.
FROM ${COUCHDB_FROM} AS couchdb
# Stage 2: Nginx Proxy Manager, which supplies s6-overlay and the admin UI.
# Both images are Debian trixie, so the CouchDB release is binary compatible.
FROM ${BUILD_FROM}
# hadolint ignore=DL3008
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
jq \
openssl \
ripgrep \
libicu76 \
libmozjs-128-0 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=couchdb /opt/couchdb /opt/couchdb
COPY --from=couchdb /usr/local/bin/docker-entrypoint.sh /docker-entrypoint.sh
# CouchDB refuses to run as root and expects to own its runtime directories.
RUN groupadd -g 5984 couchdb \
&& useradd -u 5984 -g couchdb -d /opt/couchdb -s /bin/bash couchdb \
&& chown -R couchdb:couchdb /opt/couchdb \
&& chmod +x /docker-entrypoint.sh
COPY run.sh /run.sh
COPY rootfs /
RUN chmod +x /run.sh \
&& chmod +x /etc/s6-overlay/s6-rc.d/couchdb/run \
&& chmod +x /etc/s6-overlay/s6-rc.d/couchdb/finish \
&& chmod +x /etc/s6-overlay/s6-rc.d/addon-init/script
ARG BUILD_VERSION
LABEL \
io.hass.version="${BUILD_VERSION}" \
io.hass.type="addon" \
io.hass.arch="aarch64|amd64"
ENTRYPOINT ["/init"]

View File

@@ -0,0 +1,101 @@
# Home assistant add-on: Obsidian Sync Server NPM
![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_npm%2Fconfig.yaml)
![Ingress](https://img.shields.io/badge/dynamic/yaml?label=Ingress&query=%24.ingress&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_npm%2Fconfig.yaml)
![Arch](https://img.shields.io/badge/dynamic/yaml?color=success&label=Arch&query=%24.arch&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_npm%2Fconfig.yaml)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9c6cf10bdbba45ecb202d7f579b5be0e)](https://www.codacy.com/gh/alexbelgium/hassio-addons/dashboard?utm_source=github.com&utm_medium=referral&utm_content=alexbelgium/hassio-addons&utm_campaign=Badge_Grade)
[![GitHub Super-Linter](https://img.shields.io/github/actions/workflow/status/alexbelgium/hassio-addons/weekly-supelinter.yaml?label=Lint%20code%20base)](https://github.com/alexbelgium/hassio-addons/actions/workflows/weekly-supelinter.yaml)
[![Builder](https://img.shields.io/github/actions/workflow/status/alexbelgium/hassio-addons/onpush_builder.yaml?label=Builder)](https://github.com/alexbelgium/hassio-addons/actions/workflows/onpush_builder.yaml)
Runs CouchDB as a sync backend for the [Self-hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync) plugin in Obsidian, with [Nginx Proxy Manager](https://nginxproxymanager.com/) bundled in to handle TLS.
This add-on is only the server side. Install the companion plugin in Obsidian: <https://community.obsidian.md/plugins/obsidian-livesync>
> [!IMPORTANT]
>
> - Before installing or upgrading this add-on or the obsidian livesync plugin, please back up your vault.
> - Not compatible with other synchronisation solution (including iCloud and Obsidian Sync).
> - For backups, use [Differential ZIP Backup](https://github.com/vrtmrz/diffzip).
Your vault syncs between your own devices through Home Assistant. No Obsidian Sync subscription, and the notes stay on your network.
This version has everything mobile Obsidian needs in one add-on. NPM requests and renews the certificates and proxies HTTPS through to CouchDB. Pick it if you do not already run a reverse proxy.
| Add-on | TLS | Use when |
| :--- | :--- | :--- |
| [Obsidian Sync Server](../obsidian_syncserver_solo/README.md) | none | You already run a reverse proxy |
| [Obsidian Sync Server SSL](../obsidian_syncserver_ssl/README.md) | CouchDB serves HTTPS from your certificates in `/ssl` | You have certificates on the Home Assistant machine |
| Obsidian Sync Server NPM (this one) | Bundled Nginx Proxy Manager | You have no proxy and want certificate handling included |
Note that this add-on binds ports 80, 81 and 443. If you already run the Nginx Proxy Manager + Static Web Server add-on, or anything else on those ports, only one of them can be running at a time. In that case use the plain [Obsidian Sync Server](../obsidian_syncserver_solo/README.md) and add a proxy host to the NPM you already have.
## Ports
| Port | Use |
| :--- | :--- |
| 443 | HTTPS, point Obsidian here |
| 81 | Nginx Proxy Manager admin UI |
| 80 | HTTP, certificate validation and redirect |
| 5984 | CouchDB directly, for desktop or local tools |
## Installation
1. Add the repository `https://github.com/alexbelgium/hassio-addons` to Home Assistant, then install the add-on.
2. Set a password under Configuration. Leaving it blank generates one and prints it in the log on first start.
3. Start the add-on and look for `Ready.` in the log.
4. Open the NPM admin UI on port 81. The default login is `admin@example.com` with password `changeme`, and NPM makes you change both on first login. Do that now rather than later.
## Getting a real certificate
Port 443 answers out of the box, but with a self-signed certificate that mobile Obsidian will reject. To fix that:
1. In the NPM admin UI, go to SSL Certificates, then Add SSL Certificate, then Let's Encrypt.
2. Enter the domain name pointing at your Home Assistant machine, plus your email.
3. If the domain has no public IP, tick Use a DNS Challenge and pick your DNS provider.
4. Once the certificate is issued, go to Hosts, then Proxy Hosts, then Add Proxy Host:
- Domain Names: your domain
- Scheme: `http`
- Forward Hostname / IP: `127.0.0.1`
- Forward Port: `5984`
- Websockets Support: on. LiveSync will not sync without it.
- On the SSL tab, select your certificate and turn on Force SSL.
## Configuration
```yaml
username: admin
password: ""
database: obsidian
log_level: info
```
`username` and `password` are the CouchDB administrator credentials that the LiveSync plugin uses, separate from the NPM admin login. A blank password gets generated on first start and saved to `/config/obsidian-syncserver/admin_password`.
`database` is the CouchDB database holding your vault. The add-on creates it if it does not exist.
`log_level` sets CouchDB log verbosity.
## Connecting Obsidian
Install Self-hosted LiveSync from Obsidian's community plugins. In its settings, pick the manual setup and fill in:
- URI: `https://your-domain`
- Username and password: the CouchDB credentials above
- Database name: `obsidian`, unless you changed it
Hit Test Database Connection to check it, then turn on end-to-end encryption with a passphrase. With that on, the server only ever holds ciphertext.
[DOCS.md](DOCS.md) covers troubleshooting.
## Security
CouchDB requires authentication on every request, and NPM's admin UI has its own login that you have to change the first time you use it. Keep this on your LAN unless you have deliberately set up remote access.
## Support
For problems with this add-on (not the upstream CouchDB or Nginx Proxy Manager software), create an issue on [github](https://github.com/alexbelgium/hassio-addons/issues) and tag @ToledoEM
- Obsidian Self-hosted LiveSync plugin → [github.com/vrtmrz/obsidian-livesync](https://github.com/vrtmrz/obsidian-livesync)
- CouchDB upstream → [couchdb.apache.org](https://couchdb.apache.org/)
- Nginx Proxy Manager upstream → [github.com/NginxProxyManager/nginx-proxy-manager](https://github.com/NginxProxyManager/nginx-proxy-manager)

View File

@@ -0,0 +1,37 @@
#include <tunables/global>
profile hassio-addons/obsidian_syncserver_npm flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
#include <abstractions/bash>
#include <abstractions/nameservice>
#include <abstractions/openssl>
# Baseline profile covering both CouchDB (Erlang VM) and Nginx Proxy
# Manager (s6-overlay, nginx, node). Both need broad file and network
# access plus the ability to drop privileges.
file,
network,
capability chown,
capability dac_override,
capability fowner,
capability kill,
capability net_bind_service,
capability setgid,
capability setuid,
signal (send) set=(kill,term,int,hup,cont),
# s6-overlay boot chain
/init ix,
/bin/** ix,
/usr/bin/** ix,
/command/** ix,
/package/** ix,
/run/{s6,s6-rc*,service}/** ix,
/etc/s6-overlay/** rwix,
deny /proc/kcore rwklx,
deny /proc/sysrq-trigger rwklx,
deny /sys/firmware/** rwklx,
}

View File

@@ -0,0 +1,4 @@
---
build_from:
aarch64: jc21/nginx-proxy-manager:2.15.1
amd64: jc21/nginx-proxy-manager:2.15.1

View File

@@ -0,0 +1,34 @@
name: "Obsidian Sync Server NPM"
slug: obsidian_syncserver_npm
image: ghcr.io/alexbelgium/obsidian_syncserver_npm-{arch}
description: "Self-hosted Obsidian LiveSync backend on CouchDB, bundled with Nginx Proxy Manager for TLS and certificate management."
version: "3.5.2.1"
url: "https://github.com/alexbelgium/hassio-addons/tree/master/obsidian_syncserver_npm"
arch:
- amd64
- aarch64
startup: services
init: false
ports:
5984/tcp: 5984
80/tcp: 80
81/tcp: 81
443/tcp: 443
ports_description:
5984/tcp: "CouchDB HTTP (direct access, desktop Obsidian)"
80/tcp: "HTTP (certificate validation and redirect)"
81/tcp: "Nginx Proxy Manager admin UI"
443/tcp: "HTTPS — use this for mobile Obsidian"
webui: "http://[HOST]:[PORT:81]"
map:
- addon_config:rw
options:
username: admin
password: ""
database: obsidian
log_level: info
schema:
username: str
password: password?
database: match(^[a-z][a-z0-9_$()+/-]*$)
log_level: list(debug|info|warn|error)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -0,0 +1,20 @@
#!/command/with-contenv bash
# shellcheck shell=bash
# NPM's own "prepare" service aborts the entire boot if /etc/letsencrypt is
# not a mount. Home Assistant does not mount it, so point it at /data, which
# Supervisor persists as a Docker volume.
#
# This is an s6-rc oneshot that "prepare" depends on, so it is guaranteed to
# run first. NPM's image uses s6-overlay v3 and has no /etc/cont-init.d.
if [ ! -L /etc/letsencrypt ]; then
mkdir -p /data/letsencrypt
if [ -d /etc/letsencrypt ] && [ -n "$(ls -A /etc/letsencrypt 2> /dev/null)" ]; then
cp -a /etc/letsencrypt/. /data/letsencrypt/ 2> /dev/null || true
fi
rm -rf /etc/letsencrypt
ln -sf /data/letsencrypt /etc/letsencrypt
fi
mkdir -p /data/letsencrypt
echo "[obsidian-syncserver] /etc/letsencrypt -> /data/letsencrypt"

View File

@@ -0,0 +1 @@
oneshot

View File

@@ -0,0 +1 @@
/etc/s6-overlay/s6-rc.d/addon-init/script

View File

@@ -0,0 +1,3 @@
#!/command/with-contenv bash
# shellcheck shell=bash
exit 0

View File

@@ -0,0 +1,3 @@
#!/command/with-contenv bash
# shellcheck shell=bash
exec /run.sh

View File

@@ -0,0 +1 @@
longrun

282
obsidian_syncserver_npm/run.sh Executable file
View File

@@ -0,0 +1,282 @@
#!/command/with-contenv bash
# shellcheck shell=bash
set -Eeuo pipefail
# Obsidian LiveSync sync server (CouchDB) as a Home Assistant add-on.
#
# This flavour runs under the s6-overlay supervision tree that Nginx Proxy
# Manager's image provides, as one service alongside NPM's own. NPM handles
# TLS termination and certificate management; CouchDB only listens on
# loopback plus the LAN port.
#
# CouchDB alone is not usable as a LiveSync backend: the plugin needs a
# single-node cluster, CORS opened to Obsidian's app origins, authentication
# required, and raised request/document size limits. This script applies that
# configuration on every start. The settings mirror the upstream provisioning
# tool (vrtmrz/obsidian-livesync, utils/couchdb/provision.ts), which is the
# authoritative source for what LiveSync expects.
OPTIONS_JSON="/data/options.json"
ADDON_DIR="/config/obsidian-syncserver"
PASSWORD_FILE="${ADDON_DIR}/admin_password"
DATA_DIR="${ADDON_DIR}/data"
LOCAL_D="/opt/couchdb/etc/local.d"
COUCH_URL="http://127.0.0.1:5984"
# Retry budget matches provision.ts: CouchDB on a Raspberry Pi can take a
# while to open its listener on first boot.
READY_RETRIES=12
READY_DELAY=5
log() { echo "[obsidian-syncserver] $*"; }
warn() { echo "[obsidian-syncserver] WARN: $*" >&2; }
die() {
echo "[obsidian-syncserver] ERROR: $*" >&2
exit 1
}
read_opt() {
jq -er --arg k "$1" '.[$k]' "$OPTIONS_JSON" 2> /dev/null || true
}
# ---------------------------------------------------------------------------
# Step 1: Read add-on options
# ---------------------------------------------------------------------------
[[ -f "$OPTIONS_JSON" ]] || die "Missing options file at ${OPTIONS_JSON}"
USERNAME="$(read_opt username)"
USERNAME="${USERNAME:-admin}"
PASSWORD="$(read_opt password)"
DATABASE="$(read_opt database)"
DATABASE="${DATABASE:-obsidian}"
LOG_LEVEL="$(read_opt log_level)"
LOG_LEVEL="${LOG_LEVEL:-info}"
# CouchDB database names are restricted; a bad name only fails much later at
# the create step, with an opaque 400.
[[ "$DATABASE" =~ ^[a-z][a-z0-9_$()+/-]*$ ]] \
|| die "database '${DATABASE}' is invalid. Must start with a lowercase letter and contain only a-z 0-9 _ \$ ( ) + / -"
mkdir -p "$ADDON_DIR"
# ---------------------------------------------------------------------------
# Step 2: Resolve admin credentials
#
# A blank password auto-generates one and persists it, so the add-on never
# ships a guessable default. It is reused on later starts, otherwise every
# restart would invalidate the credentials already configured in Obsidian.
# ---------------------------------------------------------------------------
if [[ -z "$PASSWORD" ]]; then
if [[ -f "$PASSWORD_FILE" ]]; then
PASSWORD="$(cat "$PASSWORD_FILE")"
log "Using previously generated admin password from ${PASSWORD_FILE}"
else
PASSWORD="$(openssl rand -base64 24)"
(
umask 077
printf '%s\n' "$PASSWORD" > "$PASSWORD_FILE"
)
warn "No password set. Generated one and saved it to ${PASSWORD_FILE}"
warn "Admin username: ${USERNAME}"
warn "Admin password: ${PASSWORD}"
warn "Set a password in the add-on options to choose your own."
fi
fi
export COUCHDB_USER="$USERNAME"
export COUCHDB_PASSWORD="$PASSWORD"
# ---------------------------------------------------------------------------
# Step 3: Point CouchDB at persistent storage
#
# /data is wiped when the add-on is reinstalled, and is not included in a
# Home Assistant backup the way the add-on config directory is. The vault is
# the whole point of this add-on, so it lives under /config instead.
# ---------------------------------------------------------------------------
mkdir -p "$DATA_DIR" "${DATA_DIR}/.delayed" "$LOCAL_D"
COUCH_UID="$(id -u couchdb 2> /dev/null || echo 5984)"
COUCH_GID="$(id -g couchdb 2> /dev/null || echo 5984)"
chown -R "${COUCH_UID}:${COUCH_GID}" "$ADDON_DIR" 2> /dev/null \
|| warn "Could not chown ${ADDON_DIR}; CouchDB may fail to write to it"
cat > "${LOCAL_D}/10-addon-storage.ini" << EOF
; Managed by the Home Assistant add-on. Edits are overwritten on restart.
[couchdb]
database_dir = ${DATA_DIR}
view_index_dir = ${DATA_DIR}
[chttpd]
bind_address = 0.0.0.0
port = 5984
[log]
level = ${LOG_LEVEL}
EOF
# ---------------------------------------------------------------------------
# Step 3b: Seed a default nginx server block pointing at CouchDB
#
# NPM's own proxy hosts are created through its admin UI and stored in its
# database. This only replaces the "Congratulations" default page, so that a
# fresh install answers on 443 with CouchDB instead of NPM's placeholder.
# Once a real proxy host is defined in the UI, that takes precedence.
#
# The proxy settings below are what LiveSync needs: the Authorization header
# must survive the hop (CouchDB authenticates every request), and the
# connection must be upgradable (replication is long-lived).
# ---------------------------------------------------------------------------
DEFAULT_HOST_DIR="/data/nginx/default_host"
mkdir -p "$DEFAULT_HOST_DIR"
# nginx.conf includes this directory at http level, so this must be a whole
# server block rather than a bare location.
cat > "${DEFAULT_HOST_DIR}/obsidian_syncserver.conf" << 'EOF'
# Managed by the Home Assistant add-on. Edits are overwritten on restart.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
access_log /data/logs/obsidian_access.log standard;
error_log /data/logs/obsidian_error.log warn;
include conf.d/include/letsencrypt-acme-challenge.conf;
location / {
proxy_pass http://127.0.0.1:5984;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# CouchDB authenticates every request, so the credentials must
# pass through untouched.
proxy_pass_request_headers on;
# LiveSync replication holds connections open.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 600s;
client_max_body_size 0;
}
}
EOF
log "Seeded default nginx host proxying to CouchDB on 127.0.0.1:5984"
# ---------------------------------------------------------------------------
# Step 4: Start CouchDB in the background
#
# It runs in the background so provisioning can talk to it, then this script
# blocks on it at the end. s6 supervises this script as the service, so it
# must not exit while CouchDB is alive.
# ---------------------------------------------------------------------------
log "Starting CouchDB (user=${USERNAME}, database=${DATABASE}, log_level=${LOG_LEVEL})"
/docker-entrypoint.sh /opt/couchdb/bin/couchdb &
COUCH_PID=$!
# Without this, a CouchDB that dies during provisioning leaves the script
# retrying against a socket that will never come up.
trap 'kill -TERM "$COUCH_PID" 2>/dev/null || true' EXIT INT TERM
# ---------------------------------------------------------------------------
# Step 5: Wait for CouchDB to accept requests
# ---------------------------------------------------------------------------
ready=false
for i in $(seq 1 "$READY_RETRIES"); do
if curl -fsS -u "${USERNAME}:${PASSWORD}" "${COUCH_URL}/_up" > /dev/null 2>&1; then
ready=true
break
fi
kill -0 "$COUCH_PID" 2> /dev/null || die "CouchDB exited during startup. See the log above."
log "Waiting for CouchDB to come up (${i}/${READY_RETRIES})"
sleep "$READY_DELAY"
done
[[ "$ready" == "true" ]] || die "CouchDB did not become ready after $((READY_RETRIES * READY_DELAY))s"
log "CouchDB is up, applying Obsidian LiveSync configuration"
# ---------------------------------------------------------------------------
# Step 6: Provision for LiveSync
#
# Every call below is idempotent, so this runs safely on each start and
# repairs configuration that was changed by hand in Fauxton.
# ---------------------------------------------------------------------------
# Promotes the single node out of the uninitialised state. A node that is
# already set up answers 400/409 with "already"/"finished", which is success
# here, not an error.
cluster_body="$(jq -nc \
--arg u "$USERNAME" --arg p "$PASSWORD" \
'{action:"enable_single_node",username:$u,password:$p,bind_address:"0.0.0.0",port:5984,singlenode:true}')"
cluster_response="$(curl -sS -u "${USERNAME}:${PASSWORD}" \
-X POST "${COUCH_URL}/_cluster_setup" \
-H "Content-Type: application/json" \
-d "$cluster_body" \
-w '\n%{http_code}' 2>&1 || true)"
cluster_code="$(printf '%s' "$cluster_response" | tail -n1)"
cluster_text="$(printf '%s' "$cluster_response" | sed '$d')"
case "$cluster_code" in
2*) log "Single-node cluster initialised" ;;
400 | 409)
if printf '%s' "$cluster_text" | rg -qi 'already|finished'; then
log "Single-node cluster already initialised"
else
die "Cluster setup failed (HTTP ${cluster_code}): ${cluster_text}"
fi
;;
*) die "Cluster setup failed (HTTP ${cluster_code}): ${cluster_text}" ;;
esac
# CORS origins are what let the Obsidian desktop app and the mobile app talk
# to CouchDB at all; without them the plugin fails with an opaque network
# error. Values are taken from provision.ts.
set_config() {
local label="$1" key="$2" value="$3" code
code="$(curl -sS -o /dev/null -w '%{http_code}' \
-u "${USERNAME}:${PASSWORD}" \
-X PUT "${COUCH_URL}/_node/_local/_config/${key}" \
-H "Content-Type: application/json" \
-d "$value" 2>&1 || true)"
case "$code" in
2*) log " set ${label}" ;;
*) die "Failed to ${label} (HTTP ${code}) at ${key}" ;;
esac
}
set_config "require authenticated HTTP users" "chttpd/require_valid_user" '"true"'
set_config "require authenticated HTTP users for authentication" "chttpd_auth/require_valid_user" '"true"'
set_config "the HTTP authentication challenge" "httpd/WWW-Authenticate" '"Basic realm=\"couchdb\""'
set_config "enable HTTP CORS" "httpd/enable_cors" '"true"'
set_config "enable clustered HTTP CORS" "chttpd/enable_cors" '"true"'
set_config "the maximum HTTP request size" "chttpd/max_http_request_size" '"4294967296"'
set_config "the maximum document size" "couchdb/max_document_size" '"50000000"'
set_config "enable CORS credentials" "cors/credentials" '"true"'
set_config "allowed CORS origins" "cors/origins" '"app://obsidian.md,capacitor://localhost,http://localhost"'
# 412 means the database is already there, which is the normal case on every
# start after the first.
db_code="$(curl -sS -o /dev/null -w '%{http_code}' \
-u "${USERNAME}:${PASSWORD}" \
-X PUT "${COUCH_URL}/$(printf '%s' "$DATABASE" | jq -sRr @uri)" 2>&1 || true)"
case "$db_code" in
2*) log "Created database '${DATABASE}'" ;;
412) log "Database '${DATABASE}' already exists" ;;
*) die "Failed to create database '${DATABASE}' (HTTP ${db_code})" ;;
esac
log "Ready. Point Obsidian Self-hosted LiveSync at this server."
log " database: ${DATABASE} username: ${USERNAME}"
# ---------------------------------------------------------------------------
# Step 7: Hand the container's lifetime back to CouchDB
# ---------------------------------------------------------------------------
trap - EXIT
wait "$COUCH_PID"

View File

@@ -0,0 +1,13 @@
configuration:
username:
name: Admin username
description: CouchDB administrator username. Use this in the Obsidian LiveSync plugin settings. Unrelated to the Nginx Proxy Manager login.
password:
name: Admin password
description: CouchDB administrator password. Leave blank to generate a strong one on first start and save it to /config/obsidian-syncserver/admin_password (also printed once in the log).
database:
name: Database name
description: CouchDB database holding the vault. Created automatically if missing. Must start with a lowercase letter.
log_level:
name: Log level
description: CouchDB log verbosity.

View File

@@ -0,0 +1,9 @@
{
"source": "dockerhub",
"upstream_repo": "library/couchdb",
"upstream_version": "3.5.2",
"last_update": "2026-08-12",
"paused": true,
"paused_reason": "Tracks two upstreams (couchdb and jc21/nginx-proxy-manager) which the updater cannot resolve together, and inherits the NPM base image build constraint from issue #4. Bump by hand.",
"slug": "obsidian_syncserver_npm"
}

View File

@@ -0,0 +1,17 @@
## 3.5.2.1 (2026-08-13)
- Update to latest version from library/couchdb
- Upstream tag : 3.5.2.1-nouveau
## 3.5.2 (12-08-2026)
- Minor bugs fixed
# Changelog
## 3.5.2
- Initial release wrapping couchdb:3.5.2 as an Obsidian Self-hosted LiveSync backend
- Applies the CouchDB configuration LiveSync requires on every start: single-node cluster, CORS for Obsidian app origins, mandatory authentication, 4 GB max request size, 50 MB max document size
- Creates the vault database automatically
- Generates and persists a strong admin password when none is set
- Stores data under /config/obsidian-syncserver/data so it survives reinstalls and is included in Home Assistant backups
- Plain HTTP on port 5984; use a reverse proxy for TLS if you need mobile sync

View File

@@ -0,0 +1,98 @@
# Obsidian Sync Server
CouchDB set up as a backend for the [Self-hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync) plugin in Obsidian.
## What the add-on configures
A stock CouchDB will not work as a LiveSync backend. On every start this add-on applies the settings the plugin needs, matching what upstream's own provisioning tool does:
| Setting | Value | Why |
| :--- | :--- | :--- |
| `chttpd/require_valid_user` | `true` | No anonymous access |
| `chttpd_auth/require_valid_user` | `true` | No anonymous access to the auth endpoints |
| `httpd/WWW-Authenticate` | `Basic realm="couchdb"` | Prompts for credentials |
| `httpd/enable_cors`, `chttpd/enable_cors` | `true` | Obsidian behaves like a browser client |
| `cors/credentials` | `true` | Lets it send the auth header cross-origin |
| `cors/origins` | `app://obsidian.md,capacitor://localhost,http://localhost` | Desktop and mobile app origins |
| `chttpd/max_http_request_size` | `4294967296` | Large vault batches |
| `couchdb/max_document_size` | `50000000` | Large notes and attachments |
These get re-applied on each start, so editing them by hand in Fauxton will not stick.
## Storage
The vault database lives in `/config/obsidian-syncserver/data` rather than the add-on's `/data` directory, so it survives a reinstall and **gets picked up by Home Assistant backups**.
If you did not set a password, the generated one is in `/config/obsidian-syncserver/admin_password`.
## Reverse proxy setup
Mobile Obsidian refuses plain HTTP, so a phone or tablet needs TLS in front of this add-on. Any proxy will do, as long as it does three things:
Pass the `Authorization` header through untouched. CouchDB authenticates every single request, so a proxy that strips or rewrites that header turns everything into a 401.
Allow WebSocket upgrades. LiveSync uses continuous replication. Without upgrade support the connection looks like it works and then just sits there.
Avoid buffering responses indefinitely, or the long-poll changes feed lags behind.
### Nginx Proxy Manager
Add a Proxy Host:
- Domain Names: whatever hostname you plan to use, say `obsidian.example.com`
- Scheme: `http`
- Forward Hostname / IP: your Home Assistant machine
- Forward Port: `5984`
- Websockets Support: on
- On the SSL tab, request or select a certificate and turn on Force SSL
Then point LiveSync at `https://obsidian.example.com`.
### Plain nginx
```nginx
location / {
proxy_pass http://homeassistant.local:5984;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# CouchDB authenticates every request
proxy_pass_request_headers on;
# LiveSync uses continuous replication
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_read_timeout 600s;
}
```
## Troubleshooting
If the add-on stops right after starting, read the log. A malformed `database` name or a `/config` directory CouchDB cannot write to will both halt startup with a message saying which.
If LiveSync reports a network or CORS error, it is nearly always the proxy rather than CouchDB. Check the server directly first:
```bash
curl -u admin:YOURPASSWORD http://homeassistant.local:5984/obsidian
```
When that works but the plugin still fails, the proxy is either dropping the `Authorization` header or blocking the WebSocket upgrade.
If desktop syncs but mobile does not, the app does not trust your certificate. Self-signed ones generally will not cut it. The NPM version of this add-on exists partly to make that easier.
If sync connects and then stalls, WebSocket upgrade is not getting through the proxy.
To see the applied configuration:
```bash
curl -u admin:YOURPASSWORD http://homeassistant.local:5984/_node/_local/_config/cors
```
The Obsidian origins should be listed there.
## Backups
Home Assistant backs up `/config`, which covers the vault database. For a copy you can move elsewhere, use CouchDB replication or export from Fauxton at `http://<host>:5984/_utils`.

View File

@@ -0,0 +1,26 @@
ARG BUILD_FROM=couchdb:3.5.2
FROM ${BUILD_FROM}
# The official couchdb image is Debian-based and carries no s6-overlay, so
# this add-on runs run.sh directly rather than through the s6 service tree
# the other add-ons in this repository use.
# hadolint ignore=DL3008
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
jq \
openssl \
ripgrep \
&& rm -rf /var/lib/apt/lists/*
COPY run.sh /run.sh
RUN chmod +x /run.sh
ARG BUILD_VERSION
LABEL \
io.hass.version="${BUILD_VERSION}" \
io.hass.type="addon" \
io.hass.arch="aarch64|amd64"
ENTRYPOINT ["/run.sh"]

View File

@@ -0,0 +1,73 @@
# Home assistant add-on: Obsidian Sync Server
![Version](https://img.shields.io/badge/dynamic/yaml?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_solo%2Fconfig.yaml)
![Ingress](https://img.shields.io/badge/dynamic/yaml?label=Ingress&query=%24.ingress&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_solo%2Fconfig.yaml)
![Arch](https://img.shields.io/badge/dynamic/yaml?color=success&label=Arch&query=%24.arch&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2Fobsidian_syncserver_solo%2Fconfig.yaml)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9c6cf10bdbba45ecb202d7f579b5be0e)](https://www.codacy.com/gh/alexbelgium/hassio-addons/dashboard?utm_source=github.com&utm_medium=referral&utm_content=alexbelgium/hassio-addons&utm_campaign=Badge_Grade)
[![GitHub Super-Linter](https://img.shields.io/github/actions/workflow/status/alexbelgium/hassio-addons/weekly-supelinter.yaml?label=Lint%20code%20base)](https://github.com/alexbelgium/hassio-addons/actions/workflows/weekly-supelinter.yaml)
[![Builder](https://img.shields.io/github/actions/workflow/status/alexbelgium/hassio-addons/onpush_builder.yaml?label=Builder)](https://github.com/alexbelgium/hassio-addons/actions/workflows/onpush_builder.yaml)
Runs CouchDB as a sync backend for the [Self-hosted LiveSync](https://github.com/vrtmrz/obsidian-livesync) plugin in Obsidian.
This add-on is only the server side. Install the companion plugin in Obsidian: <https://community.obsidian.md/plugins/obsidian-livesync>
> [!IMPORTANT]
>
> - Before installing or upgrading this add-on or the obsidian livesync plugin, please back up your vault.
> - Not compatible with other synchronisation solution (including iCloud and Obsidian Sync).
> - For backups, use [Differential ZIP Backup](https://github.com/vrtmrz/diffzip).
Your vault syncs between your own devices through Home Assistant. No Obsidian Sync subscription, and the notes stay on your network.
This add-on speaks plain HTTP. Desktop Obsidian works fine with that. Mobile Obsidian does not, because it insists on a valid TLS certificate ([Easy to add on HA](https://www.home-assistant.io/blog/2017/09/27/effortless-encryption-with-lets-encrypt-and-duckdns/)). To sync a phone or tablet you need a reverse proxy in front of this add-on, or one of the other two versions:
| Add-on | TLS | Use when |
| :--- | :--- | :--- |
| Obsidian Sync Server (this one) | none | You already run a reverse proxy |
| [Obsidian Sync Server SSL](../obsidian_syncserver_ssl/README.md) | CouchDB serves HTTPS from your certificates in `/ssl` | You have certificates on the Home Assistant machine |
| [Obsidian Sync Server NPM](../obsidian_syncserver_npm/README.md) | Bundled Nginx Proxy Manager | You have no proxy and want certificate handling included |
## Installation
1. Add the repository `https://github.com/alexbelgium/hassio-addons` to Home Assistant, then install the add-on.
2. Set a password under Configuration. Leaving it blank generates one and prints it in the log on first start.
3. Start the add-on and look for `Ready.` in the log.
## Configuration
```yaml
username: admin
password: ""
database: obsidian
log_level: info
```
`username` and `password` are the CouchDB administrator credentials that the LiveSync plugin uses. A blank password gets generated on first start and saved to `/config/obsidian-syncserver/admin_password`.
`database` is the CouchDB database holding your vault. The add-on creates it if it does not exist.
`log_level` sets CouchDB log verbosity.
## Connecting Obsidian
Install Self-hosted LiveSync from Obsidian's community plugins. In its settings, pick the manual setup and fill in:
- URI: `http://<home-assistant-host>:5984`, or your proxy's HTTPS address
- Username and password: whatever you configured above
- Database name: `obsidian`, unless you changed it
Hit Test Database Connection to check it, then turn on end-to-end encryption with a passphrase. With that on, the server only ever holds ciphertext.
[DOCS.md](DOCS.md) covers reverse proxy setup and troubleshooting.
## Security
CouchDB here requires authentication on every request, so nothing is readable anonymously. Still, do not forward port 5984 to the internet. Keep it on your LAN, or put it behind a proxy that terminates TLS and does its own access control.
## Support
Create an issue on [github](https://github.com/alexbelgium/hassio-addons/issues) and tag @ToledoEM
- Obsidian Self-hosted LiveSync plugin → [github.com/vrtmrz/obsidian-livesync](https://github.com/vrtmrz/obsidian-livesync)
- CouchDB upstream → [couchdb.apache.org](https://couchdb.apache.org/)

Some files were not shown because too many files have changed in this diff Show More