What Is Docker and Why Should You Use It?
Docker is a containerization platform that lets you run applications inside isolated environments called containers. Each container packages an app with all its dependencies, so it stays lightweight, portable, and easy to manage.
Why Use Docker?
Simpler deployments. Instead of installing software directly on your server and fighting dependency conflicts, Docker bundles everything into a self-contained unit. It runs the same way on every system.
Lighter on resources. Docker containers share the host OS kernel, so they’re far cheaper on memory and CPU than a stack of full virtual machines. You can comfortably run dozens of containers on a single box.
Easier software management. Want Jellyfin, Sonarr, Radarr, or Home Assistant? You pull an image, run a container, and you’re done. No hand-compiling, no dependency hell.
Isolation by default. Containers don’t see each other. If one crashes or gets compromised, the rest of the system keeps running.
Updates and rollbacks are cheap. Pulling a newer image is one command. Rolling back to a known-good tag is one more.
Now that you know why Docker is worth running on your home server, let’s install it correctly with security in mind.

Intel NUC 12 Pro (NUC12WSHi5) Compact mini PC for lightweight servers, GPU Passthrough, Docker stacks, and VMs.
Contains affiliate links. I may earn a commission at no cost to you.
1. Update Your System and Install Dependencies
Before installing Docker, update your system and pull in the prerequisites. This gives you a clean, stable base.
Run the following:
sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg
These commands:
- Refresh the package list (
apt update) - Upgrade installed packages (
apt upgrade -y) - Install the dependencies you’ll need (if
curlandgnupgaren’t already on the box)
2. Add Docker’s Official GPG Key and Repository
Ubuntu ships a Docker package in its default repositories, but you shouldn’t use it. Here’s why:
- Outdated versions. Ubuntu’s repo lags behind Docker’s latest stable releases, so you miss features and security fixes.
- Slower updates. Critical bug fixes and security patches land in Docker’s official repo first. Ubuntu’s version gets them later, if at all.
- Missing features. The Ubuntu package can lack support for newer Docker functionality.
So, install from Docker’s official repository. Run the following commands.
Cheat Sheet - Cut & Paste Commands:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc > /dev/null
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
The Long and Detailed Explanation of the Commands:
sudo install -m 0755 -d /etc/apt/keyrings
Breaking It Down:
sudoruns the command with superuser (root) privileges.installis a command that can copy files, set permissions, and create directories.-m 0755sets the directory permissions to0755(read and execute for everyone, write for the owner).-dtellsinstallto create a directory if it doesn’t already exist./etc/apt/keyringsis where the directory is created. This is where trusted GPG keys for package signing live.
Security Purpose:
- Ensures only the owner (root) can modify the keyring directory.
- Prevents unauthorized users from tampering with the trusted GPG keys used to verify software packages.
- Ubuntu 24.04 and later recommend storing GPG keys in
/etc/apt/keyrings/instead of the older/etc/apt/trusted.gpg. It’s better security hygiene.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo tee /etc/apt/keyrings/docker.asc > /dev/null
Breaking The Three Parts of This Command Down:
1. curl -fsSL https://download.docker.com/linux/ubuntu/gpg
curlis a tool for downloading files from the internet.-ffails silently if the URL is wrong, so you don’t end up saving an error page.-sruns in silent mode (hides progress output).-Sshows errors when they occur, which makes troubleshooting easier.-Lfollows redirects in case the URL points somewhere else.https://download.docker.com/linux/ubuntu/gpgis the URL of Docker’s official GPG key.
What this does: downloads Docker’s GPG key, which is used to verify the authenticity of Docker packages.
2. | sudo tee /etc/apt/keyrings/docker.asc
|pipes the output ofcurlinto theteecommand.sudoruns the command as root (needed to write to system directories).tee /etc/apt/keyrings/docker.asc:teewrites the Docker GPG key into/etc/apt/keyrings/docker.asc.- That file is later used to verify Docker packages are signed and authentic before installing.
3. > /dev/null
>redirects output somewhere else./dev/nullis the Linux “trash” file that throws away anything written to it.
sudo chmod a+r /etc/apt/keyrings/docker.asc
Breaking It Down:
sudoruns the command with superuser (root) privileges.chmodchanges file permissions.astands for “all users” (owner, group, and others).+radds read permission so the file can be read by everyone./etc/apt/keyrings/docker.ascis the GPG key file used to verify Docker packages when installing or updating viaapt.
What this does:
Lets the system use the key. When apt installs or updates Docker, it checks package signatures against this GPG key. Without read access, apt will fail to verify Docker’s authenticity and throw errors at you.
Prevents unauthorized modifications. The file is still protected (only root can modify it), but every user can now read it. System processes and normal users can verify packages, but they can’t tamper with the key.
Follows Ubuntu’s newer security guidelines. Older versions stored GPG keys in /etc/apt/trusted.gpg, which gave every key full system-wide trust. That’s loose. Newer Ubuntu releases put each key under /etc/apt/keyrings/, where it’s isolated and trusted only for its own repository.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Breaking The Three Parts of This Command Down:
1. echo "deb [...] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
echoprints the text inside the quotes."deb [...] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"is a software repository entry in Debian/Ubuntu format.
What’s inside the deb [...] line?
debtellsaptthis is a binary package repository, not source code.[arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc]arch=$(dpkg --print-architecture)detects your system architecture (amd64,arm64, etc.) so you install the right build.signed-by=/etc/apt/keyrings/docker.ascuses Docker’s GPG key (the one you downloaded a minute ago) to verify package authenticity.
https://download.docker.com/linux/ubuntuis the URL of Docker’s official repository.$(lsb_release -cs)inserts your Ubuntu codename (e.g.,noblefor 24.04) so you get the right release.stablepulls the stable Docker channel instead of edge or testing builds.
2. | sudo tee /etc/apt/sources.list.d/docker.list
|pipes theechooutput intotee, which writes it to a file.sudoruns the command with root privileges, since/etc/apt/sources.list.d/requires admin access.tee /etc/apt/sources.list.d/docker.listsaves the repository entry into/etc/apt/sources.list.d/docker.list.
3. > /dev/null
- Throws away the output from
teeso your terminal stays clean.
Update your apt repositories:
sudo apt update
3. Install Docker
Now install Docker. The following command also pulls in the dependencies:
sudo apt install -y docker-ce
Make sure Docker starts at boot:
sudo systemctl enable --now docker
Once installed and enabled, verify Docker is running:
sudo docker ps
If Docker is running, you should see this after running docker ps:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
With nothing showing under those headers.
Security Step: Prevent Unauthorized Docker Access
By default, Docker runs as root. That’s a problem. Anyone in the docker group gets effective root on the host, so add a dedicated group and put your user in it deliberately:
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
After running these commands, you can run Docker without sudo:
docker run hello-world
4. Configure Docker for Better Security
A stock Docker install carries real risk. Let’s harden it.
Enable AppArmor
Ubuntu ships with AppArmor, a security module that restricts what Docker containers can do on the host.
Check whether it’s enabled:
sudo aa-status
If it isn’t, turn it on:
sudo systemctl enable --now apparmor
Stop Containers from Getting Root Privileges
By default, containers can run with elevated privileges. Restrict that with user namespaces.
Cheat Sheet - Cut & Paste These Commands:
sudo mkdir -p /etc/systemd/system/docker.service.d
echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/dockerd --userns-remap=default" | sudo tee /etc/systemd/system/docker.service.d/override.conf
sudo systemctl daemon-reload
sudo systemctl restart docker
Breakdown of These Commands:
Create a configuration directory for Docker:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudoruns the command as root (required for modifying system settings).mkdir -pcreates a directory if it doesn’t already exist (-pkeeps it from erroring out if the directory’s already there)./etc/systemd/system/docker.service.dis where custom systemd overrides for Docker live.
Why? This gives you a place to drop a custom configuration for the Docker service without editing the main service file.
Create an override file to enable user namespace remapping:
echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/dockerd --userns-remap=default" | sudo tee /etc/systemd/system/docker.service.d/override.conf
echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/dockerd --userns-remap=default":- Builds a custom systemd service override for Docker.
ExecStart=(empty) clears the previousExecStartfrom the default Docker service.ExecStart=/usr/bin/dockerd --userns-remap=defaultreplaces it with one that enables user namespace remapping.
| sudo tee /etc/systemd/system/docker.service.d/override.conf:- Pipes the output (
|) intotee, which writes it into the override file at/etc/systemd/system/docker.service.d/override.conf. sudogivesteethe root access it needs.
- Pipes the output (
Why?
- User namespace remapping (
--userns-remap=default) makes Docker containers run as an unprivileged user on the host instead of root. - If a container is compromised, it doesn’t get full root on the host.
Reload systemd to apply the changes:
sudo systemctl daemon-reload
sudoruns as root.systemctl daemon-reloadreloads systemd so it picks up the new Docker service override.
Why? Without it, systemd never notices the new override.conf file.
Restart Docker to apply the new configuration:
sudo systemctl restart docker
sudoruns as root.systemctl restart dockerrestarts Docker so it runs with the new--userns-remap=defaultsetting.
Why?
- Applies the security change without rebooting.
- From now on, Docker containers run as an unprivileged user instead of root.
Wrapping Up
Docker is a powerful tool for running apps on your Ubuntu 24.04 server. An insecure setup will bite you. Follow this guide and you’ve got Docker installed correctly, with sensible security mitigations in place.
Want to push security further? Look at ufw for the firewall layer and fail2ban for blocking brute-force attempts on exposed services.
Next up: deploying Sonarr and Radarr on top of this Docker install.

ASRock Intel ARC A380 Challenger The Arc A380 isn’t for gamingβitβs for obliterating video streams. With support for H.264, HEVC, and full AV1 hardware encode/decode, it crushes 20+ 1080p streams or 6β8 HDR tone-mapped 4Ks without breaking a sweat. Drop it in your media server, give Jellyfin direct VA-API access, and watch your CPU finally cool off for a bit.
Contains affiliate links. I may earn a commission at no cost to you.
