Not working on alpine docker (BusyBox)
Hi, Thank you for a great tool. I do have an issue trying to run the latest version on an Alpine Docker, for some reason, when trying to run commands, it thinks that it is running BusyBox commands. It is very easy to reproduce
docker run --rm -it --net=host python:alpine sh
apk add postgresql-dev
pip install pgcli
pgcli --auto-vertical-output postgresql://[email protected]:5432/postgres
Then, running a command gives this output
Server: PostgreSQL 15.10
Version: 4.3.0
Home: http://pgcli.com
[email protected]:postgres> select * from information_schema.sql_features
BusyBox v1.37.0 (2025-05-26 20:04:45 UTC) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
or: busybox --install [-s] [DIR]
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.
Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, arch, arp, arping, ash, awk, base64, basename, bbconfig, bc, beep, blkdiscard, blkid, blockdev, brctl,
bunzip2, bzcat, bzip2, cal, cat, chattr, chgrp, chmod, chown, chpasswd, chroot, chvt, cksum, clear, cmp, comm, cp, cpio, crond, crontab, cryptpw, cut, date, dc,
dd, deallocvt, delgroup, deluser, depmod, df, diff, dirname, dmesg, dnsdomainname, dos2unix, du, dumpkmap, echo, egrep, eject, env, ether-wake, expand, expr,
factor, fallocate, false, fatattr, fbset, fbsplash, fdflush, fdisk, fgrep, find, findfs, flock, fold, free, fsck, fstrim, fsync, fuser, getopt, getty, grep,
groups, gunzip, gzip, halt, hd, head, hexdump, hostid, hostname, hwclock, id, ifconfig, ifdown, ifenslave, ifup, init, inotifyd, insmod, install, ionice, iostat,
ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, ipneigh, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, link, linux32, linux64, ln,
loadfont, loadkmap, logger, login, logread, losetup, ls, lsattr, lsmod, lsof, lsusb, lzcat, lzma, lzop, lzopcat, makemime, md5sum, mdev, mesg, microcom, mkdir,
mkdosfs, mkfifo, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mv, nameif, nanddump, nandwrite, nbd-client, nc,
netstat, nice, nl, nmeter, nohup, nologin, nproc, nsenter, nslookup, ntpd, od, openvt, partprobe, passwd, paste, pgrep, pidof, ping, ping6, pipe_progress,
pivot_root, pkill, pmap, poweroff, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readahead, readlink, realpath, reboot, reformime,
remove-shell, renice, reset, resize, rev, rfkill, rm, rmdir, rmmod, route, run-parts, sed, sendmail, seq, setconsole, setfont, setkeycodes, setlogcons, setpriv,
setserial, setsid, sh, sha1sum, sha256sum, sha3sum, sha512sum, showkey, shred, shuf, slattach, sleep, sort, split, stat, strings, stty, su, sum, swapoff, swapon,
switch_root, sync, sysctl, syslogd, tac, tail, tar, tee, test, time, timeout, top, touch, tr, traceroute, traceroute6, tree, true, truncate, tty, ttysize, tunctl,
udhcpc, udhcpc6, umount, uname, unexpand, uniq, unix2dos, unlink, unlzma, unlzop, unshare, unxz, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, vlock,
volname, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xxd, xzcat, yes, zcat, zcip
Time: 0.204s
[email protected]:postgres>
Doing the same with Debian based docker works
docker run --rm -it --net=host python:slim sh
apt update
apt-get install -y libpq-dev
pip install pgcli
pgcli --auto-vertical-output postgresql://[email protected]:5432/postgres
Any idea what can be the reason?
This looks odd. Off the top of my head, I can't tell how pgcli gets entangled with busybox. This needs some digging.
Thanks for looking into it, I tried to dig a bit but could not find the root cause 😓
The bug is in the click Python package (a dependency of pgcli). It calls less in some way that is not compatible with Busybox (amongst other things). See https://github.com/pallets/click/issues/2943 for the bug report and https://github.com/pallets/click/pull/2944 for the fix in click. The fixing commit is included in 8.3.1, which is yet to be released on PyPI (see this discussion for further details about the release).
So this could be fixed once we force (or at least allow) the use of click 8.3.1 in pgcli... but pgcli currently restricts to version <8.1.8 (see this commit). That constraint should be lifted first.
Note: I could not reproduce the bug in what is currently the python:alpine Docker image (which does not seem to use Busybox). However, the bug can be reproduced with the python:3.10-alpine3.22 image (and possibly other versions).