---
description: Run the Docker daemon as a non-root user (Rootless mode)
keywords: security, namespaces, rootless
title: Run the Docker daemon as a non-root user (Rootless mode)
---
Rootless mode allows running the Docker daemon and containers as a non-root
user to mitigate potential vulnerabilities in the daemon and
the container runtime.
Rootless mode does not require root privileges even during the installation of
the Docker daemon, as long as the [prerequisites](#prerequisites) are met.
## How it works
Rootless mode executes the Docker daemon and containers inside a user namespace.
This is very similar to [`userns-remap` mode](userns-remap.md), except that
with `userns-remap` mode, the daemon itself is running with root privileges,
whereas in rootless mode, both the daemon and the container are running without
root privileges.
Rootless mode does not use binaries with `SETUID` bits or file capabilities,
except `newuidmap` and `newgidmap`, which are needed to allow multiple
UIDs/GIDs to be used in the user namespace.
## Prerequisites
- You must install `newuidmap` and `newgidmap` on the host. These commands
are provided by the `uidmap` package on most distros.
- `/etc/subuid` and `/etc/subgid` should contain at least 65,536 subordinate
UIDs/GIDs for the user. In the following example, the user `testuser` has
65,536 subordinate UIDs/GIDs (231072-296607).
```console
$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536
```
### Distribution-specific hint
> Note: We recommend that you use the Ubuntu kernel.
- Install `dbus-user-session` package if not installed. Run `sudo apt-get install -y dbus-user-session` and relogin.
- `overlay2` storage driver is enabled by default
([Ubuntu-specific kernel patch](https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/commit/fs/overlayfs?id=3b7da90f28fe1ed4b79ef2d994c81efbc58f1144)).
- Known to work on Ubuntu 18.04, 20.04, and 22.04.
- Install `dbus-user-session` package if not installed. Run `sudo apt-get install -y dbus-user-session` and relogin.
- For Debian 10, add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or
`/etc/sysctl.d`) and run `sudo sysctl --system`. This step is not required on Debian 11.
- Installing `fuse-overlayfs` is recommended. Run `sudo apt-get install -y fuse-overlayfs`.
Using `overlay2` storage driver with Debian-specific modprobe option `sudo modprobe overlay permit_mounts_in_userns=1` is also possible,
however, highly discouraged due to [instability](https://github.com/moby/moby/issues/42302).
- Rootless docker requires version of `slirp4netns` greater than `v0.4.0` (when `vpnkit` is not installed).
Check you have this with
```console
$ slirp4netns --version
```
If you do not have this download and install with `sudo apt-get install -y slirp4netns` or download the latest [release](https://github.com/rootless-containers/slirp4netns/releases).
- Installing `fuse-overlayfs` is recommended. Run `sudo pacman -S fuse-overlayfs`.
- Add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or
`/etc/sysctl.d`) and run `sudo sysctl --system`
- Installing `fuse-overlayfs` is recommended. Run `sudo zypper install -y fuse-overlayfs`.
- `sudo modprobe ip_tables iptable_mangle iptable_nat iptable_filter` is required.
This might be required on other distros as well depending on the configuration.
- Known to work on openSUSE 15 and SLES 15.
- Installing `fuse-overlayfs` is recommended. Run `sudo dnf install -y fuse-overlayfs`.
- You might need `sudo dnf install -y iptables`.
- Known to work on CentOS 8, RHEL 8, and Fedora 34.
- Add `user.max_user_namespaces=28633` to `/etc/sysctl.conf` (or
`/etc/sysctl.d`) and run `sudo sysctl --system`.
- `systemctl --user` does not work by default.
Run `dockerd-rootless.sh` directly without systemd.
## Known limitations
- Only the following storage drivers are supported:
- `overlay2` (only if running with kernel 5.11 or later, or Ubuntu-flavored kernel)
- `fuse-overlayfs` (only if running with kernel 4.18 or later, and `fuse-overlayfs` is installed)
- `btrfs` (only if running with kernel 4.18 or later, or `~/.local/share/docker` is mounted with `user_subvol_rm_allowed` mount option)
- `vfs`
- Cgroup is supported only when running with cgroup v2 and systemd. See [Limiting resources](#limiting-resources).
- Following features are not supported:
- AppArmor
- Checkpoint
- Overlay network
- Exposing SCTP ports
- To use the `ping` command, see [Routing ping packets](#routing-ping-packets).
- To expose privileged TCP/UDP ports (< 1024), see [Exposing privileged ports](#exposing-privileged-ports).
- `IPAddress` shown in `docker inspect` is namespaced inside RootlessKit's network namespace.
This means the IP address is not reachable from the host without `nsenter`-ing into the network namespace.
- Host network (`docker run --net=host`) is also namespaced inside RootlessKit.
- NFS mounts as the docker "data-root" is not supported. This limitation is not specific to rootless mode.
## Install
> **Note**
>
> If the system-wide Docker daemon is already running, consider disabling it:
> `$ sudo systemctl disable --now docker.service docker.socket`
If you installed Docker 20.10 or later with [RPM/DEB packages](/engine/install), you should have `dockerd-rootless-setuptool.sh` in `/usr/bin`.
Run `dockerd-rootless-setuptool.sh install` as a non-root user to set up the daemon:
```console
$ dockerd-rootless-setuptool.sh install
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`
[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock
```
If `dockerd-rootless-setuptool.sh` is not present, you may need to install the `docker-ce-rootless-extras` package manually, e.g.,
```console
$ sudo apt-get install -y docker-ce-rootless-extras
```
If you do not have permission to run package managers like `apt-get` and `dnf`,
consider using the installation script available at [https://get.docker.com/rootless](https://get.docker.com/rootless){: target="_blank" rel="noopener" class="_" }.
Since static packages are not available for `s390x`, hence it is not supported for `s390x`.
```console
$ curl -fsSL https://get.docker.com/rootless | sh
...
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`
[INFO] Make sure the following environment variables are set (or add them to ~/.bashrc):
export PATH=/home/testuser/bin:$PATH
export DOCKER_HOST=unix:///run/user/1000/docker.sock
```
The binaries will be installed at `~/bin`.
See [Troubleshooting](#troubleshooting) if you faced an error.
## Uninstall
To remove the systemd service of the Docker daemon, run `dockerd-rootless-setuptool.sh uninstall`:
```console
$ dockerd-rootless-setuptool.sh uninstall
+ systemctl --user stop docker.service
+ systemctl --user disable docker.service
Removed /home/testuser/.config/systemd/user/default.target.wants/docker.service.
[INFO] Uninstalled docker.service
[INFO] This uninstallation tool does NOT remove Docker binaries and data.
[INFO] To remove data, run: `/usr/bin/rootlesskit rm -rf /home/testuser/.local/share/docker`
```
Unset environment variables PATH and DOCKER_HOST if you have added them to `~/.bashrc`.
To remove the data directory, run `rootlesskit rm -rf ~/.local/share/docker`.
To remove the binaries, remove `docker-ce-rootless-extras` package if you installed Docker with package managers.
If you installed Docker with https://get.docker.com/rootless ([Install without packages](#install)),
remove the binary files under `~/bin`:
```console
$ cd ~/bin
$ rm -f containerd containerd-shim containerd-shim-runc-v2 ctr docker docker-init docker-proxy dockerd dockerd-rootless-setuptool.sh dockerd-rootless.sh rootlesskit rootlesskit-docker-proxy runc vpnkit
```
## Usage
### Daemon
The systemd unit file is installed as `~/.config/systemd/user/docker.service`.
Use `systemctl --user` to manage the lifecycle of the daemon:
```console
$ systemctl --user start docker
```
To launch the daemon on system startup, enable the systemd service and lingering:
```console
$ systemctl --user enable docker
$ sudo loginctl enable-linger $(whoami)
```
Starting Rootless Docker as a systemd-wide service (`/etc/systemd/system/docker.service`)
is not supported, even with the `User=` directive.
To run the daemon directly without systemd, you need to run `dockerd-rootless.sh` instead of `dockerd`.
The following environment variables must be set:
- `$HOME`: the home directory
- `$XDG_RUNTIME_DIR`: an ephemeral directory that is only accessible by the expected user, e,g, `~/.docker/run`.
The directory should be removed on every host shutdown.
The directory can be on tmpfs, however, should not be under `/tmp`.
Locating this directory under `/tmp` might be vulnerable to TOCTOU attack.
Remarks about directory paths:
- The socket path is set to `$XDG_RUNTIME_DIR/docker.sock` by default.
`$XDG_RUNTIME_DIR` is typically set to `/run/user/$UID`.
- The data dir is set to `~/.local/share/docker` by default.
The data dir should not be on NFS.
- The daemon config dir is set to `~/.config/docker` by default.
This directory is different from `~/.docker` that is used by the client.
### Client
You need to specify either the socket path or the CLI context explicitly.
To specify the socket path using `$DOCKER_HOST`:
```console
$ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock
$ docker run -d -p 8080:80 nginx
```
To specify the CLI context using `docker context`:
```console
$ docker context use rootless
rootless
Current context is now "rootless"
$ docker run -d -p 8080:80 nginx
```
## Best practices
### Rootless Docker in Docker
To run Rootless Docker inside "rootful" Docker, use the `docker: