PO Box 1214 • La Pine • Oregon • 97739 • 541-410-2760

 

M
a
i
n

Home

  • Tech Notes
  • Showcase
  • What We Do
  • Downloads
  • Store
  • IMO
  • Contact Us
  •  
    Building a Debian Package Repository

    Building a Debian Package Repository

    *NOTE* With Debian 9+ rules about repository signing have changed. They may have disabled the use of unsigned repos altogether. I've been signing my repos with a simple Python script for some time now. But apt-get now claims its insecure. I will be updating this article at somepoint, hopefully in the near future. But I will find out the new requirements before I do.

    This is a quick and dirty personal repository for Debian packages. At least for the time being, I won't delve into signing packages, package lists or combined "pool" folders used by larger repositories. I use this procedure as an easy way to distribute packages I find outside of Debian or ones I build myself. This makes it easy to supply packages to all of my devices and provide updates as they become available. wink

    First pick a place and create a directory structure like:

    {base}/dists/{dist}/{repos}/

    {base}: is the "root" folder for your package tree. This needs to be a folder served by a web sever. Other delivery mechanisms are available. But I'm trying to keep this simple. On a default Debian install of Apache this would be "/var/www/htdocs" and you will need "root" access to alter it. If you want to serve anything else out of your web server's document root you should create a subfolder for {base} (like "/var/www/htdocs/debian").

    {dist}: Is the target distribution. This name is specified in your "sources.list" file so can be  whatever you want but typically is the name of the distribution (ie. lenny, wheezy, jessie).

    {repos}: are the individual "collections" (also called "sections") for a specific {dist}. Debian usually uses "main", "contrib" and "non-free" here. Since this is a personal repository I use "unofficial". You can pretty much use whatever you want and as many as you want. These are specified in "sources.list". In this folder you will need to create the architecture specific folders. For a typical 32bit intel repository they would be:

        binary-all
        binary-i386

    "binary-all" is used for packages that will work on all architectures. Interpreted software (perl, php, python, ...) will go here and things like docs or data-only packages, that aren't architecture specific. You need to have a "binary-..." package for your target hardware architecture for this repo to be useful, even if all you have are packages in "binary-all" (see note further down). Examples are: binary-i386 (32bit Intel), binary-amd64 (64bit Intel), binary-armhf (one version of ARM). You need to match the suffix of the package file name, everything between the last "_" and the ".deb" extension.

    After the folders are made create a text file named "Release" in the {dist} folder(s) you created to contain meta information about each {dist}. These files have a very simple syntax, the same as used in their packaging "control" file. Lines start with a field name followed by a colon and a value. Some fields can be multi-line in which case the subsequent lines are indented by one space. If you need a blank line in a multi-line field it should consist of a space followed by a period. Here's a sample:

    Architectures: amd64 i386
    Components: unofficial private
    Origin: JF Possibilities, Inc.
    Version: 8.0.0
    Codename: jessie
    Description:
     This repository contains software packages provided by me for me.
     Should you be here?
     .
     That was a blank line
    

    The "Architectures" line is a space separated list of the architectures you're supporting in your repository. For every "binary-{arch}" folder, other than "all", you should list the {arch} here. Separate them with spaces. The "Components" field is a space separated list of the {repos} folders provided. Note that you will need to provide an {arch} folder for every architecture and component you specify. "Codename" should match {dist}. "Version" is the minimum version of Debian your packages should work with. "Origin" and "Description" are optional and are for the end user to know something about your repository... although I've never seen them shown in the client apps (apt-get, synaptic, ...).

    After the "Release" file(s) are created copy your package (.deb) files into the appropriate folders. For each {dist}/{repos} folder, from the {base} folder run:

    $ dpkg-scanpackages dists/{dist}/{repos}/binary-{arch} /dev/null > dists/{dist}/{repos}/binary-{arch}/Packages
    $ dpkg-scanpackages dists/{dist}/{repos}/binary-all /dev/null >> dists/{dist}/{repos}/binary-{arch}/Packages
    $ gzip dists/{dist}/{repos}/binary-{arch}/Packages

    *NOTE* Don't type the "$". Its there purely for illustrating the shell prompt.

    Now you can add the repository to your "sources.list" file. For illustration I'll use "localhost" as the host name serving the files. Change this to the name of your machine, or IP address if name resolution (DNS, /etc/hosts, ...) isn't setup. Then add something like the following to your "/etc/apt/sources.list" file:

    deb http://localhost/{base} {dist} {repos}

    You'll have to adjust {base} to match your web server setup in conjunction with the actual path. To do that you will need familiarity with the web serving software. As an example if your software is serving "/var/www/htdocs" as the "document root" and you used "/var/www/htdocs/debian" as your {base} folder then you would use "http://localhost/debian".

    After that you can "apt-get update" and "apt-get install" as usual. If something isn't done correctly its likely "apt-get update" will complain and you'll have to fix things.


    Notes:

    1. Apparently the Packages file for the architecture specific folder needs to contain the files from binary-all because the client machine only looks into the binary-{arch} folder for its packages. Later versions of "apt" do have provision for checking "binary-all" seperately if its published in the "Release" file.
    2. There isn't any logic needed on the server to support serving a repository. A stock static webserver will work. All of the logic is handled in the client software (apt-get) or by package submission tools that generate static files like "dpkg-scanpackages".

     


     

    LOCAL apt archive variant:

    1.  make a dir accessible (at least by root):

      sudo mkdir /var/my-local-repo
       
    2. copy all the deb files to this directory.
       
    3. make the directory as a

      sudo dpkg-scanpackages  /var/my-local-repo /dev/null > /var/my-local-repo/Packages
       
    4. add the local repo to sources

      echo "deb file:/var/my-local-repo ./" > /tmp/my-local.list
      sudo mv /tmp/my-local.list /etc/apt/sources.list.d/my-local.list
      sudo apt-get update

     

    Tools to create a mirror / cache of the official debian repository

    apt-cacher
    apt-cacher-ng
    apt-proxy
    apt-mirror
    apt-move