Skip to content

Debian & Ubuntu — Footguns & Pitfalls


1. apt update vs apt upgrade

# This does NOT upgrade packages — only refreshes the package index
sudo apt update

# THIS upgrades packages
sudo apt upgrade

# People forget to run update first — then upgrade sees nothing to do
sudo apt upgrade    # "0 upgraded" — because index is stale!

Always run apt update before apt upgrade.


2. remove vs purge

# Leaves config files behind (in /etc/)
sudo apt remove nginx

# Removes everything including config
sudo apt purge nginx

If you remove and reinstall, the old (possibly broken) config is still there. Use purge when you want a clean slate.


3. snap Loop Mounts Polluting df Output

$ df -h
# Shows 20+ /snap/... loop mounts cluttering output

# Filter them out
df -h --exclude-type=squashfs
df -h -x squashfs

# Or alias it
alias df='df -h -x squashfs'

4. Unattended Upgrades Rebooting at Bad Times

# Default config may auto-reboot
# /etc/apt/apt.conf.d/50unattended-upgrades

# Dangerous default:
Unattended-Upgrade::Automatic-Reboot "true";

# Fix: disable auto-reboot
Unattended-Upgrade::Automatic-Reboot "false";

# Or set a safe time
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

5. PPA Packages Breaking on Upgrade

# PPAs are tied to a specific Ubuntu release
sudo add-apt-repository ppa:some/ppa

# When you upgrade Ubuntu (22.04 → 24.04), PPAs may:
# - Have no packages for the new release
# - Cause dependency conflicts
# - Block the upgrade entirely

# Before upgrading, disable all PPAs
sudo add-apt-repository --remove ppa:some/ppa
# Or: remove files from /etc/apt/sources.list.d/

6. GPG Key Deprecation

# OLD way (deprecated, warns loudly)
curl -s https://example.com/key.gpg | sudo apt-key add -

# NEW way (Ubuntu 22.04+, Debian Bookworm+)
curl -fsSL https://example.com/key.gpg | \
  sudo gpg --dearmor -o /usr/share/keyrings/example.gpg

echo "deb [signed-by=/usr/share/keyrings/example.gpg] https://..." | \
  sudo tee /etc/apt/sources.list.d/example.list

apt-key is deprecated. Use per-repo signed-by keyrings.


7. Netplan YAML Indentation

# WRONG — will silently misconfigure
network:
  version: 2
  ethernets:
    eth0:
    addresses:           # Not indented under eth0!
      - 192.168.1.100/24

# RIGHT
network:
  version: 2
  ethernets:
    eth0:
      addresses:         # Properly indented
        - 192.168.1.100/24

Netplan errors are sometimes cryptic. Always use netplan try (auto-reverts) before netplan apply.


8. UFW + Docker Bypass

Docker manipulates iptables directly, bypassing UFW entirely.

# You think port 3306 is blocked:
sudo ufw deny 3306

# But Docker publishes -p 3306:3306 and it's open to the world!
# Docker inserts its own iptables DOCKER chain before UFW rules

Fix: Don't publish ports to 0.0.0.0. Bind to localhost:

docker run -p 127.0.0.1:3306:3306 mysql

Or use DOCKER_IPTABLES=false and manage rules manually.


9. AppArmor vs SELinux Mental Model Mismatch

Coming from RHEL: - There's no restorecon — AppArmor uses paths, not labels - There's no semanage fcontext — you edit profile files - There's no setsebool — you edit profile rules or use tunables - aa-status is your getenforce - aa-complain is your setenforce 0 (but per-profile)

Biggest trap: Assuming if AppArmor isn't blocking, nothing is wrong. AppArmor only protects processes with loaded profiles — unconfined processes have no MAC protection at all (unlike SELinux which covers everything).


10. /etc/network/interfaces vs Netplan Conflict

# If both exist, they may conflict
# Ubuntu server: uses Netplan
# Ubuntu upgraded from old version: may still have /etc/network/interfaces

# Check which is active
ls /etc/netplan/*.yaml
cat /etc/network/interfaces

# If interfaces file has config AND netplan exists, networking breaks
# Fix: migrate to netplan, empty /etc/network/interfaces to:
auto lo
iface lo inet loopback

11. Forgetting Universe/Multiverse Repos

# "Package not found" on Ubuntu?
# Probably need universe or multiverse enabled

sudo add-apt-repository universe
sudo add-apt-repository multiverse
sudo apt update

Many common tools (htop, tree, etc.) live in universe, which may not be enabled on minimal server installs.


12. dpkg Lock Contention

# "Could not get lock /var/lib/dpkg/lock-frontend"
# Another apt process is running (or crashed)

# Check what's holding it
sudo lsof /var/lib/dpkg/lock-frontend

# If it's a real process, wait. If it's a stale lock:
sudo rm /var/lib/dpkg/lock-frontend
sudo rm /var/lib/dpkg/lock
sudo dpkg --configure -a

Common cause: unattended-upgrades running in the background when you try to manually install something.