Skip to content

2.17.6 — several things stopped being quiet about themselves

Latest

Choose a tag to compare

@amayer1983 amayer1983 released this 01 Sep 19:18
· 81 commits to main since this release

The release where several things stopped being quiet about themselves.

Added

  • The self-update sits in the icon bar now. It was in Settings, under Cleanup, which is an odd place to keep the one button that updates Docksentry itself — @LeeNX said he battled to find it every time (#2). It is in the header with the same "update now" the containers have, pointed at the same self-updater, and it still asks before it fires. The old place still works; this is a second door, not a move.

  • A container being updated says so. The yellow update badge kept claiming an update was merely available while the log already said it was running (#2, @LeeNX). It now reads updating to 1.26 for as long as the update holds the lock, falls back to plain updating when the target version is not known rather than inventing one, and the row's own update button is inert while it runs.

  • A notification survives a short network outage. @NotRetarded lost the network on two machines at once — a brief power cut, both boxes on UPS, both offline for about half a minute (#66). Discord's gateway reconnected on its own. Telegram got three tries over six seconds and then dropped the crash alert with nothing written down anywhere. Failed sends are now held and delivered when the connection comes back, carrying a ⏳ Delayed 12m line so a late alert cannot read as a fresh one. Held at most 15 minutes and at most 20 messages, and never written to disk — an alert that outlives a restart is a lie the interface can never take back. Covers Telegram, the Discord bot, the Discord webhook and the generic webhook. Not ntfy, Gotify, Matrix, Apprise or SMTP: each has its own transport and none of them tells a network failure apart from a rejection yet.

  • A private self-update answers privately. Running /selfupdate with ephemeral replies still announced the restart to the whole channel afterwards — publishing exactly what the private mode exists to hide (#63, @NotRetarded). The result now arrives as a direct message and the channel hears nothing. If Discord will not open that DM, the message goes to the channel rather than vanishing, and says why.

  • An unreachable Compose file now shows the volume line that is missing. The container detail page names the path Docksentry actually opens and whether it is there — and underneath, the mount that would make it resolve. Where the files live inside another container, that line is read off the running container itself, so it names a volume when that is what holds them: @NotRetarded's Portainer keeps its stacks in portainer_data, which means "mount that directory" was never an instruction anyone could follow. It works for a stack manager I have never heard of, as long as it runs on the same machine, and it stays quiet rather than guess when several containers mount the same depth. It also refuses to suggest a mount that would land where Docksentry already keeps something: /data is our own state directory and Portainer's, so the obliging line would have read-only-mounted a stranger's volume over our own database. Marked experimental on the page — measured against 27 Compose files on one host, all 27 right, but that is one host.

Changed

  • A fresh install keeps its data in /docksentry, not /data. /data is a busy name: Portainer keeps its stacks there, and our own shipped compose file offered to mount them at /data/compose — straight over our own state directory, where they would have been invisible. The image no longer reserves /data either. Nothing moves for an existing install: if something is already mounted at /data, that is deliberate and it still wins, so upgrading changes nothing and no volume needs touching. Which directory is ours is decided by our own files being in it, not by something being mounted there — mounting a stack manager's volume at /data must not turn it into our database. DATA_DIR overrides everything, as before.

Fixed

  • The rollback copy of a running update was reported as litter. Mid-update both containers exist — the new one is already up, and <name>_old is still what a rollback would restore from — so the status banner counted it as "left behind from an interrupted update" and offered a docker rm for it. Following that removes the one thing a failed update could fall back to. It cleared itself when the update finished, which made it look like a glitch rather than the advice it was.
  • "updating" read as "updated" in eleven languages. German said aktualisiert, which is the past tense — the badge announcing that an update is running looked like one that had finished. Same in Dutch, and the eight languages still carrying the English placeholder now have their own word. French, Italian, Spanish and Portuguese were already right.
  • A denied pull says which of the two things it probably is. pull access denied … repository does not exist is the daemon's one answer to two unrelated situations: an image built on this machine, which has nothing to pull from at all, and a private registry that wants credentials. It is also the first thing anyone who builds Docksentry themselves sees on /selfupdate. Both causes are now named — guessing one of them would be a confident wrong answer.
  • The storage check accused a volume somebody else mounted. It looks for a mount whose name suggests it was meant to be the data directory — the /app/data case from #2. Once the data directory moved off /data, that heuristic started firing on whatever the user had mounted there, and told somebody who had deliberately mounted Portainer's volume at /data to make it Docksentry's database instead. Following that buries our state inside another tool's volume. /data is no longer treated as a candidate; every other spelling of the mistake still is.
  • An ssh:// host pays for its connection once, not once per command. A bare ssh … true to a managed host costs 355 ms, so three quarters of every docker -H ssh://… call was the handshake — and a page render makes several per host. The image now multiplexes: the same call goes from 475 ms to 148 ms, and the status page from 2.55 s to 1.32 s. Configured in the image's own ssh_config, deliberately — your ~/.ssh is yours.
  • The managed hosts are asked side by side, and asked once. Every host was queried in turn, so the status page paid the sum of all of them; and each was probed with one ps and then listed with a second, asking the same question twice. Measured across four hosts, one of them over ssh: 3.66 s for the status page and 3.02 s for the V2 document, against 2.55 s and 1.93 s after. A host that fails still becomes a line in the table rather than an exception, and the order on screen still follows the configuration, not whichever answered first.
  • A host that keeps failing is asked less and less often. One minute is the right patience for a machine rebooting; it is the wrong one for an endpoint typo'd into DOCKER_HOSTS months ago, which then spent its full timeout on every page load a minute apart. The wait now doubles per consecutive failure up to fifteen minutes, and any success puts it straight back to one minute.
  • One unreachable host made every page load wait ten seconds. The status page probes each managed host before listing it, and a dead endpoint spends the full timeout every single time. Measured on an install with one host down: 13.6 seconds for the status page and 13.0 for the V2 document, against 0.08 for a page that does not build that list — and reloading to see whether the host came back, which is exactly what a reader does, paid the wait again. A host that just failed is now remembered for a minute and skipped, with the reason it gave. Same install after the change: 3.7 and 3.0 seconds. Long enough that reloading is free, short enough that a host coming back is noticed within the minute.
  • One unreachable host took the whole V2 status page down. /api/v2/status read every host view's host key, but a host that cannot be reached is deliberately recorded as {"unreachable": …} instead — so the endpoint raised a KeyError and answered nothing. The V2 page is drawn entirely from that document and polls it every 30 seconds, which means on a multi-host install with one host down — the normal case, not the exotic one — the page simply never filled in. The dead host is now listed and marked, the way the classic table has always shown it.
  • Discord's /selfupdate never worked. It called bot.check_selfupdate, a method that does not exist — so every invocation since v2.13.0 promised "Self-update started" and then answered "Something went wrong". Nobody reported it, which is its own small lesson.
  • /changelog read the container's labels on the wrong machine. The lookup ran a hardcoded docker inspect with no host routing: on Podman it answered nothing, and on a multi-host install it always asked the local daemon (#7). The host was being passed in and quietly dropped halfway through, so two containers with the same name on different hosts meant the local one answered — not an error, just the wrong repository linked.
  • The Compose mount example could not work. The docs suggested - /path/to/your/stacks:/stacks:ro. Docksentry opens the absolute path recorded in the container's own label, so the mount has to land on that same path — anything else counts as unreachable and quietly takes the rebuild path instead. Same class of mistake as the README line that cost someone a week.

Changed

  • The Compose fallback only speaks up when the rebuild actually lost something. It used to fire for every Compose container whose file was out of reach, whether or not anything was worse off for it — @LeeNX asked whether healthchecks were even the point, and on one real host with 22 containers, 18 got the note while 3 were losing anything (#65). Docksentry now looks at the container in front of it and names what it is about to drop: a Compose healthcheck in exec form, long-form tmpfs volumes, blkio_config, cgroup_parent, device_cgroup_rules, storage_opt, -P. Nothing from that list set means no message. Two paths that fell into the rebuild in total silence — a remote host, and Compose labels without a file list — now say the same thing as the rest.
  • A crash alert says when it measured. Two lines both read "at event time" and meant different moments: the top-consumer lists come from the snapshot taken as the container died, the line about the container itself from the sweep afterwards, when it was already booting again. @NotRetarded read 59% CPU there and reasonably took it for the state before the crash (#66). They are worded apart now. And the CPU line no longer disappears when nothing was busy — below the threshold it says so, because "nothing was going on" and "not measured" should not look identical.
  • A stable-window that looked like a setting is a constant. crashloop_stable_seconds was read through a getattr against the config, appeared in no config file and no documentation, and nothing has ever set it. A knob nobody can reach is worse than a number in the open.