github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/contrib/mkimage/debootstrap (about) 1 #!/usr/bin/env bash 2 set -e 3 4 rootfsDir="$1" 5 shift 6 7 # we have to do a little fancy footwork to make sure "rootfsDir" becomes the second non-option argument to debootstrap 8 9 before=() 10 while [ $# -gt 0 ] && [[ "$1" == -* ]]; do 11 before+=( "$1" ) 12 shift 13 done 14 15 suite="$1" 16 shift 17 18 # allow for DEBOOTSTRAP=qemu-debootstrap ./mkimage.sh ... 19 : ${DEBOOTSTRAP:=debootstrap} 20 21 ( 22 set -x 23 $DEBOOTSTRAP "${before[@]}" "$suite" "$rootfsDir" "$@" 24 ) 25 26 # now for some Docker-specific tweaks 27 28 # prevent init scripts from running during install/update 29 echo >&2 "+ echo exit 101 > '$rootfsDir/usr/sbin/policy-rc.d'" 30 cat > "$rootfsDir/usr/sbin/policy-rc.d" <<'EOF' 31 #!/bin/sh 32 33 # For most Docker users, "apt-get install" only happens during "docker build", 34 # where starting services doesn't work and often fails in humorous ways. This 35 # prevents those failures by stopping the services from attempting to start. 36 37 exit 101 38 EOF 39 chmod +x "$rootfsDir/usr/sbin/policy-rc.d" 40 41 # prevent upstart scripts from running during install/update 42 ( 43 set -x 44 chroot "$rootfsDir" dpkg-divert --local --rename --add /sbin/initctl 45 cp -a "$rootfsDir/usr/sbin/policy-rc.d" "$rootfsDir/sbin/initctl" 46 sed -i 's/^exit.*/exit 0/' "$rootfsDir/sbin/initctl" 47 ) 48 49 # shrink a little, since apt makes us cache-fat (wheezy: ~157.5MB vs ~120MB) 50 ( set -x; chroot "$rootfsDir" apt-get clean ) 51 52 # this file is one APT creates to make sure we don't "autoremove" our currently 53 # in-use kernel, which doesn't really apply to debootstraps/Docker images that 54 # don't even have kernels installed 55 rm -f "$rootfsDir/etc/apt/apt.conf.d/01autoremove-kernels" 56 57 # Ubuntu 10.04 sucks... :) 58 if strings "$rootfsDir/usr/bin/dpkg" | grep -q unsafe-io; then 59 # force dpkg not to call sync() after package extraction (speeding up installs) 60 echo >&2 "+ echo force-unsafe-io > '$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup'" 61 cat > "$rootfsDir/etc/dpkg/dpkg.cfg.d/docker-apt-speedup" <<-'EOF' 62 # For most Docker users, package installs happen during "docker build", which 63 # doesn't survive power loss and gets restarted clean afterwards anyhow, so 64 # this minor tweak gives us a nice speedup (much nicer on spinning disks, 65 # obviously). 66 67 force-unsafe-io 68 EOF 69 fi 70 71 if [ -d "$rootfsDir/etc/apt/apt.conf.d" ]; then 72 # _keep_ us lean by effectively running "apt-get clean" after every install 73 aptGetClean='"rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true";' 74 echo >&2 "+ cat > '$rootfsDir/etc/apt/apt.conf.d/docker-clean'" 75 cat > "$rootfsDir/etc/apt/apt.conf.d/docker-clean" <<-EOF 76 # Since for most Docker users, package installs happen in "docker build" steps, 77 # they essentially become individual layers due to the way Docker handles 78 # layering, especially using CoW filesystems. What this means for us is that 79 # the caches that APT keeps end up just wasting space in those layers, making 80 # our layers unnecessarily large (especially since we'll normally never use 81 # these caches again and will instead just "docker build" again and make a brand 82 # new image). 83 84 # Ideally, these would just be invoking "apt-get clean", but in our testing, 85 # that ended up being cyclic and we got stuck on APT's lock, so we get this fun 86 # creation that's essentially just "apt-get clean". 87 DPkg::Post-Invoke { ${aptGetClean} }; 88 APT::Update::Post-Invoke { ${aptGetClean} }; 89 90 Dir::Cache::pkgcache ""; 91 Dir::Cache::srcpkgcache ""; 92 93 # Note that we do realize this isn't the ideal way to do this, and are always 94 # open to better suggestions (https://github.com/docker/docker/issues). 95 EOF 96 97 # remove apt-cache translations for fast "apt-get update" 98 echo >&2 "+ echo Acquire::Languages 'none' > '$rootfsDir/etc/apt/apt.conf.d/docker-no-languages'" 99 cat > "$rootfsDir/etc/apt/apt.conf.d/docker-no-languages" <<-'EOF' 100 # In Docker, we don't often need the "Translations" files, so we're just wasting 101 # time and space by downloading them, and this inhibits that. For users that do 102 # need them, it's a simple matter to delete this file and "apt-get update". :) 103 104 Acquire::Languages "none"; 105 EOF 106 107 echo >&2 "+ echo Acquire::GzipIndexes 'true' > '$rootfsDir/etc/apt/apt.conf.d/docker-gzip-indexes'" 108 cat > "$rootfsDir/etc/apt/apt.conf.d/docker-gzip-indexes" <<-'EOF' 109 # Since Docker users using "RUN apt-get update && apt-get install -y ..." in 110 # their Dockerfiles don't go delete the lists files afterwards, we want them to 111 # be as small as possible on-disk, so we explicitly request "gz" versions and 112 # tell Apt to keep them gzipped on-disk. 113 114 # For comparison, an "apt-get update" layer without this on a pristine 115 # "debian:wheezy" base image was "29.88 MB", where with this it was only 116 # "8.273 MB". 117 118 Acquire::GzipIndexes "true"; 119 Acquire::CompressionTypes::Order:: "gz"; 120 EOF 121 fi 122 123 if [ -z "$DONT_TOUCH_SOURCES_LIST" ]; then 124 # tweak sources.list, where appropriate 125 lsbDist= 126 if [ -z "$lsbDist" -a -r "$rootfsDir/etc/os-release" ]; then 127 lsbDist="$(. "$rootfsDir/etc/os-release" && echo "$ID")" 128 fi 129 if [ -z "$lsbDist" -a -r "$rootfsDir/etc/lsb-release" ]; then 130 lsbDist="$(. "$rootfsDir/etc/lsb-release" && echo "$DISTRIB_ID")" 131 fi 132 if [ -z "$lsbDist" -a -r "$rootfsDir/etc/debian_version" ]; then 133 lsbDist='Debian' 134 fi 135 # normalize to lowercase for easier matching 136 lsbDist="$(echo "$lsbDist" | tr '[:upper:]' '[:lower:]')" 137 case "$lsbDist" in 138 debian) 139 # updates and security! 140 if [ "$suite" != 'sid' -a "$suite" != 'unstable' ]; then 141 ( 142 set -x 143 sed -i " 144 p; 145 s/ $suite / ${suite}-updates / 146 " "$rootfsDir/etc/apt/sources.list" 147 echo "deb http://security.debian.org $suite/updates main" >> "$rootfsDir/etc/apt/sources.list" 148 # LTS 149 if [ "$suite" = 'squeeze' -o "$suite" = 'oldstable' ]; then 150 head -1 "$rootfsDir/etc/apt/sources.list" \ 151 | sed "s/ $suite / squeeze-lts /" \ 152 >> "$rootfsDir/etc/apt/sources.list" 153 fi 154 ) 155 fi 156 ;; 157 ubuntu) 158 # add the updates and security repositories 159 ( 160 set -x 161 sed -i " 162 p; 163 s/ $suite / ${suite}-updates /; p; 164 s/ $suite-updates / ${suite}-security / 165 " "$rootfsDir/etc/apt/sources.list" 166 ) 167 ;; 168 tanglu) 169 # add the updates repository 170 if [ "$suite" != 'devel' ]; then 171 ( 172 set -x 173 sed -i " 174 p; 175 s/ $suite / ${suite}-updates / 176 " "$rootfsDir/etc/apt/sources.list" 177 ) 178 fi 179 ;; 180 steamos) 181 # add contrib and non-free if "main" is the only component 182 ( 183 set -x 184 sed -i "s/ $suite main$/ $suite main contrib non-free/" "$rootfsDir/etc/apt/sources.list" 185 ) 186 ;; 187 esac 188 fi 189 190 ( 191 set -x 192 193 # make sure we're fully up-to-date 194 chroot "$rootfsDir" bash -c 'apt-get update && apt-get dist-upgrade -y' 195 196 # delete all the apt list files since they're big and get stale quickly 197 rm -rf "$rootfsDir/var/lib/apt/lists"/* 198 # this forces "apt-get update" in dependent images, which is also good 199 200 mkdir "$rootfsDir/var/lib/apt/lists/partial" # Lucid... "E: Lists directory /var/lib/apt/lists/partial is missing." 201 )