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) orarm64(aarch64).- The repository commands rely on
bash,coreutils,dpkg,dpkg-scanpackages,apt-ftparchive,apt,dpkg-deb,unsquashfs,file,chmod, andln.
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.debbuild/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.