install-rootless-docker.sh (8498B)
1 #!/bin/sh 2 set -e 3 # Docker CE for Linux installation script (Rootless mode) 4 # 5 # See https://docs.docker.com/go/rootless/ for the 6 # installation steps. 7 # 8 # This script is meant for quick & easy install via: 9 # $ curl -fsSL https://get.docker.com/rootless -o get-docker.sh 10 # $ sh get-docker.sh 11 # 12 # NOTE: Make sure to verify the contents of the script 13 # you downloaded matches the contents of install.sh 14 # located at https://github.com/docker/docker-install 15 # before executing. 16 # 17 # Git commit from https://github.com/docker/docker-install when 18 # the script was uploaded (Should only be modified by upload job): 19 SCRIPT_COMMIT_SHA=c2de081 20 21 # This script should be run with an unprivileged user and install/setup Docker under $HOME/bin/. 22 23 # The channel to install from: 24 # * nightly 25 # * test 26 # * stable 27 DEFAULT_CHANNEL_VALUE="stable" 28 if [ -z "$CHANNEL" ]; then 29 CHANNEL=$DEFAULT_CHANNEL_VALUE 30 fi 31 # The latest release is currently hard-coded. 32 STABLE_LATEST="24.0.1" 33 TEST_LATEST="24.0.1" 34 STATIC_RELEASE_URL= 35 STATIC_RELEASE_ROOTLESS_URL= 36 case "$CHANNEL" in 37 "stable") 38 echo "# Installing stable version ${STABLE_LATEST}" 39 STATIC_RELEASE_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-${STABLE_LATEST}.tgz" 40 STATIC_RELEASE_ROOTLESS_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-rootless-extras-${STABLE_LATEST}.tgz" 41 ;; 42 "test") 43 echo "# Installing test version ${TEST_LATEST}" 44 STATIC_RELEASE_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-${TEST_LATEST}.tgz" 45 STATIC_RELEASE_ROOTLESS_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-rootless-extras-${TEST_LATEST}.tgz" 46 ;; 47 "nightly") 48 echo "# Installing nightly" 49 STATIC_RELEASE_URL="https://master.dockerproject.org/linux/$(uname -m)/docker.tgz" 50 STATIC_RELEASE_ROOTLESS_URL="https://master.dockerproject.org/linux/$(uname -m)/docker-rootless-extras.tgz" 51 ;; 52 *) 53 >&2 echo "Aborting because of unknown CHANNEL \"$CHANNEL\". Set \$CHANNEL to either \"stable\", \"test\", or \"nightly\"."; exit 1 54 ;; 55 esac 56 57 init_vars() { 58 BIN="${DOCKER_BIN:-$HOME/bin}" 59 60 DAEMON=dockerd 61 SYSTEMD= 62 if systemctl --user daemon-reload >/dev/null 2>&1; then 63 SYSTEMD=1 64 fi 65 } 66 67 checks() { 68 # OS verification: Linux only, point osx/win to helpful locations 69 case "$(uname)" in 70 Linux) 71 ;; 72 *) 73 >&2 echo "Rootless Docker cannot be installed on $(uname)"; exit 1 74 ;; 75 esac 76 77 # User verification: deny running as root (unless forced?) 78 if [ "$(id -u)" = "0" ] && [ -z "$FORCE_ROOTLESS_INSTALL" ]; then 79 >&2 echo "Refusing to install rootless Docker as the root user"; exit 1 80 fi 81 82 # HOME verification 83 if [ ! -d "$HOME" ]; then 84 >&2 echo "Aborting because HOME directory $HOME does not exist"; exit 1 85 fi 86 87 if [ -d "$BIN" ]; then 88 if [ ! -w "$BIN" ]; then 89 >&2 echo "Aborting because $BIN is not writable"; exit 1 90 fi 91 else 92 if [ ! -w "$HOME" ]; then 93 >&2 echo "Aborting because HOME (\"$HOME\") is not writable"; exit 1 94 fi 95 fi 96 97 # Existing rootful docker verification 98 if [ -w /var/run/docker.sock ] && [ -z "$FORCE_ROOTLESS_INSTALL" ]; then 99 >&2 echo "Aborting because rootful Docker is running and accessible. Set FORCE_ROOTLESS_INSTALL=1 to ignore."; exit 1 100 fi 101 102 # Validate XDG_RUNTIME_DIR 103 if [ ! -w "$XDG_RUNTIME_DIR" ]; then 104 if [ -n "$SYSTEMD" ]; then 105 >&2 echo "Aborting because systemd was detected but XDG_RUNTIME_DIR (\"$XDG_RUNTIME_DIR\") does not exist or is not writable" 106 >&2 echo "Hint: this could happen if you changed users with 'su' or 'sudo'. To work around this:" 107 >&2 echo "- try again by first running with root privileges 'loginctl enable-linger <user>' where <user> is the unprivileged user and export XDG_RUNTIME_DIR to the value of RuntimePath as shown by 'loginctl show-user <user>'" 108 >&2 echo "- or simply log back in as the desired unprivileged user (ssh works for remote machines)" 109 exit 1 110 fi 111 fi 112 113 # Already installed verification (unless force?). Only having docker cli binary previously shouldn't fail the build. 114 if [ -x "$BIN/$DAEMON" ]; then 115 # If rootless installation is detected print out the modified PATH and DOCKER_HOST that needs to be set. 116 echo "# Existing rootless Docker detected at $BIN/$DAEMON" 117 echo 118 echo "# To reinstall or upgrade rootless Docker, run the following commands and then rerun the installation script:" 119 echo "systemctl --user stop docker" 120 echo "rm -f $BIN/$DAEMON" 121 echo 122 echo "# Alternatively, install the docker-ce-rootless-extras RPM/deb package for ease of package management (requires root)." 123 echo "# See https://docs.docker.com/go/rootless/ for details." 124 exit 0 125 fi 126 127 INSTRUCTIONS= 128 129 # uidmap dependency check 130 if ! command -v newuidmap >/dev/null 2>&1; then 131 if command -v apt-get >/dev/null 2>&1; then 132 INSTRUCTIONS="apt-get install -y uidmap" 133 elif command -v dnf >/dev/null 2>&1; then 134 INSTRUCTIONS="dnf install -y shadow-utils" 135 elif command -v yum >/dev/null 2>&1; then 136 INSTRUCTIONS="curl -o /etc/yum.repos.d/vbatts-shadow-utils-newxidmap-epel-7.repo https://copr.fedorainfracloud.org/coprs/vbatts/shadow-utils-newxidmap/repo/epel-7/vbatts-shadow-utils-newxidmap-epel-7.repo 137 yum install -y shadow-utils46-newxidmap" 138 else 139 echo "newuidmap binary not found. Please install with a package manager." 140 exit 1 141 fi 142 fi 143 144 # iptables dependency check 145 if [ -z "$SKIP_IPTABLES" ] && ! command -v iptables >/dev/null 2>&1 && [ ! -f /sbin/iptables ] && [ ! -f /usr/sbin/iptables ]; then 146 if command -v apt-get >/dev/null 2>&1; then 147 INSTRUCTIONS="${INSTRUCTIONS} 148 apt-get install -y iptables" 149 elif command -v dnf >/dev/null 2>&1; then 150 INSTRUCTIONS="${INSTRUCTIONS} 151 dnf install -y iptables" 152 else 153 echo "iptables binary not found. Please install with a package manager." 154 exit 1 155 fi 156 fi 157 158 # ip_tables module dependency check 159 if [ -z "$SKIP_IPTABLES" ] && ! lsmod | grep ip_tables >/dev/null 2>&1 && ! grep -q ip_tables "/lib/modules/$(uname -r)/modules.builtin"; then 160 INSTRUCTIONS="${INSTRUCTIONS} 161 modprobe ip_tables" 162 fi 163 164 # debian requires setting unprivileged_userns_clone 165 if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then 166 if [ "1" != "$(cat /proc/sys/kernel/unprivileged_userns_clone)" ]; then 167 INSTRUCTIONS="${INSTRUCTIONS} 168 cat <<EOT > /etc/sysctl.d/50-rootless.conf 169 kernel.unprivileged_userns_clone = 1 170 EOT 171 sysctl --system" 172 fi 173 fi 174 175 # centos requires setting max_user_namespaces 176 if [ -f /proc/sys/user/max_user_namespaces ]; then 177 if [ "0" = "$(cat /proc/sys/user/max_user_namespaces)" ]; then 178 INSTRUCTIONS="${INSTRUCTIONS} 179 cat <<EOT > /etc/sysctl.d/51-rootless.conf 180 user.max_user_namespaces = 28633 181 EOT 182 sysctl --system" 183 fi 184 fi 185 186 if [ -n "$INSTRUCTIONS" ]; then 187 echo "# Missing system requirements. Please run following commands to 188 # install the requirements and run this installer again. 189 # Alternatively iptables checks can be disabled with SKIP_IPTABLES=1" 190 191 echo 192 echo "cat <<EOF | sudo sh -x" 193 echo "$INSTRUCTIONS" 194 echo "EOF" 195 echo 196 exit 1 197 fi 198 199 # validate subuid/subgid files for current user 200 if ! grep "^$(id -un):\|^$(id -u):" /etc/subuid >/dev/null 2>&1; then 201 >&2 echo "Could not find records for the current user $(id -un) from /etc/subuid . Please make sure valid subuid range is set there. 202 For example: 203 echo \"$(id -un):100000:65536\" >> /etc/subuid" 204 exit 1 205 fi 206 if ! grep "^$(id -un):\|^$(id -u):" /etc/subgid >/dev/null 2>&1; then 207 >&2 echo "Could not find records for the current user $(id -un) from /etc/subgid . Please make sure valid subuid range is set there. 208 For example: 209 echo \"$(id -un):100000:65536\" >> /etc/subgid" 210 exit 1 211 fi 212 } 213 214 exec_setuptool() { 215 if [ -n "$FORCE_ROOTLESS_INSTALL" ]; then 216 set -- "$@" --force 217 fi 218 if [ -n "$SKIP_IPTABLES" ]; then 219 set -- "$@" --skip-iptables 220 fi 221 ( 222 set -x 223 PATH="$BIN:$PATH" "$BIN/dockerd-rootless-setuptool.sh" install "$@" 224 ) 225 } 226 227 do_install() { 228 echo "# Executing docker rootless install script, commit: $SCRIPT_COMMIT_SHA" 229 230 init_vars 231 checks 232 233 tmp=$(mktemp -d) 234 trap 'rm -rf "$tmp"' EXIT INT TERM 235 # Download tarballs docker-* and docker-rootless-extras=* 236 ( 237 cd "$tmp" 238 curl -L -o docker.tgz "$STATIC_RELEASE_URL" 239 curl -L -o rootless.tgz "$STATIC_RELEASE_ROOTLESS_URL" 240 ) 241 # Extract under $HOME/bin/ 242 ( 243 mkdir -p "$BIN" 244 cd "$BIN" 245 tar zxf "$tmp/docker.tgz" --strip-components=1 246 tar zxf "$tmp/rootless.tgz" --strip-components=1 247 ) 248 249 exec_setuptool "$@" 250 } 251 252 do_install "$@"