When managing LXC container templates, installing packages in chroot environments creates an annoying issue - services automatically start during installation. This results in multiple duplicate service instances running on the host system, as recently happened when I needed to install rsyslog across several templates:
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
chroot $template apt-get install rsyslog
done
While Debian policy suggests services shouldn't start in chroot environments, in practice many packages still launch their services during installation. The issue stems from maintainer scripts (postinst) that don't properly check for chroot environments before starting services.
Here are several effective approaches to prevent service startup during package installation:
# Method 1: Using policy-rc.d
cat < /path/to/chroot/usr/sbin/policy-rc.d
#!/bin/sh
exit 101
EOF
chmod +x /path/to/chroot/usr/sbin/policy-rc.d
The second method uses environment variables:
# Method 2: Environment variable approach
chroot $template /bin/bash -c "export RUNLEVEL=1; apt-get -y install package-name"
For more complex scenarios, consider mounting a custom policy-rc.d:
# Method 3: Temporary mount solution
mount --bind /path/to/custom/policy-rc.d $template/usr/sbin/policy-rc.d
chroot $template apt-get install package
umount $template/usr/sbin/policy-rc.d
Some packages require special handling. For example, with exim4:
debconf-set-selections <<< "exim4-config exim4/dc_eximconfig_configtype select local"
chroot $template apt-get -o Dpkg::Options::="--force-confold" install exim4
For systems using systemd, additional precautions are needed:
# Prevent systemd units from starting
ln -s /dev/null $template/etc/systemd/system/package.service
chroot $template systemctl daemon-reload
When building LXC container templates on Debian/Ubuntu systems, a common pain point emerges: package installations automatically start associated services, even in chroot environments. This creates multiple running instances of services like rsyslog or exim4 when you're just trying to prepare container templates.
The default package installation process in Debian-based systems follows this sequence:
1. Package files are extracted
2. Pre-installation scripts run
3. Main package files installed
4. Post-installation scripts run (often including service activation)
5. Service gets enabled in default runlevel
Method 1: Using policy-rc.d
The cleanest approach is creating a /usr/sbin/policy-rc.d
script in your chroot environment before installation:
#!/bin/sh
exit 101
Then make it executable:
chmod +x /usr/sbin/policy-rc.d
Method 2: APT Configuration Approach
Create or modify /etc/apt/apt.conf.d/
with:
DPkg::Pre-Invoke {"if [ -x /usr/sbin/policy-rc.d ]; then /usr/sbin/policy-rc.d || true; fi";};
DPkg::Post-Invoke {"if [ -x /usr/sbin/policy-rc.d ]; then /usr/sbin/policy-rc.d || true; fi";};
Method 3: Package-Specific Solutions
Some packages respect environment variables:
DEBIAN_FRONTEND=noninteractive \\
NEEDRESTART_MODE=a \\
apt-get install -y --no-install-recommends rsyslog
For your LXC template scenario, here's a complete solution:
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
# Create policy-rc.d
echo -e '#!/bin/sh\nexit 101' > $template/usr/sbin/policy-rc.d
chmod +x $template/usr/sbin/policy-rc.d
# Install package with prevention measures
chroot $template env DEBIAN_FRONTEND=noninteractive \\
apt-get install -y --no-install-recommends rsyslog
# Cleanup (optional)
rm $template/usr/sbin/policy-rc.d
done
After installation, verify no services are running:
ps aux | grep rsyslog
service --status-all
If services still start, check for:
- Missing policy-rc.d executable permissions
- Package-specific init systems (systemd units might bypass traditional methods)
- Incorrect chroot environment setup