dynapt/README.md

9.3 KiB

dynapt

Dynamic APT repository.

Warning

dynapt is experimental. The configuration format and package compatibility can change, and the project does not yet provide a stable CLI/GUI or APT transport.

dynapt runs a local APT repository server. When APT requests repository metadata, dynapt downloads the configured packages, generates Debian repository metadata, and serves the resulting files over HTTP.

It supports direct links to DEB packages and AppImages. AppImages are extracted and wrapped into DEB packages using their desktop entry and icon. Packages from GitHub releases can also be downloaded and filtered by file name.

dynapt is not a package manager. It makes packages available to APT, so upgrades, searches, installation, and removal can continue using apt, aptitude, Synaptic, or other APT frontends.

Requirements

  • Linux with APT.
  • amd64 (x86_64) or arm64 (aarch64).
  • The repository commands rely on bash, coreutils, dpkg, dpkg-scanpackages, apt-ftparchive, apt, dpkg-deb, unsquashfs, file, chmod, and ln.

apt-ftparchive is provided by apt-utils. Install it first on minimal systems where apt did not pull it in:

sudo apt update
sudo apt install apt-utils

The APT source below uses trusted=yes because dynapt currently does not sign repository metadata. Only use this setup on a trusted local machine and do not expose the dynapt port to the network.

Installation

Download and install the current development release automatically:

wget https://git.kaki87.net/KaKi87/dynapt/releases/download/0.0.0-dev.9b8fa75/dynapt-"$(dpkg --print-architecture)".deb
sudo apt install ./dynapt-"$(dpkg --print-architecture)".deb

Or download the package manually for:

The packages are also listed on the release page.

Configuration

Create /opt/dynapt/config.json:

sudo nano /opt/dynapt/config.json

Start with an empty application list:

{
    "port": 3000,
    "concurrency": null,
    "apps": []
}

Change port if another service already uses port 3000. concurrency limits how many applications are downloaded and packaged at the same time. Use 1 on slower connections or lower-powered devices, or null to let all applications run concurrently.

Add the local repository to APT. Replace 3000 if you changed the port in config.json:

echo "deb [trusted=yes] http://127.0.0.1:3000/ /" | sudo tee /etc/apt/sources.list.d/dynapt.list

Start the server. It must run as a user that can write to /opt/dynapt:

sudo nohup dynapt >/dev/null 2>&1 &

Make it start at boot. Run this as root:

crontab -l | { cat; echo "@reboot dynapt"; } | crontab -

The first time APT reads the repository, dynapt downloads and packages the configured applications. It can take longer than a normal APT mirror update.

Application configuration

Each item in apps configures one upstream application.

A direct DEB link uses url:

{
    "name": "Example",
    "url": "https://example.com/download/package.deb"
}

A direct AppImage link must set appimage to true. If the command name should be available in PATH, set an object with bin:

{
    "name": "Example",
    "url": "https://example.com/download/package.AppImage",
    "appimage": {
        "bin": "example"
    }
}

A GitHub release uses github instead of url:

{
    "name": "Example",
    "github": {
        "repo": "example/example",
        "filter": "*.deb",
        "prerelease": true
    }
}

If a direct URL returns JSON instead of a package, use a jq expression to extract the package URL:

{
    "name": "Example",
    "url": "https://example.com/download/latest.json",
    "jq": ".downloads[0].url",
    "appimage": true
}

Configuration fields

Field Required Description
name Yes Display name used by dynapt.
url One of url or github Direct HTTPS download URL for a DEB or AppImage.
github.repo With github GitHub repository in owner/name format.
github.filter No Glob expression used to select release assets.
github.prerelease No Inspect prereleases when true.
appimage No Use true for an AppImage, or an object containing bin.
appimage.bin No Command name to link from /usr/bin.
jq No Applied to JSON returned by url; requires url.
id No Internal UUID used for cache metadata. dynapt creates it automatically.

If APT updates many GitHub-hosted applications, GitHub API rate limits can interrupt metadata requests. Add a personal access token to the root configuration:

{
    "githubAccessToken": "github_pat_example_placeholder"
}

Complete example

The following example contains direct-download configurations that have been useful in the current experimental stage:

{
    "port": 3000,
    "concurrency": null,
    "apps": [
        {
            "name": "Discord",
            "url": "https://discord.com/api/download?platform=linux&format=deb"
        },
        {
            "name": "Free Download Manager",
            "url": "https://files2.freedownloadmanager.org/6/latest/freedownloadmanager.deb"
        },
        {
            "name": "kDrive",
            "url": "https://www.infomaniak.com/drive/latest",
            "jq": ".[\"linux-amd64\"].downloadurl",
            "appimage": true
        },
        {
            "name": "Kiro",
            "url": "https://prod.download.desktop.kiro.dev/stable/metadata-linux-x64-deb-stable.json",
            "jq": ".releases[].updateTo.url | select(endswith(\".deb\"))"
        },
        {
            "name": "LM Studio",
            "url": "https://lmstudio.ai/download/latest/linux/x64",
            "appimage": true
        }
    ]
}

For an arm64 kDrive client, replace linux-amd64 in its jq filter with linux-arm64. The LM Studio example shown here uses the current x64 download URL.

Using the repository

After dynapt is configured, refresh APT and install packages using their Debian package names:

sudo apt update
apt search example
sudo apt install example-package

For AppImages, dynapt derives the package name, version, description, architecture, and icon from the desktop entry inside the AppImage. Direct DEBs retain the metadata supplied by their upstream.

The server generates repository metadata when APT requests /Packages or /Release. Downloads are cached and ETag/GitHub release metadata is reused on later requests.

Commands

dynapt also includes commands for debugging and maintenance.

Fetch and package applications without first installing an APT package:

sudo dynapt update

Show configured applications and compare their available versions with the versions installed through APT:

sudo dynapt list

Remove downloaded files, generated package data, and cache data:

sudo dynapt clean

Refresh only the dynapt APT source:

sudo apt update \
    -o Dir::Etc::sourcelist="sources.list.d/dynapt.list" \
    -o Dir::Etc::sourceparts="-" \
    -o APT::Get::List-Cleanup="0"

Troubleshooting

Logs

Read /opt/dynapt/dynapt.log and include the relevant lines together with the APT output when asking for help.

Download failures

Try sudo dynapt update to see fetch, download, AppImage extraction, or package generation errors without involving APT. A missing unsquashfs, file, apt-ftparchive, or disk space can prevent packaging from completing.

Package appears changed by upstream

Run dynapt clean, then refresh from APT:

sudo dynapt clean
sudo apt update

GitHub rate limits

Requests to GitHub release metadata can be anonymous or authenticated with githubAccessToken. Use a token with the minimum public repository read access and do not include the token in a publicly shared configuration file.

Port is already in use

Either stop the process using port 3000 or change port in /opt/dynapt/config.json and update the APT source to use the new port.

Development

dynapt is written in JavaScript and runs on Deno. Install Deno and the Debian packaging and AppImage tools listed in the requirements.

Run the CLI from a checkout:

./dynapt --version
./dynapt list
./dynapt update
./dynapt serve

When run from source, dynapt uses config.json and writes cache and package data beneath the checkout rather than /opt/dynapt.

Build both Debian packages:

./build.sh

Deno compiles main.js for x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu, and dpkg-deb creates:

  • build/dynapt-amd64.deb
  • build/dynapt-arm64.deb

There is not a separate automated test command at the moment. Changes should be checked against the affected CLI commands, server routes, and the packaging steps they touch.

Acknowledgements

This README incorporates the experimental setup tutorial originally shared as a Gist by KaKi87. It is now maintained with the code in this repository, as requested in issue #1.