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