├── SPONSORS ├── rootfs.tar ├── opkg-install ├── rootfs ├── Dockerfile ├── Makefile └── config ├── opkg.conf ├── Makefile ├── Dockerfile ├── LICENSE ├── README.md └── functions.sh /SPONSORS: -------------------------------------------------------------------------------- 1 | DigitalOcean http://digitalocean.com -------------------------------------------------------------------------------- /rootfs.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nelsonjchen/busybox/master/rootfs.tar -------------------------------------------------------------------------------- /opkg-install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | opkg-cl -f /etc/opkg.conf update 3 | opkg-cl -f /etc/opkg.conf install $@ 4 | rm -rf /var/opkg-lists 5 | -------------------------------------------------------------------------------- /rootfs/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM progrium/rootbuilder 2 | ADD ./config /tmp/buildroot/.config 3 | RUN make oldconfig 4 | RUN make --quiet 5 | -------------------------------------------------------------------------------- /rootfs/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: config 2 | 3 | config: 4 | docker run -it progrium/rootbuilder make nconfig 5 | docker cp `docker ps -lq`:/tmp/buildroot/.config . 6 | docker rm `docker ps -lq` 7 | mv .config config 8 | -------------------------------------------------------------------------------- /opkg.conf: -------------------------------------------------------------------------------- 1 | src/gz base http://downloads.openwrt.org/snapshots/trunk/x86_64/generic/packages/base 2 | src/gz packages http://downloads.openwrt.org/snapshots/trunk/x86_64/generic/packages/packages 3 | dest root / 4 | dest ram /tmp 5 | lists_dir ext /var/opkg-lists 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: rootfs.tar Dockerfile 3 | docker build -t busybox . 4 | 5 | tag: 6 | docker tag busybox progrium/busybox 7 | 8 | rootfs.tar: 9 | cd rootfs && docker build -t busybox-rootfs . 10 | docker run --rm busybox-rootfs cat /tmp/buildroot/output/images/rootfs.tar > rootfs.tar 11 | docker rmi busybox-rootfs -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | MAINTAINER Jeff Lindsay 3 | 4 | ADD ./rootfs.tar / 5 | ADD ./opkg.conf /etc/opkg.conf 6 | ADD ./opkg-install /usr/bin/opkg-install 7 | ADD ./functions.sh /lib/functions.sh 8 | RUN opkg-cl install http://downloads.openwrt.org/snapshots/trunk/x86_64/generic/packages/base/libgcc_4.8-linaro-1_x86_64.ipk 9 | RUN opkg-cl install http://downloads.openwrt.org/snapshots/trunk/x86_64/generic/packages/base/libc_0.9.33.2-1_x86_64.ipk 10 | 11 | CMD ["/bin/sh"] 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Jeff Lindsay 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # busybox 2 | 3 | > **Notice:** *This image will probably soon be deprecated in favor of our even smaller [Alpine Linux based image](https://github.com/gliderlabs/docker-alpine). Alpine is a minimal Linux distro designed with containers in mind, based on Busybox, with a real, modern package system* 4 | 5 | This might not be the smallest Busybox container (4.8MB), but it has [opkg](http://wiki.openwrt.org/doc/techref/opkg), which means you can *very easily* install other [common packages](http://downloads.openwrt.org/snapshots/trunk/x86_64/generic/packages/packages/) while keeping the image size to an absolute minimum. 6 | 7 | The convenience of `apt-get install` but for Busybox! 8 | 9 | ## Using and installing packages 10 | 11 | This image is meant to be used as the base image for Busybox-based containers. It includes glibc, uclibc, and opkg with an easy-to-use wrapper for installing packages from your Dockerfiles: 12 | 13 | FROM progrium/busybox 14 | RUN opkg-install curl bash git 15 | CMD ["/bin/bash"] 16 | 17 | The above Dockerfile grabs the latest package index during build, installs curl, bash, git, all their dependencies, and then deletes the local package index. **The result is a Docker image that's only 10MB.** Not too shabby. 18 | 19 | Compare that to a minimal Ubuntu 12.04 (which comes with curl, bash) after installing git: 300MB. 20 | 21 | ## Customizing buildroot configuration (Advanced) 22 | 23 | If you want more control over how the rootfs is produced by customizing the buildroot config, there is some great tooling and an easy workflow. Delete the `rootfs.tar` file, then: 24 | 25 | $ cd rootfs 26 | $ make config 27 | 28 | This will run an interactive menu inside a Docker container to configure buildroot. The resulting config will be placed at `rootfs/config`. Now go back up and rebuild: 29 | 30 | $ cd .. 31 | $ make build 32 | 33 | This will cause buildroot to run again using [rootbuilder](https://github.com/progrium/rootbuilder) and your config. Building will likely take a while. The result will not only be a new `rootfs.tar`, but a new local Docker image tagged `busybox`. 34 | 35 | ## Sponsor 36 | 37 | This project was made possible thanks to [DigitalOcean](http://digitalocean.com). 38 | 39 | ## License 40 | 41 | BSD 42 | -------------------------------------------------------------------------------- /functions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (C) 2006-2013 OpenWrt.org 3 | # Copyright (C) 2006 Fokus Fraunhofer 4 | # Copyright (C) 2010 Vertical Communications 5 | debug () { 6 | ${DEBUG:-:} "$@" 7 | } 8 | # newline 9 | N=" 10 | " 11 | _C=0 12 | NO_EXPORT=1 13 | LOAD_STATE=1 14 | LIST_SEP=" " 15 | append() { 16 | local var="$1" 17 | local value="$2" 18 | local sep="${3:- }" 19 | eval "export ${NO_EXPORT:+-n} -- \"$var=\${$var:+\${$var}\${value:+\$sep}}\$value\"" 20 | } 21 | list_contains() { 22 | local var="$1" 23 | local str="$2" 24 | local val 25 | eval "val=\" \${$var} \"" 26 | [ "${val%% $str *}" != "$val" ] 27 | } 28 | config_load() { 29 | [ -n "$IPKG_INSTROOT" ] && return 0 30 | uci_load "$@" 31 | } 32 | reset_cb() { 33 | config_cb() { return 0; } 34 | option_cb() { return 0; } 35 | list_cb() { return 0; } 36 | } 37 | reset_cb 38 | package() { 39 | return 0 40 | } 41 | config () { 42 | local cfgtype="$1" 43 | local name="$2" 44 | export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=$(($CONFIG_NUM_SECTIONS + 1)) 45 | name="${name:-cfg$CONFIG_NUM_SECTIONS}" 46 | append CONFIG_SECTIONS "$name" 47 | [ -n "$NO_CALLBACK" ] || config_cb "$cfgtype" "$name" 48 | export ${NO_EXPORT:+-n} CONFIG_SECTION="$name" 49 | export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_TYPE=$cfgtype" 50 | } 51 | option () { 52 | local varname="$1"; shift 53 | local value="$*" 54 | export ${NO_EXPORT:+-n} "CONFIG_${CONFIG_SECTION}_${varname}=$value" 55 | [ -n "$NO_CALLBACK" ] || option_cb "$varname" "$*" 56 | } 57 | list() { 58 | local varname="$1"; shift 59 | local value="$*" 60 | local len 61 | config_get len "$CONFIG_SECTION" "${varname}_LENGTH" 0 62 | [ $len = 0 ] && append CONFIG_LIST_STATE "${CONFIG_SECTION}_${varname}" 63 | len=$(($len + 1)) 64 | config_set "$CONFIG_SECTION" "${varname}_ITEM$len" "$value" 65 | config_set "$CONFIG_SECTION" "${varname}_LENGTH" "$len" 66 | append "CONFIG_${CONFIG_SECTION}_${varname}" "$value" "$LIST_SEP" 67 | list_cb "$varname" "$*" 68 | } 69 | config_unset() { 70 | config_set "$1" "$2" "" 71 | } 72 | # config_get