Creating Ubuntu DEB Packages: Complete Guide

Creating DEB packages for Ubuntu allows you to distribute software efficiently and integrate with the system’s package management. This guide provides a comprehensive walkthrough of the Ubuntu package creation process, from initial setup to building release-ready packages.

Prerequisites and System Requirements

Before beginning package creation, ensure your system has the necessary development tools installed. The packaging process requires specific Debian utilities and a properly configured development environment.

For comprehensive package management workflows using containerized development environments, see our Ubuntu containerized packaging guide, which demonstrates how to set up isolated Ubuntu containers for safe package development without affecting your host system.

Required Packages

Install the essential packaging tools:

sudo apt install dh-make devscripts reprepro build-essential

Package explanations:

  • dh-make: Creates debian package templates and directory structure
  • devscripts: Collection of scripts for Debian package development
  • reprepro: Tool for creating and managing APT repositories
  • build-essential: Meta-package with essential compilation tools

Environment Configuration

Set up your developer identity for package signing and metadata:

export EMAIL="your.email@example.com"
export DEBFULLNAME="Your Full Name"

Important: Replace these values with your actual email and name. These will appear in package metadata and changelogs.

For secure package signing operations, you’ll need GPG key management configured properly. This includes key generation, import/export capabilities, and digital signature workflows essential for official package distribution.

Package Structure and Initialization

Ubuntu packages follow the Debian packaging standard, requiring specific directory structures and metadata files.

Creating the Package Base

Start by creating a directory with your package name and version:

mkdir your-package-1.0
cd your-package-1.0

Naming convention: Use the format packagename-version where:

  • Package name should be lowercase with hyphens for separators
  • Version follows semantic versioning (e.g., 1.0, 2.1.3)

Initializing Package Templates

Generate the debian packaging templates:

dh_make --indep --createorig --email your.email@example.com

Parameter explanations:

  • --indep: Creates architecture-independent package (for scripts, data files)
  • --createorig: Creates original source tarball
  • --email: Specifies maintainer email address

Alternative options:

  • Use --single for architecture-specific packages
  • Use --multi for packages that generate multiple binary packages

Building Your First Package

The initial package build creates a DEB file from your source code and debian configuration.

First-Time Package Build

For the initial build, use the following command:

debuild -b -rfakeroot -us -uc

Parameter breakdown:

  • -b: Build binary package only (no source package)
  • -rfakeroot: Use fakeroot to simulate root privileges
  • -us: Don’t sign the source package
  • -uc: Don’t sign the changes file

This creates a .deb file in the parent directory that can be installed with dpkg -i.

Package Content Organization

Before building, organize your package content:

mkdir -p debian/your-package/usr/bin
mkdir -p debian/your-package/usr/share/doc/your-package
mkdir -p debian/your-package/etc

Place your files in the appropriate directories under debian/your-package/ to match their final system locations.

Version Management and Releases

Proper version management ensures smooth updates and maintains package repository consistency.

Creating New Releases

When preparing a new version, update the changelog:

debchange

This opens an editor where you can:

  • Increment the version number
  • Add release notes and changes
  • Set the distribution (stable, testing, unstable)

Best practices:

  • Use semantic versioning (MAJOR.MINOR.PATCH)
  • Include meaningful change descriptions
  • Set appropriate urgency levels (low, medium, high)

Release Distribution Settings

Common distribution values:

  • stable: Production-ready releases
  • testing: Pre-release versions
  • unstable: Development versions
  • UNRELEASED: Work-in-progress versions

Production Package Building

For release builds, use the standard debian build process:

debuild -us -uc -i -I -b

Parameters explained:

  • -us: Don’t sign source (for unsigned builds)
  • -uc: Don’t sign changes file
  • -i: Ignore VCS files (git, svn directories)
  • -I: Ignore patterns in debian/.gitignore
  • -b: Build binary package only

Signed Package Building

For official releases, create signed packages:

debuild -b

This requires:

  • GPG key configured on your system
  • Key registered with package repository
  • Proper GPG agent setup

Package Testing and Validation

Before distributing packages, thoroughly test the installation and functionality.

Local Installation Testing

Test your package locally:

sudo dpkg -i ../your-package_1.0_all.deb

Verify installation:

  • Check that files are placed correctly
  • Test application functionality
  • Verify dependencies are satisfied

Dependency Verification

Check package dependencies:

dpkg-deb -f your-package_1.0_all.deb

Package Removal Testing

Test clean removal:

sudo apt remove your-package

Ensure no orphaned files remain and system remains stable.

Cross-Platform Package Management

Comparison with Arch Linux Packaging

Ubuntu’s DEB packaging system differs significantly from Arch Linux’s PKGBUILD approach. While Ubuntu uses debian/ directories and complex build scripts, Arch Linux package creation uses simpler PKGBUILD files with bash functions. Key differences include:

  • Build System: Ubuntu uses debhelper vs Arch’s makepkg
  • Dependency Format: Ubuntu control files vs Arch PKGBUILD arrays
  • Package Management: pacman commands vs apt operations
  • Repository Structure: Ubuntu’s multi-component repos vs Arch’s simpler hierarchy

Development Environment Automation

For comprehensive development environment setup that includes packaging tools, consider automated installation workflows. The Hyprland desktop setup includes development tools, terminal utilities, and complete shell configuration that complement package development workflows.

Advanced Package Configuration

Control File Customization

  • Package dependencies
  • Architecture requirements
  • Description and metadata
  • Maintainer information

Post-Installation Scripts

Create scripts in debian/ directory:

  • postinst: Run after installation
  • prerm: Run before removal
  • postrm: Run after removal
  • preinst: Run before installation

Service Integration

For packages that install services:

mkdir -p debian/your-package/etc/systemd/system
cp your-service.service debian/your-package/etc/systemd/system/

Repository Management

Creating Local Repository

Use reprepro to create a local APT repository:

mkdir -p repo/conf
cd repo
reprepro -b . include stable ../your-package_1.0_all.changes

Repository Configuration

Create conf/distributions:

Origin: Your Repository
Label: Your Repository
Codename: stable
Architectures: i386 amd64 source
Components: main
Description: Custom package repository

Common Issues and Troubleshooting

Build Failures

Missing dependencies:

sudo apt build-dep your-package

Permission issues:

  • Ensure proper file permissions in package structure
  • Use fakeroot for privilege simulation

Package Conflicts

Version conflicts:

  • Update version numbers properly
  • Check for conflicting package names

File conflicts:

  • Verify no files overlap with existing packages
  • Use dpkg -S filename to check file ownership

Best Practices and Recommendations

Package Naming

  • Use lowercase names with hyphens
  • Follow Debian naming conventions
  • Avoid conflicts with existing packages

Version Management

  • Follow semantic versioning
  • Use meaningful changelog entries
  • Test version upgrades thoroughly

Security Considerations

  • Sign packages for production use
  • Validate dependencies for security
  • Keep build environment secure

Documentation

  • Include comprehensive package descriptions
  • Provide installation and usage instructions
  • Document configuration options

References and Resources

Official Documentation

Development Tools

Community Resources

Questions Answered in This Document

Q: What packages do I need to install to create Ubuntu DEB packages? A: You need to install dh-make, devscripts, reprepro, and build-essential using sudo apt install dh-make devscripts reprepro build-essential.

Q: How do I create the initial package structure? A: Create a directory with your package name and version, then use dh_make --indep --createorig --email your.email@example.com to generate the debian packaging templates.

Q: What’s the difference between first-time and subsequent package builds? A: First-time builds use debuild -b -rfakeroot -us -uc for basic unsigned packages, while subsequent builds use debuild -us -uc -i -I -b for cleaner release builds.

Q: How do I update the version number for a new release? A: Use the debchange command to open an editor where you can increment the version number, add release notes, and set the distribution target.

Q: What does the —indep flag do in dh_make? A: The --indep flag creates an architecture-independent package suitable for scripts, configuration files, and data that works on any architecture.

Q: How do I test my package before distribution? A: Install locally with sudo dpkg -i package.deb, test functionality, verify file placement, and test removal with sudo apt remove package-name.

Q: What’s the purpose of the EMAIL and DEBFULLNAME environment variables? A: These variables set the maintainer information that appears in package metadata, changelogs, and signing information.

Q: How do I create a signed package for official distribution? A: Use debuild -b without the -us and -uc flags, ensuring you have a properly configured GPG key for package signing.

Q: What directory structure should I use for package contents? A: Place files under debian/your-package/ in their final system locations, such as debian/your-package/usr/bin/ for executables.

Q: How do I create a local APT repository for my packages? A: Use reprepro to create a repository structure and include packages with reprepro -b . include stable package.changes.