This repository has no description
hakobin docs apt-setup.md
5.2 kB
Markdown
at main

APT Repository Setup #

This guide walks you through creating and maintaining a signed Debian/APT repository under the deb/ prefix in your S3-compatible bucket, suitable for Debian, Ubuntu, Linux Mint, and other Debian-based client systems.


Understanding APT Repository Concepts #

If you are new to the Debian ecosystem, the repository structure might look complex. Let's break down the three main variables:

  • Distribution (e.g., stable, testing, bookworm, focal): Represents the target release or release state. You can name these whatever you like (e.g., production, staging).
  • Component (e.g., main, contrib, non-free): A sub-section of the distribution. Typically, main is used for the primary software packages.
  • Architecture (e.g., amd64, arm64, all): The hardware architecture the packages are compiled for. all is used for architecture-independent packages (like Python scripts, configuration files, or themes).

1. Configure Storage #

Hakobin needs credentials and settings to communicate with your S3 bucket. Export these environment variables:

export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export S3_BUCKET_NAME=your-bucket-name
export AWS_REGION=us-east-1

For custom endpoints (like MinIO, Cloudflare R2, or DigitalOcean Spaces):

export S3_ENDPOINT=http://localhost:9000
export S3_USE_PATH_STYLE=true

Set the public base URL that clients will use to download packages:

export HAKOBIN_PUBLIC_URL=https://packages.example.com

2. Initialize the Repository #

Initialize your APT metadata and let Hakobin generate the initial repository signing key:

hakobin deb init \
  --origin "Example Inc" \
  --label "Example Packages" \
  --description "APT repository for Example packages" \
  --distributions stable \
  --components main \
  --architectures amd64,all \
  --key-name "Example Repository Signing Key" \
  --key-email "packages@example.com"

What does this command do? #

  • Generates a private GPG key named signing-key.gpg in your current local directory.
  • Creates deb/apt-repo.json in your bucket to store these configurations.
  • Creates empty package indexes.
  • Signs the repository metadata.
  • Writes deb/pubkey.asc, deb/pubkey.gpg (the public keys), and deb/setup.sh (a client bootstrapping script) to S3.

Important

Save signing-key.gpg in a secure location (e.g., a credential manager or CI secrets). Do not commit it to source control. It is used to sign all future package uploads.


3. Upload Packages #

To upload a .deb package file:

hakobin --signing-key ./signing-key.gpg \
  deb upload ./package.deb \
  --distribution stable \
  --component main

If you are running this in a CI pipeline (such as GitHub Actions or GitLab CI), passing file paths can be cumbersome. Instead, pass the key content directly via an environment variable:

export GPG_PRIVATE_KEY="$(cat signing-key.gpg)"
hakobin deb upload ./package.deb --distribution stable --component main

Forcing Overwrites #

By default, Hakobin will fail if you try to upload a package version that already exists. To overwrite it, use the --force flag:

hakobin --signing-key ./signing-key.gpg deb upload --force ./*.deb

4. Query and Manage Packages #

List Published Packages #

To see what packages are currently published in your repository:

hakobin deb list

You can filter the list by package name, distribution, or component:

hakobin deb list nginx --distribution stable --component main

Remove a Package #

To delete a specific package version and architecture from the repository:

hakobin deb remove nginx --version 1.2.3 --architecture amd64 --force

5. Configure APT Clients #

There are two ways to configure your client machines to download packages from your repository.

Hakobin automatically generates a helper shell script called setup.sh and publishes it to your bucket. Clients can run it directly:

curl -fsSL https://packages.example.com/deb/setup.sh | sudo bash

Note

The setup.sh script detects the client's OS, installs the public GPG key into /etc/apt/keyrings/hakobin.gpg, adds the repository sources list, and runs apt update.

Option B: Manual Client Setup #

If you want to configure clients manually or write Ansible/Chef playbooks, run:

# 1. Create the keyrings folder if it doesn't exist
sudo install -d -m 0755 /etc/apt/keyrings

# 2. Download the binary public GPG key
curl -fsSL https://packages.example.com/deb/pubkey.gpg \
  | sudo tee /etc/apt/keyrings/hakobin.gpg >/dev/null
sudo chmod 0644 /etc/apt/keyrings/hakobin.gpg

# 3. Add the repository sources list pointing to the downloaded keyring
echo "deb [signed-by=/etc/apt/keyrings/hakobin.gpg] https://packages.example.com/deb stable main" \
  | sudo tee /etc/apt/sources.list.d/hakobin.list

# 4. Refresh package indexes
sudo apt update

Once completed, users can install your packages using standard apt commands:

sudo apt install package-name