Setting Up a Rootless Docker Environment in 2024
A guide to setting up a rootless Docker environment in 2024, providing enhanced security and isolation of containers.
Step 1: Clean Up Pre-existing Docker and Container Packages
Begin by clearing any existing packages that could interfere with your new setup. This includes various Docker and container packages.
# Remove unwanted packages
PACKAGES=(docker.io docker-doc docker-compose podman-docker containerd runc)
for pkg in "${PACKAGES[@]}"; do
sudo apt-get remove -y "$pkg"
done
Step 2: Install Rootless Docker Prerequisites
Update your package list and install the essential components for a rootless Docker setup. This includes the Docker CLI, Docker Compose Plugins, Docker Buildx, as well as other critical packages like uidmap and containerd.io.
# Update system and install necessary packages.
sudo apt-get update -y && sudo apt-get install -y ca-certificates curl gnupg docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin uidmap
Step 3: Secure Package Installation and Repository Setup
Secure your Docker package installation by configuring the Docker keyring and adding Docker's official repository to your Apt sources list. These steps ensure a trusted source for your Docker installation.
# Setting up the Docker keyring for secure package installation.
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Adding Docker's official repository to the Apt sources list.
DEB_ARCH=$(dpkg --print-architecture)
VERSION_CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME")
echo "deb [arch=${DEB_ARCH} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu ${VERSION_CODENAME} stable" \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Step 4: Configure a Non-Root User for Docker
Set up a dedicated non-root user for Docker to reinforce the security of your Docker environment. This step involves user creation and configuration.
# Configuring a non-root user for Docker.
USER_NAME="docker-primary"
if ! id "$USER_NAME" &>/dev/null; then
echo "Creating a non-root user: $USER_NAME"
adduser --disabled-password --gecos "" $USER_NAME
passwd $USER_NAME
else
echo "User $USER_NAME already exists. Continuing without creating..."
fi
Step 5: Prepare the User Environment for Rootless Docker
After logging into the newly created user account, adjust the systemd settings to ensure user processes persist after logout.
# ssh or use machinectl to login as docker-primary
# ssh docker-primary@localhost -p 2222
machinectl shell docker-primary@
# Ensure user processes can persist across logouts
loginctl enable-linger docker-primary
Step 6: Install and Configure Docker Rootless
Utilize the automated dockerd-rootless-setuptool.sh script for installation, and then configure the necessary Docker environment variables.
# Install Docker rootless via dockerd-rootless-setuptool.sh script
dockerd-rootless-setuptool.sh install
# Set Docker environment variables in .bashrc
echo "export PATH=/home/docker-primary/bin:$PATH" >> ~/.bashrc
echo "export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock" >> ~/.bashrc
echo "export XDG_RUNTIME_DIR=/run/usr/$(id -u)" >> ~/.bashrc
# Load new environment variables in current shell
. ~/.bashrc
Step 7: Test Your Rootless Docker Environment
Test your rootless Docker environment by running a simple Docker command. If successful, you should see the Docker version information.
# Check Docker Version
docker --version
Create a demo container to ensure your Docker environment is fully functional.
# Run a Hello World Container
docker run hello-world
Check that the Docker daemon is running with your user ID, not as the root user. This is a crucial aspect of a rootless setup.
# Check running user of the Docker daemon
ps -o user= -o pid= -C dockerd
Review the Docker daemon logs for any errors or warnings that might indicate issues with the rootless setup.
# Check the Docker daemon logs
journalctl --user-unit=docker
By running a nginx container that binds to a port, we can test network isolation and port mapping capabilities.
# Check network isolation via port forwarding
docker run -d -p 8000:80 nginx
curl localhost