In Docker, containers can be run in two main modes: privileged and non-privileged. This choice determines the level of access the container will have to the host’s resources and system functions. Understanding the differences between these modes is extremely important: it affects both the security of your system and the functionality of applications inside the containers. The non-privileged mode is suitable for most daily tasks, providing isolation and protection for the host, while privileged gives the container full access to host devices, the kernel, and network interfaces, which is only necessary in specific cases such as driver testing or hardware management. A conscious choice of the execution mode helps balance functionality and security.
Non-privileged Containers (Default)
What it is:
- Containers run in a restricted environment.
- They do not have direct access to the host kernel and most system resources.
- They cannot perform operations that require elevated privileges (e.g., modifying host network interfaces, managing kernel modules).
Features:
- Security: Increased isolation from the host.
- Limitations: Some applications that require low-level access to the host may not work.
Real use cases: Web services, databases, applications that don’t need to change host system settings.
Example of running:
docker run -it ubuntu:22.04 bashThis container runs in non-privileged mode by default.
Privileged Containers
What it is:
- The container gets almost full access to the host.
- All kernel capabilities and host device access are allowed.
The container can:
- Mount host devices (/dev),
- Manage kernel modules,
- Configure network interfaces,
- Perform other system operations as root on the host.
Features:
- Functionality: Full host access allows running containers for system software, emulation, or driver testing.
- Risk: Increased security risk. If an attacker gains control over such a container, they effectively gain control over the host.
Example of running:
docker run --privileged -it ubuntu:22.04 bashWhen to use:
- For containers that need access to host devices (e.g., USB, GPU).
- For system containers emulating host services.
- For testing and debugging.
Permission Differences
| Characteristic | Non-privileged | Privileged |
|---|---|---|
| Host kernel access | No | Yes |
| Access to /dev devices | Limited | Full |
| Kernel module management | No | Yes |
| Modifying host network interfaces | No | Yes |
| Security risk | Low | High |
| Use case | Regular applications, services | System services, testing, device access |
| Example of running | docker run -it image bash | docker run --privileged -it image bash |
Recommendations
In most cases, it’s better to run containers in non-privileged mode — it’s safe and ideal for regular applications and services that don’t require direct host access. The privileged mode should only be used when truly necessary, for example, if your application needs to manage devices, kernel modules, or host network interfaces. Even in these cases, think about security and don’t grant more permissions than necessary. Often a good alternative to full --privileged is granting specific capabilities via --cap-add or access to needed devices via --device, for example:
docker run --cap-add=NET_ADMIN --device=/dev/sda1 -it ubuntu:22.04 bashThis way, you maintain control, enhance security, and allow the container to perform necessary tasks without unnecessary risks.
Cheat Sheet
| Characteristic | Non-privileged | Privileged |
|---|---|---|
| Host kernel access | No | Yes |
| Access to /dev devices | Limited | Full |
| Kernel module management | No | Yes |
| Modifying host network interfaces | No | Yes |
| Security risk | Low | High |
| Use case | Regular applications, services | System services, testing, device access |
| Example of running | docker run -it image bash | docker run --privileged -it image bash |