How to Install Docker on a Linux Dedicated Server (Ubuntu Guide)

A Linux dedicated server gives you exclusive CPU, RAM, NVMe storage and network bandwidth. Docker gives you a clean way to split that hardware into isolated, repeatable services. Together they let one machine run a website, an API, a database and a monitoring stack without any of them interfering with the others.

This guide shows you how to install Docker Engine on an Ubuntu dedicated server using Docker's official apt repository. It then goes past the install and covers what production actually needs: running Nginx in a container, Docker networking, persistent volumes, Docker Compose, firewall rules that work with Docker, security hardening, monitoring, backups and troubleshooting.

Before you start: Package names and repository details change over time. Cross-check Docker's official Ubuntu installation documentation before running any install or security command on a production server.

Quick Answer: How Do You Install Docker on a Linux Dedicated Server?

  • Connect over SSH and update Ubuntu.

  • Add Docker's official GPG key and apt repository.

  • Install docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin and docker-compose-plugin.

  • Enable the Docker service so it starts at boot.

  • Verify with sudo docker run hello-world.

1. What Is Docker?

Docker is a container platform. It packages an application together with its libraries and dependencies into a portable unit called a container. A container shares the host's Linux kernel, but its processes, filesystem, and resource limits are isolated using Linux namespaces and control groups (cgroups).

That is the key difference from a virtual machine. A container does not boot a full guest operating system, so it starts in seconds and carries far less overhead.

Component Role
Docker Engine Builds and runs containers
Docker CLI Command-line tool for managing Docker
Docker daemon (dockerd) Background service that does the actual work
Docker image Read-only template used to create containers
Docker container A running instance of an image
Docker network Virtual network that connects containers
Docker volume Persistent storage managed by Docker
Docker Compose Defines and runs multi-container applications

Instead of installing and configuring Nginx by hand, you pull the official Nginx image and start a container with one command. Recreate it tomorrow, and you get exactly the same runtime.

2. Why Run Docker on a Dedicated Server?

A dedicated server reserves physical CPU, RAM, storage, and bandwidth for you alone. Docker adds an isolation layer on top, so one powerful machine can host many independent services safely.

Dedicated hardware matters most when your containers need:

  • Predictable CPU performance, because no other tenant competes for your cores

  • Large memory pools for databases, caches, and search engines

  • Fast NVMe storage for write-heavy or I/O-heavy workloads

  • Sustained network throughput for high-traffic applications

Typical workloads include web and application hosting, Nginx and Apache reverse proxies, Node.js, Python and PHP apps, MySQL, MariaDB and PostgreSQL databases, Redis, API services, CI/CD runners, monitoring stacks, staging environments, game servers and background job workers.

Docker does not make an application faster on its own. Performance still depends on your code, container resource limits, storage speed, and network configuration. What Docker does give you is consistency, isolation, and easy redeployment on hardware you fully control.

3. Docker vs Virtual Machines

Containers and virtual machines both isolate workloads, but at different layers.

Docker containers

  • Share the host's Linux kernel

  • Start in seconds

  • Use less overhead than a full guest OS

  • Suit microservices and repeatable application deployment

Virtual machines

  • Run a complete guest operating system

  • Provide stronger isolation between OS environments

  • Can run different operating systems on one host

  • Fit workloads that need their own kernel

The two are not mutually exclusive. You can run Docker inside a virtual machine, and many teams do. On a Linux dedicated server, Docker directly on the host is usually the simplest and most efficient option, because the physical hardware already provides dedicated resources beneath your containers.

4. Server Requirements for Docker

Docker itself is lightweight. Your applications decide the real hardware needs.

Resource Details
CPU A modern multi-core processor helps when you run several containers, build images or handle concurrent requests.
RAM Needs vary widely. A small web app needs little; databases, caches, search engines and AI inference can need a lot.
Storage SSD or NVMe is strongly recommended. Images, logs, databases and volumes all grow over time.
Network Public-facing containers need enough bandwidth. Consider 1 Gbps or higher for busy applications.
Operating System This guide uses 64-bit Ubuntu. Check Docker's official list of supported Ubuntu versions before you install.

Sizing tip: Plan the server for the combined needs of every container you intend to run, not for Docker alone.

5. Prepare Your Ubuntu Server

Connect to the server over SSH:

ssh username@SERVER_IP

Replace username with your Linux account and SERVER_IP with the server's public IP address.

Confirm the environment before changing anything:

cat /etc/os-release   # OS version
uname -m              # CPU architecture
uname -r              # Kernel version
free -h               # Available memory
df -h                 # Disk usage

On a fresh server, create a dedicated administrative user instead of working as root, and prefer SSH key authentication over password-only login. Keep a working access method (such as your provider's remote console or IPMI/KVM) available before you change SSH or firewall settings.

6. Update the Server

Update the package index and installed packages:

sudo apt update
sudo apt upgrade -y

Install the prerequisites needed to set up Docker's repository:

sudo apt install -y ca-certificates curl

If the system recommends a reboot (for example, after a kernel update), reboot and reconnect:

sudo reboot

Updating first avoids installing Docker on top of outdated dependencies and applies existing security patches before you expose any new services.

7. Install Docker Engine from the Official Repository

For production, install Docker Engine from Docker's official apt repository rather than an older distribution package. This keeps Docker updateable through your normal apt workflow.

Step 1: Add Docker's GPG key

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.asc

Step 2: Add the Docker apt repository

sudo tee /etc/apt/sources.list.d/docker.sources <<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
EOF

sudo apt update

Step 3: Install Docker Engine, the CLI, containerd, Buildx, and Compose

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Docker also publishes a convenience install script. Its own documentation recommends it for development and testing rather than production, so the repository method above is the better choice for a production dedicated server.

8. Verify the Docker Installation

Check that the service is running:

sudo systemctl status docker
sudo systemctl start docker   # only if it is not already running

Confirm versions and configuration:

sudo docker version
sudo docker info
docker compose version

Run the official test image:

sudo docker run hello-world

Docker should pull the image, run it, print a confirmation message and exit cleanly. Modern Docker Compose is a plugin, invoked as docker compose (with a space). The older standalone docker-compose binary is a legacy tool.

9. Start Docker Automatically on Boot

On a dedicated server, Docker should come back after every reboot:

sudo systemctl enable docker.service
sudo systemctl enable containerd.service
sudo systemctl start docker

sudo systemctl is-enabled docker
sudo systemctl is-active docker

Auto-start brings the Docker service back after maintenance or an unplanned restart, but it does not guarantee every container restarts. Set an explicit restart policy on each production container (shown in the next sections).

10. Run Your First Docker Container

Launch a simple Nginx container:

sudo docker run -d --name web-server nginx:alpine

Useful commands for managing it:

sudo docker ps                              # running containers
sudo docker ps -a                         # all containers, including stopped
sudo docker logs web-server             # view logs
sudo docker inspect web-server          # full container details
sudo docker stop web-server
sudo docker start web-server
sudo docker rm web-server

Because a container can always be recreated from its image, you get a reproducible runtime instead of a hand-configured server that slowly drifts over time.

11. Deploy Nginx with Docker

Run Nginx with its HTTP port published and an automatic restart policy:

sudo docker run -d \
  --name nginx-server \
  --restart unless-stopped \
  -p 80:80 \
  nginx:alpine

Open http://SERVER_IP in a browser to see the Nginx welcome page.

Flag Purpose
-d Runs the container in the background (detached mode)
--name nginx-server Gives the container a readable name
--restart unless-stopped Restarts the container after failures or reboots
-p 80:80 Maps host port 80 to container port 80
nginx:alpine The lightweight Alpine-based Nginx image

A real production deployment adds a domain name, HTTPS/TLS, application configuration, persistent storage, logging, and a proper reverse-proxy layout in front of your services.

12. Expose a Container to the Internet Safely

Containers are not reachable from outside unless you publish their ports:

docker run -d -p HOST_PORT:CONTAINER_PORT IMAGE

Example:

sudo docker run -d --name web-app -p 8080:80 nginx:alpine

Now http://SERVER_IP:8080 reaches the container. Publish ports deliberately. A mapping such as -p 5432:5432 can expose a PostgreSQL database to the public internet on an internet-facing server.

To keep a service reachable only from the server itself, bind it to the loopback address:

sudo docker run -d --name internal-web -p 127.0.0.1:8080:80 nginx:alpine

Security rule: publish only the ports a service genuinely needs to expose externally.

13. Configure Docker Networking

Docker networks let containers talk to each other in isolation from the host's default network.

sudo docker network ls                                                 # list networks
sudo docker network create app-network                                   # create a custom bridge network
sudo docker run -d --name web --network app-network nginx:alpine
sudo docker run -d --name test-client --network app-network alpine:latest sleep 3600
sudo docker network inspect app-network

On a custom network, containers can reach each other by name (for example web), which is far cleaner than tracking IP addresses.

A typical multi-service layout looks like this:

Internet
   |
   v
Nginx / Reverse Proxy
   |
   +---- Web Application
   |
   +---- API
   |
   +---- Database

Only the reverse proxy needs to be public. Application containers communicate over an internal Docker network, so you avoid publishing databases, caches, queues, and internal APIs unless there is a specific reason.

14. Configure Persistent Docker Volumes

Containers are disposable by design. Data stored only in a container's writable layer disappears when the container is removed. Use Docker volumes (or carefully managed bind mounts) for anything you need to keep.

sudo docker volume create nginx-data
sudo docker volume inspect nginx-data

sudo docker run -d \
  --name nginx-volume \
  -p 8081:80 \
  -v nginx-data:/usr/share/nginx/html \
  nginx:alpine

sudo docker volume ls
sudo docker volume rm nginx-data

Be careful with docker volume rm, because volumes can hold production data. For databases such as PostgreSQL or MySQL, plan storage before go-live: filesystem performance, backup strategy, disk capacity, and recovery procedures all matter.

15. Run Multiple Containers with Docker Compose

For applications with several services (for example, Nginx, an app server, Redis, and PostgreSQL), Docker Compose replaces managing each container by hand.

mkdir -p ~/docker-demo
cd ~/docker-demo

Create a file named compose.yaml:

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    restart: unless-stopped

Manage the stack:

sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs
sudo docker compose logs -f
sudo docker compose down

Good Compose habits for production: keep the file in version control, document required environment variables, never commit secrets, and define persistent storage explicitly.

16. Configure a Firewall for Docker

A public dedicated server needs a clear inbound-traffic policy. Typical allowed services are:

  • SSH: TCP 22 (or your configured port)

  • HTTP: TCP 80

  • HTTPS: TCP 443

Do not open database ports or admin interfaces to the internet without a specific need and proper access control. Ubuntu commonly uses UFW:

sudo ufw status
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Important: Docker and UFW do not always cooperate. Docker manages its own iptables and NAT rules for published ports, and those rules can bypass what you expect UFW to enforce. A rule like sudo ufw deny 8080/tcp does not necessarily block a port that Docker has published on 8080.

Practical ways to stay in control:

  • Bind internal services to 127.0.0.1 so they are never exposed in the first place.

  • Publish only the ports you truly need.

  • Use the DOCKER-USER iptables chain, which Docker documents as the place for custom filtering rules evaluated before its own forwarding rules.

  • Review any provider-level network firewall as well.

Test every firewall change carefully and keep out-of-band console access available. A bad rule can lock you out of your own dedicated server.

17. Secure Docker on a Dedicated Server

Docker security covers the host, the daemon, network exposure, credentials, images and volumes, not just the container image.

  • Use trusted images. Prefer official images and vetted publishers, and check update history.

  • Keep Docker updated. Track Docker Engine, containerd, Compose and Ubuntu security patches.

  • Never expose the Docker daemon publicly. Its API carries powerful privileges.

  • Restrict access to the Docker socket. Treat it as a highly privileged credential.

  • Avoid running containers as root where the application supports a non-root user.

  • Drop unnecessary Linux capabilities instead of granting them by default.

  • Avoid --privileged containers unless the workload genuinely requires it.

  • Use --read-only filesystems where practical, with separate writable temp storage.

  • Protect secrets. Never bake passwords or API keys into images or public repositories.

  • Limit published ports to what needs external connectivity.

  • Segment services with internal networks to reduce lateral exposure.

  • Set resource limits so a runaway container cannot exhaust CPU, RAM, disk or bandwidth.

  • Back up persistent data. Images are reproducible; production data usually is not.

It also helps to stop container logs from filling the disk. Add log rotation in /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Then restart Docker with sudo systemctl restart docker. The new defaults apply to newly created containers, so recreate existing ones to pick them up.

Treat Docker as one layer of your dedicated server's security architecture, not a complete security boundary on its own.

18. Monitor Docker Containers

Start with the built-in commands:

sudo docker ps               # running containers
sudo docker ps -a            # all containers
sudo docker stats            # live resource usage
sudo docker logs CONTAINER_NAME
sudo docker logs -f CONTAINER_NAME
sudo docker inspect CONTAINER_NAME
sudo docker system df        # Docker disk usage

Track these over time: CPU and memory use, disk usage, container restarts, application logs, network traffic, storage growth, host load, daemon health, and response times.

For larger deployments, add an observability stack such as Prometheus and Grafana, or a centralized logging system. One misconfigured container can consume a disproportionate share of a dedicated server's resources, and monitoring is how you catch it early.

19. Back Up Docker Data

Images and containers can be rebuilt. Application data cannot. Back up:

  • Docker volumes and bind-mounted directories

  • Databases and application uploads

  • Configuration files and TLS certificates

  • Compose files and infrastructure configuration

Inspect your volumes, then archive one with a throwaway container:

sudo docker volume ls
sudo docker volume inspect VOLUME_NAME

sudo docker run --rm \
  -v VOLUME_NAME:/data:ro \
  -v "$PWD":/backup \
  alpine \
  tar czf /backup/volume-backup.tar.gz -C /data .

For databases, prefer native tools such as pg_dump or mysqldump over copying live files, because they preserve transactional consistency.

Always test restores. A backup that has never been restored is not a validated recovery plan. Where practical, follow the 3-2-1 rule: three copies, on two types of storage, with one copy offsite. Define your recovery time objective (RTO) and recovery point objective (RPO) up front.

20. Common Docker Problems and Fixes

  • docker: command not found: Verify the installation with docker --version and re-check the repository steps in Section 7.

  • Permission denied when running Docker: If sudo docker ps works but docker ps fails, your user is not in the docker group:

    groups
    sudo usermod -aG docker $USER   # log out and back in afterward

    Only add trusted users. Membership in the docker group is effectively root-level access to the server.

  • Docker service not running:

    sudo systemctl status docker
    sudo systemctl start docker
    sudo journalctl -u docker --no-pager -n 100
  • Container stops immediately: Run docker ps -a, then docker logs CONTAINER_NAME to find the exit cause: a bad config, missing environment variable, invalid command, permission problem or application error.

  • Port already in use:

    sudo ss -lntp
    sudo docker ps

    Change the host port (for example -p 8081:80) or stop the conflicting service.

  • Container cannot reach the internet:

    sudo docker exec CONTAINER_NAME ping -c 3 1.1.1.1
    sudo docker inspect CONTAINER_NAME

    Check DNS settings and host firewall rules.

  • Published port unreachable from outside:

    sudo docker port CONTAINER_NAME
    curl http://127.0.0.1:HOST_PORT

    If it works locally but not externally, check the host firewall, any provider-level firewall or security group, and routing.

  • Disk space running low:

    df -h
    sudo docker system df

    Review unused images, stopped containers, and volumes before cleaning up. Never run docker system prune -a on production without checking exactly what it will remove.

  • Container loses data after recreation: Inspect docker inspect CONTAINER_NAME and look at the Mounts section. If data lives only in the writable layer, redesign storage with a volume before going to production.

21. Docker Production Checklist

Server

  • Ubuntu version supported by the current Docker release

  • System packages updated

  • SSH access secured

  • Administrative access limited

  • Server resources match the workload

  • Disk space monitored

Docker

  • Installed from the official repository

  • Starts automatically on boot

  • Compose installed where needed

  • Kept updated

  • Only trusted users can control it

Networking

  • Only required ports published

  • Internal services on private Docker networks

  • Database ports not unnecessarily public

  • Firewall rules tested

  • Provider-level firewall reviewed

Security

  • No unnecessary container privileges

  • Secrets protected, never in images or repositories

  • Images reviewed and updated

  • Docker daemon not publicly exposed

  • Unnecessary capabilities dropped

  • Logs monitored

Storage

  • Important data on persistent storage

  • Database backups configured

  • Volumes included in the backup plan

  • Restore procedures tested

  • Storage growth monitored

Operations

  • Restart policies defined

  • Application logs monitored

  • CPU, RAM and disk usage monitored

  • Container failures trigger a response

  • Upgrade and rollback procedures documented

Choosing the Right Dedicated Server for Docker

Once Docker is running, the hardware underneath it decides how far you can scale. A few practical pointers:

  • Many small containers or microservices: prioritize core count and RAM.

  • Database-heavy stacks: prioritize NVMe storage and memory. See our comparison of HDD vs SSD vs NVMe dedicated servers for storage trade-offs.

  • Public traffic and APIs: prioritize bandwidth and a data center close to your users. Browse KW Servers dedicated server locations to compare regions.

  • Memory planning: our guide on how much RAM a dedicated server needs helps you size the machine for your container mix.

Explore more Linux and infrastructure guides in the KW Servers tutorials hub.

Frequently Asked Questions

Can I install Docker on a dedicated server?

Yes. Docker Engine runs on supported Linux distributions, including current Ubuntu LTS releases, and a dedicated server provides the CPU, memory, storage and network resources your containers need.

Is Docker good for dedicated servers?

Docker fits well when you need repeatable deployments, isolated services, containerized development and staging environments, or several workloads sharing one host. The right architecture still depends on your applications and operational needs.

How much RAM does Docker need?

Docker itself is lightweight. Real memory needs come from your containers. A web server, database, cache and monitoring stack can each demand very different amounts of RAM.

Can Docker run multiple websites on one dedicated server?

Yes. Each site can run in its own container, with an Nginx reverse proxy routing domains and HTTPS traffic to the correct backend.

Does Docker replace a virtual machine?

No. They use different isolation models: containers share the host kernel, while virtual machines run full guest operating systems. Both have valid, sometimes complementary, uses.

Are Docker containers secure?

Containers provide isolation, but Docker is not a complete security solution by itself. Secure deployments also need host hardening, trusted images, least-privilege configuration, restricted access, careful network exposure, timely updates and monitoring.

Should Docker containers use persistent volumes?

Any application whose data must survive container recreation, such as databases and user uploads, should use Docker volumes or bind mounts, together with a deliberate backup strategy.

How do I expose a Docker container to the internet?

Publish a port, for example docker run -d -p 80:80 nginx:alpine. Expose only the ports that genuinely need external access, and review your firewall and application security first.

What is Docker Compose used for?

Docker Compose defines multiple services, networks, volumes and configuration in a single file, so a multi-container application can be managed as one unit.

What should I monitor on a Docker dedicated server?

Host CPU, RAM, disk and network usage; container restarts and resource consumption; application logs; storage growth; and overall service availability.

How often should I update Docker?

Review Docker Engine, container images, Compose, Ubuntu security patches and application dependencies on a regular schedule that fits your change-control process.

Final Thoughts

Installing Docker on a Linux dedicated server takes only a few commands. Running it well takes a few more decisions: publish only the ports you need, keep data on volumes, back it up, monitor resource use and keep everything patched. Follow the steps and checklist above and you will have a container platform that is repeatable, easy to recover and ready for production.

Need hardware to match? Explore KW Servers dedicated servers for dedicated CPU, RAM, NVMe storage and bandwidth built for containerized workloads.

Discover KW Servers Dedicated Server Locations

KW Servers servers are available around the world, providing diverse options for hosting websites. Each region offers unique advantages, making it easier to choose a location that best suits your specific hosting needs.

Find Your Perfect Server

AI-powered · Instant results

Ask KW Servers AI
Instantly match you to the perfect dedicated server

How can I help you today?

Try asking for specific hardware, locations, or budgets.

Ryzen 9 in Germany

High-performance compute nodes in EU

128GB RAM Servers

Ideal for heavy virtualization

Budget Gaming

Low-latency servers under $100/mo

10TB Storage Arrays

Secure backup and archiving