App ecoDMS: how to expose a folder as a network share when the node already runs the Samba AD module?

Context.
I’m packaging ecoDMS as an NS8 module. ecoDMS is a document archive system. It has several input options for PDFs, besindes others there is a scaninput folder — a watched drop directory where scanners/users deposit pdf documents, which ecoDMS then auto-imports and deletes. I want to expose it as a network share, ideally AD-authenticated. Inside the ecoDMS container this maps cleanly: if a volume is mounted at /srv/scaninput, ecoDMS symlinks its import folder to it (verified in the image’s check_env.sh). The question is purely how to serve that folder on the network.

Constraints:

  • The Samba module (AD DC + file server) already binds :445 on the node IPs
  • NS8 has no per-module “dedicated IP” primitive. The Samba module’s dedicated IP is an address the admin pre-configures on the NIC out-of-band; Samba merely bind()s it. There is no core action/UI to allocate one, and nothing that creates macvlan/ipvlan or a static-IP podman network for a module.
  • Rootless modules are UID-isolated — each runs as its own Linux user with its own subuid range and 0700 home, so one rootless module can’t traverse into or delete files in another’s podman volume.

** Options**

  1. WebDAV sidecar, routed through the existing Traefik HTTPS route (rootless, self-contained)
    Add a small WebDAV container to ecoDMS’s own pod, sharing the same scaninput volume. Because it’s in the same pod / same module user, there is no UID-isolation problem at all — both containers see the volume natively. It rides the module’s existing Traefik
    route (e.g. https://ecodms.example.org/scaninput/), so no extra port, no :445, no dedicated IP, stays rootless.
    pro
    – Fully portable, no privilege escalation, no coupling to the Samba module, ecoDMS keeps its own volume.
    con
    — WebDAV ≠ SMB: Windows can map it as a drive (WebClient service, HTTPS) but many MFP scanners speak SMB/FTP, not WebDAV. AD auth needs the WebDAV server configured to LDAP-bind against Samba (or Traefik forward-auth).

  2. Reuse the Samba server — rootfull bind-mount
    Create a scaninput share on the Samba module; make ecoDMS rootfull and bind-mount the Samba share’s backing directory into the container. I verified a rootfull container can read and delete Samba-written files under enforcing SELinux, with Samba unaffected.
    pro
    – No credentials, instant ingestion, no second SMB server, real AD auth for the drop.
    con
    – ecoDMS becomes privileged (rootfull); only works when Samba is on the same node; reaches into the Samba module’s internal podman volume path (fragile if the instance is renamed/relocated).

  3. Reuse the Samba server — rootless smbclient poll sidecar
    Keep ecoDMS rootless; a sidecar uses smbclient (userspace, no kernel mount, no privileges) to poll the Samba share every ~30 s,
    copy new scans into ecoDMS’s local folder, and delete them from the share.
    pro
    – Rootless, no storage coupling, and works against a remote file server too.
    con
    – Needs a service-account credential to authenticate; ingestion is polled, not instant.

  4. Own SMB sidecar on an admin-provided dedicated IP
    Run our own smbd in the ecoDMS pod and bind :445 on a second node IP the admin adds by hand (bind interfaces only), joining AD as a member for auth.
    pro
    – Self-contained, real SMB, decoupled from the Samba module.
    con
    – Requires a manual host-networking step (not portable — NS8 won’t manage/release the IP) and an AD member-join; heaviest option.

Considered and rejected: shared-disk volume + coordinated GID across two rootless modules (brittle cross-userns GID mapping); FTP/SFTP sidecar (port 21+passive range, or :22 clashes with host sshd); ecoDMS’s own web-client upload (licence-gated in the community image).

Question for the community

  1. Is there a supported NS8 pattern for cross-module file/share access that I’ve missed — e.g. a blessed way for module B to consume a share hosted by the Samba module, without going rootfull or reaching into its volume path?
  2. For a document-scanning drop folder, would you steer a module toward WebDAV-over-Traefik (A) for portability, or reusing Samba (B/C) for native SMB + AD? Any precedent modules doing either?

About question 1, nothing comes to my mind, but I remember @oneitonitram has raised a similar question in the past. The rootless subuid/subgid namespace mapping should not be bypassed, and going rootfull to do it would be unacceptable.

For question 2, I think I’d go with option 3 – Configure a smbclient access in the ecoDMS application (share UNC name, user name + password), allowing access to both SMB shares provided by NS8 itself, or external file servers. Start polling the designed SMB share.

@davidep, thanks for the thoughts — and for pulling @oneitonitram into this, more on that below.

Your take on rootfull makes complete sense from a NethServer perspective. The subuid/subgid isolation is a core promise of NS8, and weakening it for a single module’s edge case would be the wrong call.

From the ecoDMS side, though, that’s exactly what blocks a highly relevant feature. The scaninput folder is one of ecoDMS’s central ingestion paths, and the proposed smbclient poll approach (Option 3) noticeably cripples it: “instant ingestion” turns into a ~30 s poll with a service-account credential. ecodms includes such a feature already internally (poll by shedule from path)

For context on where the folder actually sits: ecoDMS’s own import directory lives inside its working dir (/opt/ecodms/workdir/scaninput), and at container startup check_env.sh replaces it with a symlink pointing at the mounted volume /srv/scaninput (the startup log even prints Linking Scaninput to /srv/scaninput). In other words, whatever is mounted at /srv/scaninput is exactly the directory ecoDMS watches and auto-imports from — that’s the single point everything has to reach.

I’ll admit this puts me in a real dilemma of conscience — and honestly, I came into this post secretly hoping for some kind of absolution for going rootfull, even though I hold the opposite view myself. And that’s telling: the fact that it would take rootfull to do cleanly is a fairly clear sign that these two systems can’t — or shouldn’t — run coupled like that.

Incidentally, I think @oneitonitram runs into the same underlying problem with ns8-chiefonboarding (persistent volumes / uploads across the module boundary), so it’s fitting that you’re the one who brought him up.

Where I’m currently leaning is actually Option 4 — our own smbd sidecar in the ecoDMS pod, bound to an admin-provided dedicated IP and joined to AD as a member. It’s the heaviest option, but it’s the one that supports both systems best: ecoDMS keeps real SMB + native AD auth on its drop folder with no compromise, and we stay rootless without reaching into the Samba module’s volume. The annoying downside is that I’d then effectively end up with two domains / two SMB identities on the node, which feels redundant right next to the existing Samba DC.

Which leads to my actual open question: rather than joining AD as a plain member server on a second IP — could the ecoDMS-side Samba instead simply become a member of the existing NethServer domain? That would give me the native SMB drop I want without standing up what feels like a parallel domain.

About joining the ecoDMS-side Samba as a member of the existing domain instead of standing up a parallel one — I think before going there it’s worth stepping back. An smbd sidecar with its own AD membership feels like a lot of weight (and ongoing maintenance) for what’s fundamentally a drop-folder ingestion problem. I’d consider alternative paths before committing to that route.

One angle worth considering: instead of ecoDMS reaching into Samba’s share (rootfull) or polling it (Option 3), let Samba push a notification, not the files themselves.

  • An inotify watcher inside the Samba container monitors a target directory in a share.
  • On new files, Samba emits an event through Redis, using NS8’s existing event/task infrastructure — no custom protocol, no new port.
  • Any interested module (ecoDMS, or others in the future) subscribes to that event and pulls the new files itself, e.g. via smbclient or an equivalent client-side tool like rclone, over the cluster VPN.

This keeps Samba rootless and ignorant of who’s consuming its shares — same posture it already has as a generic file server — while giving near-instant reactivity instead of a poll loop, and without requiring same-node placement or a dedicated IP. It also generalizes beyond ecoDMS: any module needing “share changed” notifications gets the same primitive for free, rather than one-off glue code per integration.

Caveat: the inotify side needs real scrutiny before this is more than a sketch — partial writes, event coalescing/overflow under bursty scan jobs, and reconciliation against missed events all need a solid answer. Flagging it here mainly to get feedback on the overall shape before diving into that.