As a developer relying on Debian or Ubuntu for work, being able to efficiently manage software on your system is critical. Whether deploying application dependencies, installing tools or keeping everything updated – package management plays a huge role.

Debian‘s apt and dpkg utilities help automate this via access to organized repositories containing over 60,000 open source packages. In this comprehensive guide, we dive deep into all aspects of Debian packages – from insights only developers would care about to best practices for integrations.

After reading, you‘ll be fully empowered to control your Debian environment as a power user!

Deb Packages Under the Hood

Debian packages software in .deb files – these are archives bundling binaries, libs, docs and other components that make up a release.

As a developer, understanding what comprises a .deb format can help you better leverage it for deployments.

Inside we find the following folders:

Control metadata

  • control – Package details like version, maintainer, dependencies
  • conffiles – Configuration files that get tracked

Install payload

  • ./ – Root folder containing installable files/dirs mirroring system layout
  • ./usr/bin – Binaries and scripts
  • ./usr/share/doc – Documentation
  • ./etc – Configuration files

Package builder scripts

  • preinst – Execute before unpacking (install hook)
  • postinst – Run after unpacking (configure hook)
  • prerm – Execute before removing (uninstall hook)
  • postrm – Run after removing

So .deb packages encapsulate everything required – the software itself along with metadata and custom logic via helper scripts.

Let‘s see how we can work with them.

APT Repositories

APT relies on repositories to find packages to install. Repos are collections of .deb files containing software and metadata.

The main config file at /etc/apt/sources.list defines repositories to use.

deb http://us.archive.ubuntu.com/ubuntu/ focal main
deb-src http://us.archive.ubuntu.com/ubuntu/ focal main

Here we have 2 repos enabled:

  • deb: Binary packages
  • deb-src: Source code packages

When running apt commands, the package manager consults these repositories, downloads the .deb files needed and handles installation.

The metadata helps determine distro release compatibility and fetch latest versions.

Common repository sections:

  • main – Officially supported software
  • restricted – Proprietary drivers
  • universe – Community maintained software
  • multiverse – Software without a free license

Using apt update syncs the local cache with the remote repositories to ensure you have latest package data.

Understanding DPKG

dpkg is the lower level package manager that can install, remove, list and query .deb packages.

sudo dpkg -i myapp_1.3-2_amd64.deb

Installs the .deb file directly by unpacking contents into filesystem.

However, dpkg will not fetch dependencies or repos. The package itself must provide everything needed. This is where apt comes in with higher level features.

Checking Package Contents

dpkg lets us introspect the contents of both installed and uninstalled .deb files.

dpkg --contents postgresql_12.6-r0_amd64.deb

Lists files that would get unpacked without actually installing!

dpkg -L postgresql

Displays all files installed on the system under a package.

This allows developers to inspect package payloads and inventory deployed files.

Understanding APT

The Advanced Packaging Tool apt improves ease of use and automates repository access.

Operations like:

sudo apt update
sudo apt install postgresql

Fetch latest metadata and install software with all dependencies handled automatically.

Under the hood APT relies on dpkg for low level .deb unpacking after downloading packages itself.

This abstraction and automation makes the developer experience smoother. We should utilize APT whenever possible.

Aptitude – Interactive Frontend

Aptitude provides an ncurses interactive UI on top of APT + dpkg. Launch via:

sudo aptitude

It presents menu driven navigation, ability to queue up actions before applying in bulk and a visual interface making package management easier.

Aptitude console UI

Especially useful in case of conflicts – aptitude makes resolving dependencies and previews smoother.

The terminal environment aptitude operates in does however limit advanced UX concepts today‘s devs may expect. But it‘s still quite handy for server deployments.

For graphical interface, consider GNOME Software or Synaptic on the desktop.

Key Uses Cases for Developers

Now that we understand the internals, let‘s explore some common developer workflows.

Environment Setup

When setting up a programming environment on a new Debian install, APT radically simplifies matters.

Want to get PostgreSQL running? Just:

sudo apt install postgresql postgresql-contrib

Steps like downloading binaries, resolving individual library dependencies, integrating components – all hand held automatically!

This leaves devs free to focus on just domain specific configuration.

For mass deploying development machines – APT combined with a configuration management system like Ansible, Puppet or Chef makes bootstrapping efficient.

Deploying Apps

Shipping apps as .deb packages helps streamline deployment on Debian systems.

By bundling runtimes, defining dependencies and adding install hooks – you can package your app as a .deb file directly consumable via dpkg or apt.

sudo dpkg -i myapp_1.3-2_amd64.deb

Tools like fpm or mkdeb help automate generating .deb packages from source code.

The Debian new maintainer‘s guide offers an in-depth look at constructing .deb files compliant with system policies.

User Safety

Developers need latest versions and rapid updates. But production servers prefer stability. APT supports both models.

For user systems, security fixes can automatically install via:

Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
};

This ensures Vulnerabilities get patched without admin effort.

Whereas your build servers can explicitly track unstable or QA repos for fresher packages.

Balancing production use vs developer flexibility is crucial when managing environments at scale.

Offline Devlopment

Devs working in secure environments disconnected from the internet still need access to tools.

APT + dpkg offer offline functionality:

Mirror package pool locally

apt-mirror \
   --arch amd64 \
   --section main,restricted \
   --host ftp.debian.org  \
   --root ~/apt-mirror

Satisfy dependencies from mirror

Create /etc/apt/sources.list entry pointing to the local dir. Then installations will fetch packages from the mirrored subset without any external connectivity.

Handy for developers focused on building software rather than ops.

Advanced Package Management

Now that we‘ve covered the most common cases – let‘s discuss some pro tips for package management.

Mixing Multiple Distro Releases

Developers often test software across multiple Debian / Ubuntu versions. Managing different repo lists can get tedious.

Instead extend your main sources.list file like:

deb [arch=amd64 trusted=yes] http://archive.ubuntu.com/ubuntu/ focal main restricted
deb [arch=amd64 trusted=yes] http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted

Now you have both Ubuntu 20.04 and 18.04 enabled on the same system!

Next create preferences to prevent incompatible packages from co-installing:

Package: *
Pin: release n=focal
Pin-Priority: 900

Package: *  
Pin: release n=bionic 
Pin-Priority: 700

This makes APT prefer focal over bionic packages.

Finally, when installing specify release codename:

apt install -t bionic postgresql-10

Fetch just that one package from 18.04 repos.

With some tweaks, developers can leverage mixing releases for testing without virtualization overhead.

Auto Patching Systems

Servers running 24/7 can‘t rely on admins to manually run updates. Automating patches improves reliability and security.

The unattended-upgrades package helps:

sudo apt install unattended-upgrades

To enable automatic updates, edit /etc/apt/apt.conf.d/50unattended-upgrades:

Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
};

Now it will automatically apply security patches!

We can also enable automatic restarts for kernel updates via:

Unattended-Upgrade::Automatic-Reboot "true";

This way Debian servers stay secure with zero admin effort. One less thing for devops teams to worry about.

Compiling From Source

While Debian packages pre-built software, sometimes you need to compile from source for customization or debugging.

This poses challenges like:

  • Resolving build dependencies
  • Integrating with system libraries
  • Avoiding conflicts between distro packages and source

Here APT can automatically setup the build environment:

sudo apt build-dep postgresql

This installs all compiler packages, underlying libraries needed to compile the software.

Use --compile to remove build dependencies afterwards:

sudo apt --compile install postgresql

By leveraging apt before compiling from source, you avoid manually tracking every single -dev package needed.

Recovery & Forensics

Since developers push systems in extreme ways, having recovery options is useful.

APT keeps detailed logs at /var/log/dpkg.log* and /var/log/apt/*.log tracking all installs, upgrades, downgrades and removals.

These can help identity what corrupted a system or analyse configuration drift when troubleshooting crashes.

You can also list all packages installed on a given date:

grep " install " /var/log/dpkg.log* | grep " 2021-10-14 "

Or packages that were upgraded:

grep " upgrade " /var/log/dpkg.log* 

low level information but very handy when systems need restoration.

Developing on Debian

I hope this guide has shed light into Debian package internals from a developer perspective. Let‘s recap key insights:

  • .deb packages bundles apps as complete filesystem images
  • Built-in scripts allow custom install logic
  • Mix multiple distro releases for portable testing
  • Granular pinning priorities to avoid conflicts
  • Enable automatic security patching for prod
  • Utilize apt to easily setup build environments
  • Leverage logs for diagnostics when things break

Learning the internals of core operating system components is important towards mastering development. Hopefully understanding dpkg and apt leads to Debian excellence!

Similar Posts