Skip to content

Debian Package OTA Update

This tutorial walks you through building and updating an IoT application packaged as a Debian package on a fleet of IoT devices, using the SocketXP OTA update feature end-to-end.

Before you start, make sure you have downloaded and installed the SocketXP agent on your IoT devices and completed the Getting Started guide.

Sample App

We'll use a simple C program to demonstrate the OTA update workflow, and package the compiled binary as a Debian package. The app prints "Hello, OTA update!" every 10 minutes and runs as a Linux systemd service on the device.

Note

We're using C for this example, but the app can be written in any language, such as Java, C++, Go, Python or JavaScript.

/*
 * To build: gcc myapp.c -o myapp
 * To run: ./myapp
 * Output: "Hello, OTA update!"
 */

#include <stdio.h>
#include <unistd.h>

int main() {
    while (1) {
        printf("Hello, OTA update!\n");
        fflush(stdout); // Ensure immediate output
        sleep(600); // in seconds
    }
    return 0;
}

The C program, build script, and Debian package build scripts used in this tutorial are available in our official GitHub repository.

Build the App Binary

Clone the repository:

$ git clone https://github.com/ampaslabs/ota-update-build-artifacts

For this example, we'll use the debian_pkg folder:

~/$ cd ota-update-build-artifacts/debian_pkg
~/ota-update-build-artifacts/debian_pkg$ ls
make_artifact.sh  myapp/  update.sh
~/ota-update-build-artifacts/debian_pkg$ ls myapp/
debian/  makefile  myapp.c
~/ota-update-build-artifacts/debian_pkg$ ls myapp/debian/
control  myapp.service  postinst  postrm  prerm

The debian_pkg folder contains:

  1. A myapp folder containing the app source (myapp.c) and a makefile to compile the app and build a Debian package. The debian subfolder has the scripts required to install and configure the app binary as a Debian package on the target device.
  2. An update.sh shell script — the workflow script that runs on the target device and updates the myapp Debian package.
  3. A make_artifact.sh shell script — packages the Debian package and workflow script into a tar.gz artifact.

Create a New Version of the App

Edit myapp.c to print "Hello, OTA update! Version 1.0.0" — we'll call this version 1.0.0 of the app.

/*
 * To build: gcc myapp.c -o myapp
 * To run: ./myapp
 * Output: "Hello, OTA update!"
 */

#include <stdio.h>
#include <unistd.h>

int main() {
    while (1) {
        printf("Hello, OTA update! Version 1.0.0\n");
        fflush(stdout); // Ensure immediate output
        sleep(600); // in seconds
    }
    return 0;
}

Build the app and package it as a Debian package using make all:

$ cd myapp
$ make all
++ Building myapp
gcc myapp.c -o myapp
++ Building Debian package
rm -rf debian_build
mkdir -p debian_build/myapp_1.0.0
mkdir -p debian_build/myapp_1.0.0/usr/bin
cp myapp debian_build/myapp_1.0.0/usr/bin
mkdir -p debian_build/myapp_1.0.0/etc/systemd/system
cp debian/myapp.service debian_build/myapp_1.0.0/etc/systemd/system
mkdir -p debian_build/myapp_1.0.0/DEBIAN
cp debian/postinst debian_build/myapp_1.0.0/DEBIAN
cp debian/prerm debian_build/myapp_1.0.0/DEBIAN
cp debian/postrm debian_build/myapp_1.0.0/DEBIAN
cp debian/control debian_build/myapp_1.0.0/DEBIAN
dpkg-deb --build --root-owner-group debian_build/myapp_1.0.0
dpkg-deb: building package 'myapp' in 'debian_build/myapp_1.0.0.deb'.

Now that you've built the app binary and the Debian package, create a tar.gz style artifact using them.

Why a tar.gz archive?

SocketXP OTA update expects the artifact to be uploaded as a tar.gz archive file containing the Debian package and the workflow script update.sh. When the artifact is downloaded to the target device, the SocketXP agent unzips and extracts the tar.gz file contents into the /tmp directory, then starts executing the update.sh workflow script contained in the myapp_1.0.0 folder.

Go back to the parent directory and run make_artifact.sh:

~/ota-update-build-artifacts/debian_pkg/myapp$ cd ..
~/ota-update-build-artifacts/debian_pkg$ ls
make_artifact.sh  myapp  update.sh
~/ota-update-build-artifacts/debian_pkg$ sh make_artifact.sh
myapp_1.0.0/
myapp_1.0.0/myapp_1.0.0.deb
myapp_1.0.0/update.sh
~/ota-update-build-artifacts/debian_pkg$ ls
make_artifact.sh  myapp  myapp_1.0.0.tar.gz  update.sh

Verify the contents of the tar.gz file:

$ tar -tf myapp_1.0.0.tar.gz
myapp_1.0.0/
myapp_1.0.0/myapp_1.0.0.deb
myapp_1.0.0/update.sh

Workflow Script - update.sh

The OTA update workflow script contains all the instructions required to update the myapp service running on the IoT devices.

#!/bin/bash

#================================================
# MyApp Update Workflow Script
#================================================

# backup the existing app
mv /usr/bin/myapp /usr/bin/myapp.bkup

# update the myapp package
sudo dpkg -i myapp_*.deb

# verify the app is working fine
service_name="myapp"
if systemctl --quiet is-active "$service_name"; then
  echo "$service_name is running."
  # update success
  # clean up the backup and exit
  rm -f /usr/bin/myapp.bkup
else
  echo "$service_name is not running."
  # update failed
  # restore from the backup
  mv /usr/bin/myapp.bkup /usr/bin/myapp
  # start the previous working version
  systemctl start myapp
fi

What the script does:

  • Creates a backup of the myapp binary already running on the device.
  • Installs the Debian package containing the new version of the app using dpkg -i, which:
    • Runs the package's prerm/postrm scripts, which stop the myapp service.
    • Copies the new version of myapp to the /usr/bin directory.
    • Runs the package's postinst script, which starts the myapp service and kicks off the new version of the app binary.
  • Verifies the service is running fine. If the app fails to run properly after the update, the script restores the previous working version from the backup and starts the app service.
  • If the app runs fine after the update, it deletes the backup files and exits.

Learn more about writing your own workflow script in How to create an OTA Update Workflow Script.

Upload the Artifact

Log in to your SocketXP account and go to the OTA Update page. In the Artifacts table, click Upload new artifact.

SocketXP OTA Update IoT app binary on remote devices

Browse and select the myapp_1.0.0.tar.gz file you just built. Specify the artifact version, 1.0.0 in this example. Click Upload to upload the artifact to the cloud registry. You'll see a message saying "File uploaded successfully".

Deploy the Artifact

SocketXP OTA Update upload an IoT app binary to SocketXP cloud artifact registry

From the Artifacts table, select the artifact you just uploaded.

Note

If you don't see your artifact yet, click Refresh to reload the table data.

Click the + icon next to the artifact to create a new deployment.

SocketXP OTA Update - deploy an IoT app binary on a fleet of remote iot devices

Give the deployment a name, for example, deploy-version-1.0.0-to-test-devices. Specify the target device ID, device group, or tag to deploy the artifact on.

Note

You can deploy the artifact on a single device ID, device group, or device tag. To deploy on more than one group or tag, repeat the "Create New Deployment" process for each.

Click Create Deployment. Go to the Deployments tab and click Refresh.

SocketXP OTA Update - View the summary of OTA updates deployed

Select the deployment to see its progress. Click More Info < > to monitor the progress on each target device in the group or tag. Click Refresh to view the progress.

SocketXP OTA Update - View the progress of OTA updates deployed on each IoT device

You can check the stdout and stderr logs generated by the update process by clicking the view log buttons.

Verify the Update

Log in to one of the devices to check if the myapp deployment was successful:

$ systemctl status myapp
 myapp.service - myapp service
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2025-02-25 00:25:47 UTC; 2 seconds ago
   Main PID: 486462 (myapp)
      Tasks: 1 (limit: 3301)
     Memory: 152.0K
        CPU: 291ms
     CGroup: /system.slice/myapp.service
             └─486462 /usr/bin/myapp

Feb 25 00:25:47 ubuntu myapp[486462]: Hello, OTA update! Version 1.0.0

You can also view the app logs using journalctl:

$ journalctl -u myapp -n 10
Feb 24 02:00:52 ubuntu myapp[486462]: Hello, OTA update!
Feb 25 00:25:47 ubuntu myapp[486462]: Hello, OTA update! Version 1.0.0

You have successfully updated a Debian package app on remote IoT devices using SocketXP OTA update.

Next Steps

Now that you've learned how to publish a Debian package as an OTA update, check out the other artifact types: