252 строки
8.1 KiB
Bash
Executable File
252 строки
8.1 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e
|
|
# Docker CE for Linux installation script (Rootless mode)
|
|
#
|
|
# See https://docs.docker.com/go/rootless/ for the
|
|
# installation steps.
|
|
#
|
|
# This script is meant for quick & easy install via:
|
|
# $ curl -fsSL https://get.docker.com/rootless -o get-docker.sh
|
|
# $ sh get-docker.sh
|
|
#
|
|
# NOTE: Make sure to verify the contents of the script
|
|
# you downloaded matches the contents of install.sh
|
|
# located at https://github.com/docker/docker-install
|
|
# before executing.
|
|
#
|
|
# Git commit from https://github.com/docker/docker-install when
|
|
# the script was uploaded (Should only be modified by upload job):
|
|
SCRIPT_COMMIT_SHA=UNKNOWN
|
|
|
|
# This script should be run with an unprivileged user and install/setup Docker under $HOME/bin/.
|
|
|
|
# latest version available in the stable channel.
|
|
STABLE_LATEST="27.3.1"
|
|
|
|
# latest version available in the test channel.
|
|
TEST_LATEST="27.3.1"
|
|
|
|
# The channel to install from:
|
|
# * test
|
|
# * stable
|
|
DEFAULT_CHANNEL_VALUE="stable"
|
|
if [ -z "$CHANNEL" ]; then
|
|
CHANNEL=$DEFAULT_CHANNEL_VALUE
|
|
fi
|
|
|
|
STATIC_RELEASE_URL=
|
|
STATIC_RELEASE_ROOTLESS_URL=
|
|
case "$CHANNEL" in
|
|
"stable")
|
|
echo "# Installing stable version ${STABLE_LATEST}"
|
|
STATIC_RELEASE_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-${STABLE_LATEST}.tgz"
|
|
STATIC_RELEASE_ROOTLESS_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-rootless-extras-${STABLE_LATEST}.tgz"
|
|
;;
|
|
"test")
|
|
echo "# Installing test version ${TEST_LATEST}"
|
|
STATIC_RELEASE_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-${TEST_LATEST}.tgz"
|
|
STATIC_RELEASE_ROOTLESS_URL="https://download.docker.com/linux/static/$CHANNEL/$(uname -m)/docker-rootless-extras-${TEST_LATEST}.tgz"
|
|
;;
|
|
*)
|
|
>&2 echo "Aborting because of unknown CHANNEL \"$CHANNEL\". Set \$CHANNEL to either \"stable\" or \"test\"."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
init_vars() {
|
|
BIN="${DOCKER_BIN:-$HOME/bin}"
|
|
|
|
DAEMON=dockerd
|
|
SYSTEMD=
|
|
if systemctl --user daemon-reload >/dev/null 2>&1; then
|
|
SYSTEMD=1
|
|
fi
|
|
}
|
|
|
|
checks() {
|
|
# OS verification: Linux only, point osx/win to helpful locations
|
|
case "$(uname)" in
|
|
Linux)
|
|
;;
|
|
*)
|
|
>&2 echo "Rootless Docker cannot be installed on $(uname)"; exit 1
|
|
;;
|
|
esac
|
|
|
|
# User verification: deny running as root (unless forced?)
|
|
if [ "$(id -u)" = "0" ] && [ -z "$FORCE_ROOTLESS_INSTALL" ]; then
|
|
>&2 echo "Refusing to install rootless Docker as the root user"; exit 1
|
|
fi
|
|
|
|
# HOME verification
|
|
if [ ! -d "$HOME" ]; then
|
|
>&2 echo "Aborting because HOME directory $HOME does not exist"; exit 1
|
|
fi
|
|
|
|
if [ -d "$BIN" ]; then
|
|
if [ ! -w "$BIN" ]; then
|
|
>&2 echo "Aborting because $BIN is not writable"; exit 1
|
|
fi
|
|
else
|
|
if [ ! -w "$HOME" ]; then
|
|
>&2 echo "Aborting because HOME (\"$HOME\") is not writable"; exit 1
|
|
fi
|
|
fi
|
|
|
|
# Existing rootful docker verification
|
|
if [ -w /var/run/docker.sock ] && [ -z "$FORCE_ROOTLESS_INSTALL" ]; then
|
|
>&2 echo "Aborting because rootful Docker is running and accessible. Set FORCE_ROOTLESS_INSTALL=1 to ignore."; exit 1
|
|
fi
|
|
|
|
# Validate XDG_RUNTIME_DIR
|
|
if [ ! -w "$XDG_RUNTIME_DIR" ]; then
|
|
if [ -n "$SYSTEMD" ]; then
|
|
>&2 echo "Aborting because systemd was detected but XDG_RUNTIME_DIR (\"$XDG_RUNTIME_DIR\") does not exist or is not writable"
|
|
>&2 echo "Hint: this could happen if you changed users with 'su' or 'sudo'. To work around this:"
|
|
>&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>'"
|
|
>&2 echo "- or simply log back in as the desired unprivileged user (ssh works for remote machines)"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Already installed verification (unless force?). Only having docker cli binary previously shouldn't fail the build.
|
|
if [ -x "$BIN/$DAEMON" ]; then
|
|
# If rootless installation is detected print out the modified PATH and DOCKER_HOST that needs to be set.
|
|
echo "# Existing rootless Docker detected at $BIN/$DAEMON"
|
|
echo
|
|
echo "# To reinstall or upgrade rootless Docker, run the following commands and then rerun the installation script:"
|
|
echo "systemctl --user stop docker"
|
|
echo "rm -f $BIN/$DAEMON"
|
|
echo
|
|
echo "# Alternatively, install the docker-ce-rootless-extras RPM/deb package for ease of package management (requires root)."
|
|
echo "# See https://docs.docker.com/go/rootless/ for details."
|
|
exit 0
|
|
fi
|
|
|
|
INSTRUCTIONS=
|
|
|
|
# uidmap dependency check
|
|
if ! command -v newuidmap >/dev/null 2>&1; then
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
INSTRUCTIONS="apt-get -y install uidmap"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
INSTRUCTIONS="dnf -y install shadow-utils"
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
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
|
|
yum -y install shadow-utils46-newxidmap"
|
|
else
|
|
echo "newuidmap binary not found. Please install with a package manager."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# iptables dependency check
|
|
if [ -z "$SKIP_IPTABLES" ] && ! command -v iptables >/dev/null 2>&1 && [ ! -f /sbin/iptables ] && [ ! -f /usr/sbin/iptables ]; then
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
INSTRUCTIONS="${INSTRUCTIONS}
|
|
apt-get -y install iptables"
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
INSTRUCTIONS="${INSTRUCTIONS}
|
|
dnf -y install iptables"
|
|
else
|
|
echo "iptables binary not found. Please install with a package manager."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# ip_tables module dependency check
|
|
if [ -z "$SKIP_IPTABLES" ] && ! lsmod | grep ip_tables >/dev/null 2>&1 && ! grep -q ip_tables "/lib/modules/$(uname -r)/modules.builtin"; then
|
|
INSTRUCTIONS="${INSTRUCTIONS}
|
|
modprobe ip_tables"
|
|
fi
|
|
|
|
# debian requires setting unprivileged_userns_clone
|
|
if [ -f /proc/sys/kernel/unprivileged_userns_clone ]; then
|
|
if [ "1" != "$(cat /proc/sys/kernel/unprivileged_userns_clone)" ]; then
|
|
INSTRUCTIONS="${INSTRUCTIONS}
|
|
cat <<EOT > /etc/sysctl.d/50-rootless.conf
|
|
kernel.unprivileged_userns_clone = 1
|
|
EOT
|
|
sysctl --system"
|
|
fi
|
|
fi
|
|
|
|
# centos requires setting max_user_namespaces
|
|
if [ -f /proc/sys/user/max_user_namespaces ]; then
|
|
if [ "0" = "$(cat /proc/sys/user/max_user_namespaces)" ]; then
|
|
INSTRUCTIONS="${INSTRUCTIONS}
|
|
cat <<EOT > /etc/sysctl.d/51-rootless.conf
|
|
user.max_user_namespaces = 28633
|
|
EOT
|
|
sysctl --system"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$INSTRUCTIONS" ]; then
|
|
echo "# Missing system requirements. Please run following commands to
|
|
# install the requirements and run this installer again.
|
|
# Alternatively iptables checks can be disabled with SKIP_IPTABLES=1"
|
|
|
|
echo
|
|
echo "cat <<EOF | sudo sh -x"
|
|
echo "$INSTRUCTIONS"
|
|
echo "EOF"
|
|
echo
|
|
exit 1
|
|
fi
|
|
|
|
# validate subuid/subgid files for current user
|
|
if ! grep "^$(id -un):\|^$(id -u):" /etc/subuid >/dev/null 2>&1; then
|
|
>&2 echo "Could not find records for the current user $(id -un) from /etc/subuid . Please make sure valid subuid range is set there.
|
|
For example:
|
|
echo \"$(id -un):100000:65536\" >> /etc/subuid"
|
|
exit 1
|
|
fi
|
|
if ! grep "^$(id -un):\|^$(id -u):" /etc/subgid >/dev/null 2>&1; then
|
|
>&2 echo "Could not find records for the current user $(id -un) from /etc/subgid . Please make sure valid subuid range is set there.
|
|
For example:
|
|
echo \"$(id -un):100000:65536\" >> /etc/subgid"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
exec_setuptool() {
|
|
if [ -n "$FORCE_ROOTLESS_INSTALL" ]; then
|
|
set -- "$@" --force
|
|
fi
|
|
if [ -n "$SKIP_IPTABLES" ]; then
|
|
set -- "$@" --skip-iptables
|
|
fi
|
|
(
|
|
set -x
|
|
PATH="$BIN:$PATH" "$BIN/dockerd-rootless-setuptool.sh" install "$@"
|
|
)
|
|
}
|
|
|
|
do_install() {
|
|
echo "# Executing docker rootless install script, commit: $SCRIPT_COMMIT_SHA"
|
|
|
|
init_vars
|
|
checks
|
|
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT INT TERM
|
|
# Download tarballs docker-* and docker-rootless-extras=*
|
|
(
|
|
cd "$tmp"
|
|
curl -L -o docker.tgz "$STATIC_RELEASE_URL"
|
|
curl -L -o rootless.tgz "$STATIC_RELEASE_ROOTLESS_URL"
|
|
)
|
|
# Extract under $HOME/bin/
|
|
(
|
|
mkdir -p "$BIN"
|
|
cd "$BIN"
|
|
tar zxf "$tmp/docker.tgz" --strip-components=1
|
|
tar zxf "$tmp/rootless.tgz" --strip-components=1
|
|
)
|
|
|
|
exec_setuptool "$@"
|
|
}
|
|
|
|
do_install "$@"
|