Fix: containers exit with code 139 on 32-bit ARM models (TS-x31P3, TS-x31X...) - 32K page size explained + working Pi-hole v6 / Syncthing images

If you own a 32-bit ARM QNAP (TS-431P3, TS-231P3, TS-x31X, TS-431KX, TS-1635…) and most Docker images in Container Station die instantly - exit code 139, completely empty logs - here’s the full explanation and a working fix.

Why it happens (two separate causes):

  1. These CPUs (Annapurna AL314, Cortex-A15) are 32-bit ARMv7. Images built for arm64 or amd64 can never run; only linux/arm/v7 images are candidates.
  2. QNAP builds the kernel for these models with a 32 KB memory page size instead of the standard 4 KB (documented in QNAP’s own KB: “How to debug and fix common container issues in Container Station”). Any binary aligned for 4 K pages segfaults at load. This breaks the userland of Alpine >= 3.18, Debian bookworm, and Ubuntu 24.04 - which covers most modern images, including Pi-hole v6, Home Assistant, and Nextcloud. The current QTS 5.2.x still ships this kernel (4.2.8).

Bases verified to work: Ubuntu 22.04, Debian bullseye, Alpine <= 3.17, static Go binaries.

The fix: in most cases the app’s core binary is static and page-size-safe - only the Alpine userland crashes. Repackage the unmodified official binaries on ubuntu:22.04 and it works. I published ready-made arm/v7 images for Pi-hole v6 and Syncthing (auto-rebuilt weekly against upstream), the Dockerfiles, a Container Station compose example, a v5 → v6 Pi-hole migration guide, and a step-by-step recipe to fix other images yourself:

Everything verified live on a TS-431P3 running QTS 5.2.9. MIT-licensed. (For Home Assistant specifically, see albertogeniola/homeassistant-qnap-32k, which applies the same idea.)

moved to container subsection

Better yet, write your own YAML code for Containers and skip the pre-packaged ones. Generally you want to do that anyhow, so you can manage storage, etc.