Created
October 2, 2024 17:39
-
-
Save BuddhiLW/ba0a36a29fcace65cef605785cf13522 to your computer and use it in GitHub Desktop.
Install docker compose that doesn't 'sudo'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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=dd4d114 | |
# This script should be run with an unprivileged user and install/setup Docker under $HOME/bin/. | |
# The latest release is currently hard-coded. | |
STABLE_LATEST="27.0.3" | |
# The channel to install from: | |
# * test | |
# * stable | |
DEFAULT_CHANNEL_VALUE="stable" | |
if [ -z "$CHANNEL" ]; then | |
CHANNEL=$DEFAULT_CHANNEL_VALUE | |
fi | |
# The test release is currently hard-coded. | |
TEST_LATEST="27.0.3" | |
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 install -y uidmap" | |
elif command -v dnf >/dev/null 2>&1; then | |
INSTRUCTIONS="dnf install -y 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 install -y 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 install -y iptables" | |
elif command -v dnf >/dev/null 2>&1; then | |
INSTRUCTIONS="${INSTRUCTIONS} | |
dnf install -y 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 "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment