From Source Code to .deb Package: A Tutorial for Linux Package Management
๐ Introduction
Disclaimer: This is not necessarily the optimal or best way to build a .deb package. It may be messy, but it's the workaround I've found and will be demonstrating here.
A .deb file in Linux is a package format developed for the Debian distribution, which has served as the foundation for many popular distributions such as Ubuntu, Linux Mint, and Kali Linux. When building a .deb package, it can typically run on these and other Debian-based distributions, ensuring compatibility across a wide range of systems
In this example we are going to do the following things:
Create a simple cli-app
Build the .deb file
Upload it to GitHub
Publish a release
๐งฐ Prerequisites
๐ Creating the Debian Package Directory Structure
We can read about what to use inside our DEBIAN folder -> Debian-package
As for my example, I'm only using
postinst
andpostrm
.Little fact: control, postinst, postrm have no file extension.
๐ฆdebian-package-base
โฃ ๐DEBIAN
โ โฃ ๐control
โ โฃ ๐postinst
โ โ ๐postrm
โฃ ๐usr
โ โฃ ๐bin
โ โ ## OUR APP RESIDES INSIDE THE BIN FOLDER
โฃ ๐.gitignore
First of all, we have our DEBIAN folder which contains the necessary information to build our package
Remember to give execution permissions to these files
chmod +x ./DEBIAN/postinst
chmod +x ./DEBIAN/postrm
๐ The control file - * REQUIRED
Package: debian-template
Version: 0.0.1
Section: utils
Priority: optional
Architecture: all
Depends: bash
Maintainer: Jonathan Dyallo <contacto@jonathan.com.ar>
Description: A demo application
This one contains information about our package itself
package-name: the package name itself, this is how we are going to launch our app once is finished
version: version of the package
section: utils, system, security, can be a variety of things
priority: is necessary to the system?
architecture: processor architecture, like intelx32, amdx64, etc
dependencies: if we have to install something to run our package, like the module requests for making api-calls on a python script
To read more about the control file you can visit debian-docs
๐ง The postinst file
This section contains information about what we do during the installation process once the package is running. It is important to note that we cannot install something with our package manager while the app is running. For instance, if we run dpkg -i our_app.deb
, and our postinst
script contains a command like dpkg -i another_app
, it will result in an error message stating that the package manager is in use.
Here is where the monkey inside of me started to use a 1% of his power.
To execute the app as any other instead of going to the folder and run the main script etc, we create a symbolik link and clone the repo to that particular place.
So the instalattion itself is a big lie and we are just creating a workaround to execute it from the main file itself.
#!/bin/bash
# Create symbolic link
sudo ln -s /usr/share/debian-package-base/usr/bin/main.sh /usr/bin/debian-package-base
# Get the project in a more monkey-friendly way
cd /usr/share
git clone https://github.com/jd-apprentice/debian-package-base.git
# Give permissions to the application and source the files
chmod -R 777 /usr/share/debian-package-base
# Successfully installed the application, give message to the user
echo "debian-package-base has been installed successfully!"
echo "You can run it by typing 'debian-package-base' in the terminal."
โ The postrm file
The postrm
file is an optional script that runs after the package is removed from the system. It can be used to perform cleanup tasks such as deleting configuration files or stopping running services that were associated with the package.
#!/bin/bash
# We remove everything we can from the user's home directory
sudo rm -rf /usr/bin/debian-package-base
sudo rm -rf /usr/share/debian-package-base
๐ซ Building the Package
For this particular task I've created a util/script to automate the building process of the package itself or new versions
#!/bin/bash # App name for multiples uses app_name="debian-package-base" # Starting message echo "Building latest version of ${app_name}" # Find version of the package and save it in a variable file=$(find . -name 'control') string="Version" while read -r line; do if [[ $line =~ $string ]]; then version=${line:(-3):3} fi done <$file # We locate where the folder is located and move to it folder=$(find $HOME -type d -name "${app_name}" -print | tail -n 1) cd "$folder" # We create a folder for the build and copy the entire file one level above cd .. mkdir -p -- "${version}-${app_name}" copy=$(find $HOME -type d -name "${version}-${app_name}") cp -r $folder/* "$copy" # Move to the copy directory cd "$copy" # We remove git since we don't want it in the final build # Also here remove anything not useful to the final build example images for the readme, markdown files, etc rm -rf .git rm *.md # Move out of the copy directory cd .. # Build latest version of the package dpkg --build "${version}-${app_name}"
To run this script (you can create it inside the root of your app or a
utils
folder)
# Remember to be at the same level of the app
chmod +x ./utils/<script_name>.sh
./utils/<script_name>.sh
With this we should have a
.deb
file ready to be installed!But before going to the install we proceed to uploading everything to github
โ Uploading to Github
We can use my template with the button
Use this template
-
Select a new name and with that we have our new repo, just like we see it above
Upload everything to the repository
๐ฆ Installing the Package
Now if everything is uploaded to the repository and we have the
.deb
fileTo install the package we are going to use
dpkg
Run the following command inside your terminal
sudo dpkg -i ./<version>-<package-name>.deb
๐ง It's Alive!
Here is an example of building, installing and running the app at the same time
Once we know is working we just have to create a release on github or share it with others!
In the future i'm going to expand this example with better practices and how to upload it to PPA and users can download it with just a simple
apt-get install <my-package>
๐ Ending
Let me know if something is messed up and I'll update the guide and also if you have any trouble or have better ideas / suggestions, I'm open to hear.
Contact me at any of my Socials