Aptfile Format
The Aptfile is a simple, line-oriented, UTF-8 encoded text file. The default filename is Aptfile, but you can specify a different path using the --file flag.
Basic Rules
- Comments: Lines beginning with
#are ignored - Empty Lines: Empty lines are ignored
- Directives: Each line consists of a directive (keyword) followed by an argument
- Quotes: Quotes (
"or') are required if the argument contains spaces or special characters
Directives
apt - Install Packages
Specifies a standard apt package to be installed.
Syntax: apt <package-name>[=<version-string>]
Logic: Corresponds to apt-get install -y <package-name>[=<version-string>]
Examples:
# Install latest version
apt vim
apt curl
apt build-essential
# Install specific version
apt "nano=2.9.3-2"
apt "docker-ce=5:19.03.13~3-0~ubuntu-focal"
Notes:
- Package names are case-sensitive
- Version strings must be quoted if they contain special characters
- If a version is specified, that exact version will be installed
- If no version is specified, the latest available version will be installed
ppa - Add Personal Package Archive
Specifies a Personal Package Archive (PPA) to be added.
Syntax: ppa <ppa:user/repo>
Logic: Corresponds to add-apt-repository -y <ppa:user/repo>
Examples:
ppa ppa:ondrej/php
ppa ppa:git-core/ppa
Notes:
- This directive implicitly handles adding the PPA’s GPG key
- PPAs must be in the format
ppa:user/repo - PPAs are typically Ubuntu-specific
deb - Add Custom Repository
Specifies a full deb repository line to be added to /etc/apt/sources.list.d/.
Syntax: deb "<full-repository-line>"
Logic: Creates a .list file in /etc/apt/sources.list.d/ containing the repository line.
Examples:
# Google Chrome
deb "[arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main"
# Docker
deb "[arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
Notes:
- The repository line must be quoted (usually with double quotes)
- This directive only adds the repository line; it does not add the GPG key
- You must use the
keydirective separately to add the required GPG key - Repository lines can include options like
[arch=amd64]or[trusted=yes]
key - Add GPG Key
Specifies a GPG key URL to be downloaded and added to /etc/apt/trusted.gpg.d/.
Syntax: key <url-to-key>
Logic: Downloads the key, dearmors it, and saves it to /etc/apt/trusted.gpg.d/<filename>.gpg.
Examples:
# Google Chrome Key
key https://dl.google.com/linux/linux_signing_key.pub
# Docker Key
key https://download.docker.com/linux/ubuntu/gpg
Notes:
- Keys are typically required for custom repositories (
debdirectives) - Keys are not required for PPAs (handled automatically)
- The URL can point to either an armored (
.pub,.asc) or binary key file - Keys must be added before the repository that uses them
Complete Example
Here’s a complete example Aptfile demonstrating all directives:
# This is a sample Aptfile
# Core development tools
apt build-essential
apt curl
apt git
apt vim
apt htop
# Specific version of nano
apt "nano=2.9.3-2"
# PHP from a PPA
ppa ppa:ondrej/php
apt php8.1
apt php8.1-cli
apt php8.1-fpm
# Install Docker
key https://download.docker.com/linux/ubuntu/gpg
deb "[arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
apt docker-ce
apt docker-ce-cli
apt containerd.io
Order of Operations
When apt-bundle install runs, it processes directives in the following order:
- All
keydirectives (add GPG keys) - All
ppadirectives (add PPAs) - All
debdirectives (add repositories) - Run
apt-get update(by default, can be skipped with--no-updateflag) - All
aptdirectives (install packages)
This ensures that repositories and keys are set up before attempting to install packages. The package list update runs by default to ensure fresh package information, but can be skipped using the --no-update flag if your package lists are already up-to-date (e.g., in CI/CD environments).
Best Practices
- Group related items: Keep related packages, repositories, and keys together
- Use comments: Add comments to explain why certain packages or repositories are needed
- Pin versions carefully: Only pin versions when necessary for reproducibility
- Order matters: Place
keydirectives beforedebdirectives that use them - Test your Aptfile: Use
apt-bundle checkbefore runningapt-bundle install
Common Patterns
Development Environment
# Build tools
apt build-essential
apt cmake
apt pkg-config
# Version control
apt git
apt git-lfs
# Editors
apt vim
apt nano
Docker Environment
# Docker repository
key https://download.docker.com/linux/ubuntu/gpg
deb "[arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Docker packages
apt docker-ce
apt docker-ce-cli
apt containerd.io
apt docker-compose-plugin
Language-Specific Setup
# PHP from PPA
ppa ppa:ondrej/php
apt php8.1
apt php8.1-cli
apt php8.1-fpm
apt php8.1-mysql
# Node.js repository
key https://deb.nodesource.com/gpgkey/nodesource.gpg.key
deb "https://deb.nodesource.com/node_18.x $(lsb_release -cs) main"
apt nodejs
Related Documentation
- Usage Guide - How to use apt-bundle commands
- Technical Specification - Internal specification
- Requirements - Internal specification