Docker Engine installed from Docker’s official Ubuntu repository, the Compose plugin available, and a successful test container.
This guide is for a clean Ubuntu Server system. Docker currently documents Ubuntu 26.04, 24.04, and 22.04 LTS among its supported versions. If this machine already runs containers, stop here and review your current installation and backups before replacing packages or changing the engine.
1. Check your Ubuntu installation
Complete the Ubuntu Server guide first, or confirm you have a supported release, internet access, and an account with sudo permissions.
cat /etc/os-release
dpkg --print-architectureUse the actual output to choose the right installation instructions. This walkthrough follows the official Ubuntu APT-repository method. It is separate from Docker Desktop and does not use Ubuntu’s docker.io package.
On an existing installation, conflicting container packages can require migration or removal. Do not blindly uninstall them from a working server. Check Docker’s current prerequisites and make a migration plan first.
2. Add Docker’s repository and signing key
Install the tools needed to fetch the repository key, create the key directory, and make the key readable to APT:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.ascCreate the repository definition. The expressions below read your Ubuntu codename and package architecture rather than assuming a particular release. Paste the whole block, including the final EOF line, into a Bash shell:
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOFThis is the repository-based installation path documented by Docker. It keeps later engine updates in the normal APT workflow.
3. Install the engine and plugins
Refresh APT after adding the repository, then install the engine, container runtime, build plugin, and Compose plugin:
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginCheck the service and command versions:
sudo systemctl status docker --no-pager
sudo docker version
sudo docker compose versionIf the service is not active on this fresh install, start it with sudo systemctl enable --now docker and inspect any errors. Compose is invoked as docker compose with a space.
These examples keep sudo in Docker commands. Membership in the Docker group grants powerful access to the host; understand that tradeoff before allowing an account to control the engine without sudo.
4. Run a small test container
The official test image checks whether Docker can pull an image and run a container:
sudo docker run --rm hello-worldA successful run prints a greeting and an explanation of what the engine did. The --rm option removes the test container after it exits; the downloaded image can remain in the local cache.
Now check that no unexpected containers are running:
sudo docker psThis test does not publish a service port. If the pull fails, investigate DNS, internet access, repository connectivity, and the actual error message before changing container settings.
5. Understand ports before hosting a service
A running container is not automatically a reachable website. A published port connects a host address and port to a container port. Without a specified host address, Docker normally publishes to all host interfaces.
Binding a port to a particular LAN address narrows where it is published, but routing and firewall configuration still control who can reach it. Binding to 127.0.0.1 on a current Docker release makes it accessible through the host’s loopback interface. See Docker’s port-publishing guide for the details and older-version caveats.
Docker’s published-port traffic can bypass ordinary UFW rules. Do not assume a host firewall rule makes a container private. Keep router port forwarding off for the local Jellyfin project and review Docker’s firewall guidance before changing exposure.
6. Troubleshoot before adding an application
| Problem | Useful next check |
|---|---|
| APT cannot find Docker packages | Check that docker.sources exists, its codename matches your supported Ubuntu release, and sudo apt update completed successfully. |
| Docker socket permission denied | Use the sudo docker … form shown here. Do not make the Docker socket world-writable. |
| The service will not start | Read sudo journalctl -u docker --no-pager -n 80. Investigate the error rather than reinstalling repeatedly. |
docker compose is missing | Confirm docker-compose-plugin installed from the intended repository. |
| An image cannot be downloaded | Check the image name, DNS, internet connection, available disk space, and any registry error. |
Once the engine and Compose checks work, you have the foundation for the Jellyfin guide. Keep application configuration and backups organized from the start.
Sources & further reading
The commands and examples in this guide are written for a generic installation. Consult the official documentation for release-specific changes.



