How to Create Debian Packages for a Python Application: A Step-by-Step Guide

Spread the love


Greetings, fellow system admins and tech enthusiasts! In the expansive landscape of software development, packaging remains a crucial yet often mystifying aspect. Today, we embark on a journey into the depths of Debian packaging – an indispensable skill for Linux developers. Whether you’re a seasoned coder or just starting your foray into software packaging, this guide aims to demystify the process and equip you with the knowledge to confidently create Debian packages.

Before we delve into the intricacies of Debian packaging, let’s take a moment to revisit our previous discussion on RPM packages. If you missed it, catch up on our exploration of RPM packaging here. Building upon the foundational concepts covered in that post, we now shift our focus to Debian – a cornerstone in the realm of package management.

So, grab your preferred coding beverage, settle into your coding sanctuary, and let’s unlock the secrets of creating Debian packages together!

    Introduction to Debian Packaging

    Debian packages are the building blocks of Debian-based distributions. They make installing, upgrading, and removing software much easier. If you’re involved in software development or system administration, learning how to create .deb packages will save you a lot of time and headaches.

    In this guide, we’ll walk you through the process of creating .deb packages from scratch, packaging a sample Python server application, and running it as a systemd service.

    Prerequisites and Environment Setup

    Before we dive into creating Debian packages, let’s set up our development environment with the necessary tools and libraries.

    Install Required Packages

    First, open your terminal and install the following packages:

    sudo apt update
    sudo apt install build-essential devscripts dh-make python3-venv
    

    Here’s a brief overview of what these packages do:

    • build-essential: Essential tools for compiling software.
    • devscripts: A collection of scripts to assist Debian package maintainers.
    • dh-make: Helps create the Debian package structure.
    • python3-venv: Provides support for creating virtual environments in Python.

    Setting Up a Working Directory

    Let’s create a working directory for our project:

    mkdir ~/deb-package-tutorial
    cd ~/deb-package-tutorial
    

    Creating a Sample Python Server Application

    We’ll create a simple Python HTTP server application that we will package into a .deb file and run as a systemd service.

    Writing the Application

    Create a new directory for the application source code:

    mkdir hello-python-server
    cd hello-python-server
    

    Now, create a file named server.py and add the following code:

    import http.server
    import socketserver
    
    PORT = 8000
    
    Handler = http.server.SimpleHTTPRequestHandler
    
    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        print("Serving at port", PORT)
        httpd.serve_forever()
    

    This simple server will serve files from the current directory on port 8000.

    Structuring the Package Directory

    Debian packages require a specific directory structure. Let’s create the necessary directories:

    mkdir -p hello-python-server-1.0/usr/local/bin
    mkdir -p hello-python-server-1.0/lib/systemd/system
    

    Move the Python script to the appropriate directory:

    cp server.py hello-python-server-1.0/usr/local/bin/
    

    Detailed Directory Structure

    The directory structure of a Debian package typically looks like this:

    hello-python-server-1.0/
    ├── DEBIAN
    │   ├── control
    │   ├── postinst
    │   ├── preinst (optional)
    │   ├── postrm (optional)
    │   └── prerm (optional)
    ├── usr
    │   └── local
    │       └── bin
    │           └── server.py
    └── lib
        └── systemd
            └── system
                └── hello-python-server.service
    

    DEBIAN Directory

    The DEBIAN directory is crucial. It contains all the package control information:

    • control: Contains metadata about the package.
    • postinst: Script executed after the package is installed.
    • preinst (optional): Script executed before the package is unpacked.
    • postrm (optional): Script executed after the package is removed.
    • prerm (optional): Script executed before the package is removed.

    The control file is mandatory, while the scripts are optional but useful for handling complex installation and removal procedures.

    usr Directory

    This is where the program’s executable files and other static files are stored, following the standard Unix directory structure. In our example:

    • usr/local/bin: Contains the Python script server.py.

    lib Directory

    The lib directory is used for systemd service files and other system-related configurations:

    • lib/systemd/system: Contains the hello-python-server.service file, which defines how the Python server should be started and managed by systemd.

    Writing the Control File

    The control file contains metadata about the package. It’s crucial for the package manager to understand the package’s details.

    Creating the DEBIAN Directory

    Create a directory named DEBIAN inside your package directory:

    mkdir hello-python-server-1.0/DEBIAN
    

    Writing the Control File

    Create a file named control inside the DEBIAN directory and add the following content:

    Package: hello-python-server
    Version: 1.0
    Section: web
    Priority: optional
    Architecture: all
    Depends: python3
    Maintainer: Codefy Top <test@codefy.top>
    Description: A simple Python HTTP server
     A longer description of your package.
    

    Control File Parameters

    • Package: The name of the package.
    • Version: The version of the package.
    • Section: The section under which the package will appear (e.g., web, utils, etc.).
    • Priority: The importance of the package (optional, standard, required).
    • Architecture: The target architecture (e.g., all for platform-independent packages).
    • Depends: A list of dependencies required to run the package (e.g., python3).
    • Maintainer: The maintainer’s name and email.
    • Description: A brief description of the package, followed by an extended description.

    Creating a Post-Install Script

    To ensure that the service starts after installation, create a post-install script:

    nano hello-python-server-1.0/DEBIAN/postinst
    

    Add the following content to the postinst file:

    #!/bin/bash
    systemctl daemon-reload
    systemctl enable hello-python-server.service
    systemctl start hello-python-server.service
    

    Make the script executable:

    chmod 755 hello-python-server-1.0/DEBIAN/postinst
    

    Optional Control Files

    • preinst: Executed before the package is unpacked.
    • postrm: Executed after the package is removed.
    • prerm: Executed before the package is removed.

    Creating a Systemd Service

    To run the application as a systemd service, create a service file:

    nano hello-python-server-1.0/lib/systemd/system/hello-python-server.service
    

    Add the following content to the hello-python-server.service file:

    [Unit]
    Description=Hello Python Server Service
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/python3 /usr/local/bin/server.py
    Restart=always
    User=nobody
    Group=nogroup
    
    [Install]
    WantedBy=multi-user.target
    
    • Description: A brief description of the service.
    • After: Specifies the order in which services are started.
    • ExecStart: The command to start the service.
    • Restart: Specifies the restart policy for the service.
    • User and Group: Specifies the user and group under which the service runs.
    • WantedBy: Specifies the target under which the service should be started.

    Building the Package

    Use the dpkg-deb tool to build the package:

    dpkg-deb --build hello-python-server-1.0
    

    This command will create a file named hello-python-server-1.0.deb in your current directory.

    Checking the Package

    To check the package for errors, use the lintian tool:

    sudo apt install lintian
    lintian hello-python-server-1.0.deb
    

    lintian will analyze the package and report any issues. Fixing these issues will help ensure your package adheres to Debian packaging standards.

    Testing the Package

    Install the newly created package to test it:

    sudo dpkg -i hello-python-server-1.0.deb
    

    Check the status of the service:

    systemctl status hello-python-server.service
    

    You should see that the service is running. To test the application, open a web browser and navigate to http://localhost:8000. You should see a directory listing of the current directory.

    Logging and Debugging

    To view the logs generated by the service, use:

    journalctl -u hello-python-server.service
    

    This will show the output of the Python server, which can be helpful for debugging.

    To remove the package, use:

    sudo dpkg -r hello-python-server
    

    If the package removal fails due to dependencies, you can force the removal with:

    sudo dpkg -r --force-all hello-python-server
    

    Conclusion

    Creating Debian packages is a valuable skill for software developers and system administrators. This guide provided a step-by-step process to create a .deb package from scratch, covering the environment setup, application creation, directory structuring, control file writing, systemd service creation, package building, and testing.

    By following this guide, you can package your own software and ensure it runs as a systemd service, simplifying software deployment and management on Debian-based systems. Happy packaging!