← Back to Wiki
Docker / Self-Hosting

Docker's Own Installer Can Silently Half-Fail on a Fresh, Non-Interactive Container

Scripting a new LXC or minimal VM's provisioning end-to-end — including installing Docker — over a non-interactive SSH session is a completely reasonable thing to automate. It can also fail in a way that leaves Docker looking almost installed: the package reports itself present, but the daemon won't actually start.

Share on X

The symptom

Running apt-get install docker-ce over a plain non-interactive SSH command on a freshly provisioned Ubuntu/Debian LXC or VM can partially fail with something like:

dpkg: error processing package docker-ce (--configure):

followed later by real, confusing downstream symptoms once you try to actually use Docker:

Failed to resolve group docker: No such process

docker.socket refuses to start, and the docker group — which the package's own post-install step is supposed to create — simply doesn't exist. dpkg -l may still list docker-ce as installed, which makes this easy to misread as some unrelated permissions problem rather than an incomplete install.

Why it happens

docker-ce's post-install (postinst) script expects an interactive debconf frontend to run some of its setup steps. Over a non-interactive SSH session — exactly the shape of a scripted provisioning flow — that frontend isn't available, and the postinst partially fails instead of gracefully skipping the interactive-only parts. The package ends up in a half-configured state: present, but not fully set up.

This doesn't seem to hit every fresh container the same way. Provisioning multiple LXCs with what looked like an identical process, only some of them hit this — it may be timing- or order-dependent within the install sequence rather than deterministic. Don't assume a provisioning script that worked cleanly last time is guaranteed to work cleanly this time; check for this specifically after any fresh Docker install done non-interactively, rather than only when something visibly breaks.

The fix

Finish the interrupted postinst explicitly, then start the pieces it should have started:

DEBIAN_FRONTEND=noninteractive dpkg --configure -a
systemctl enable --now docker.socket docker.service

This re-runs the configuration step with the noninteractive frontend forced, which lets it complete the parts that failed the first time (including creating the docker group), then explicitly brings the socket and daemon up rather than assuming they'll start on their own.

Worth adding to any provisioning script targeting fresh containers

If you're scripting Docker onto new LXCs/VMs as a repeatable pattern, it's worth running the fix commands above unconditionally right after the install step — they're harmless no-ops on a container where the install succeeded cleanly, and they silently save you from debugging a "docker isn't working" report that actually traces back to a postinst step that never got a chance to finish.