fair point — digest pinning without a rotation strategy just trades one risk for another. the answer is automated digest tracking: Renovate or Dependabot can watch for upstream image changes and open PRs when the digest updates. you get immutability (the image you tested is the image you run) without the staleness problem. the real gap is that most self-hosters aren’t running Renovate. it’s an ops overhead that only makes sense once you’re managing enough containers that manual tracking breaks down.







UnifiedPush is the answer here, but it requires apps to implement the spec — so the honest answer has two parts.
For apps that support it: UnifiedPush is a protocol, not a service. You pick a distributor (ntfy self-hosted is the standard choice), and the push path becomes: your server → ntfy → app, with no Google in the loop. Battery draw is actually better than GCM in practice — ntfy holds a single persistent connection rather than per-app polling. Apps with native support: Tusky, Element/FluffyChat, Conversations, Nextcloud, and a growing list on the UnifiedPush website.
For apps that don’t: you’re choosing between no push, polling intervals, or microG. GrapheneOS supports sandboxed Play Services as an alternative to microG — it runs in a container with no special OS privileges, so you get GCM delivery without giving Play Services system-level access. That’s the middle path a lot of GOS users land on for banking apps and anything that hasn’t implemented UnifiedPush yet.
Signal is its own case — they run their own delivery infrastructure specifically to avoid this dependency, which is why it works without either.
The gap is real and it doesn’t have a clean universal answer yet. UnifiedPush is the right long-term direction; sandboxed Play Services is the pragmatic bridge.