diff --git a/contrib/mkimage.sh b/contrib/mkimage.sh index db4815c204..dc82145acf 100755 --- a/contrib/mkimage.sh +++ b/contrib/mkimage.sh @@ -6,7 +6,7 @@ mkimg="$(basename "$0")" usage() { echo >&2 "usage: $mkimg [-d dir] [-t tag] script [script-args]" echo >&2 " ie: $mkimg -t someuser/debian debootstrap --variant=minbase jessie" - echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal trusty" + echo >&2 " $mkimg -t someuser/ubuntu debootstrap --include=ubuntu-minimal --components main,universe trusty" echo >&2 " $mkimg -t someuser/busybox busybox-static" echo >&2 " $mkimg -t someuser/centos:5 rinse --distribution centos-5" exit 1 diff --git a/contrib/mkimage/debootstrap b/contrib/mkimage/debootstrap index 4747a84d31..d5aeae2b99 100755 --- a/contrib/mkimage/debootstrap +++ b/contrib/mkimage/debootstrap @@ -23,9 +23,14 @@ shift # now for some Docker-specific tweaks # prevent init scripts from running during install/update -echo >&2 "+ cat > '$rootfsDir/usr/sbin/policy-rc.d'" +echo >&2 "+ echo exit 101 > '$rootfsDir/usr/sbin/policy-rc.d'" cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF' #!/bin/sh + +# For most Docker users, "apt-get install" only happens during "docker build", +# where starting services doesn't work and often fails in humorous ways. This +# prevents those failures by stopping the services from attempting to start. + exit 101 EOF chmod +x "$rootfsDir/usr/sbin/policy-rc.d" @@ -34,17 +39,25 @@ chmod +x "$rootfsDir/usr/sbin/policy-rc.d" ( set -x chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl - ln -sf /bin/true "$rootfsDir/sbin/initctl" + cp -a "$rootfsDir/usr/sbin/policy-rc.d" "$rootfsDir/sbin/initctl" + sed -i 's/^exit.*/exit 0/' "$rootfsDir/sbin/initctl" ) -# shrink the image, since apt makes us fat (wheezy: ~157.5MB vs ~120MB) +# shrink a little, since apt makes us cache-fat (wheezy: ~157.5MB vs ~120MB) ( set -x; chroot "$rootfsDir" apt-get clean ) # Ubuntu 10.04 sucks... :) if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then # force dpkg not to call sync() after package extraction (speeding up installs) echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'" - echo 'force-unsafe-io' > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" + cat > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF' + # For most Docker users, package installs happen during "docker build", which + # doesn't survive power loss and gets restarted clean afterwards anyhow, so + # this minor tweak gives us a nice speedup (much nicer on spinning disks, + # obviously). + + force-unsafe-io + EOF fi if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then @@ -52,16 +65,36 @@ if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";' echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'" cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF + # Since for most Docker users, package installs happen in "docker build" steps, + # they essentially become individual layers due to the way Docker handles + # layering, especially using CoW filesystems. What this means for us is that + # the caches that APT keeps end up just wasting space in those layers, making + # our layers unnecessarily large (especially since we'll normally never use + # these caches again and will instead just "docker build" again and make a brand + # new image). + + # Ideally, these would just be invoking "apt-get clean", but in our testing, + # that ended up being cyclic and we got stuck on APT's lock, so we get this fun + # creation that's essentially just "apt-get clean". DPkg::Post-Invoke { ${aptGetClean} }; APT::Update::Post-Invoke { ${aptGetClean} }; Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache ""; + + # Note that we do realize this isn't the ideal way to do this, and are always + # open to better suggestions (https://github.com/dotcloud/docker/issues). EOF # remove apt-cache translations for fast "apt-get update" - echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" - echo 'Acquire::Languages "none";' > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" + echo >&2 "+ echo Acquire::Languages 'none' > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" + cat > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF' + # In Docker, we don't often need the "Translations" files, so we're just wasting + # time and space by downloading them, and this inhibits that. For users that do + # need them, it's a simple matter to delete this file and "apt-get update". :) + + Acquire::Languages "none"; + EOF fi if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then @@ -76,39 +109,53 @@ if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then lsbDist='Debian' fi + # normalize to lowercase for easier matching + lsbDist="$(echo "$lsbDist" | tr '[:upper:]' '[:lower:]')" case "$lsbDist" in - debian|Debian) + debian) # updates and security! if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list" + # LTS + if [ "$suite" = 'squeeze' ]; then + head -1 "$rootfsDir/etc/apt/sources.list" \ + | sed "s/ $suite / ${suite}-lts /" \ + >> "$rootfsDir/etc/apt/sources.list" + fi ) fi ;; - ubuntu|Ubuntu) - # add the universe, updates, and security repositories + ubuntu) + # add the updates and security repositories ( set -x sed -i " - s/ $suite main$/ $suite main universe/; p; - s/ $suite main/ ${suite}-updates main/; p; - s/ $suite-updates main/ ${suite}-security main/ + p; + s/ $suite / ${suite}-updates /; p; + s/ $suite-updates / ${suite}-security / " "$rootfsDir/etc/apt/sources.list" ) ;; - tanglu|Tanglu) + tanglu) # add the updates repository if [ "$suite" != 'devel' ]; then ( set -x - sed -i "p; s/ $suite main$/ ${suite}-updates main/" "$rootfsDir/etc/apt/sources.list" + sed -i " + p; + s/ $suite / ${suite}-updates / + " "$rootfsDir/etc/apt/sources.list" ) fi ;; - steamos|SteamOS) - # add contrib and non-free + steamos) + # add contrib and non-free if "main" is the only component ( set -x sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list"