TürkiyeVPS

Install Docker on Ubuntu 24.04 and Run Your First Container

Install Docker on an Ubuntu 24.04 VPS from the official repository, run your first container and deploy a persistent service with Docker Compose — plus the firewall trap and low-RAM tips.

7 min read

Dependencies are what usually eat your time when you deploy an app: the wrong PHP version, a missing library, a package that conflicts with another project. Docker solves this by running each application inside a container together with everything it needs. In this guide we will install Docker on Ubuntu 24.04, run a first container and use Docker Compose to deploy a service that survives reboots. By the end you will be able to bring up n8n, Uptime Kuma or your own app on a Docker VPS with a single command.

What is Docker, and how is it different from a VM?

Your VPS is already a virtual machine with its own kernel and operating system. Docker containers are isolated processes that share your server's kernel, which is why they start in seconds and use very few resources.

Three terms are enough to get started:

  • Image: a packaged, read-only bundle of an application and its dependencies (for example nginx or postgres).
  • Container: a running instance of an image.
  • Volume: storage that keeps data even when the container is deleted.

Before you start

  • A VPS running Ubuntu 24.04 and a user with sudo rights.
  • Basic comfort with the command line. If you are new to it, our basic Linux commands guide is a good starting point.

Ubuntu's own repositories ship a package called docker.io, but for the current release and the Compose plugin we will use Docker's official apt repository.

1. Remove conflicting packages

If Docker was ever installed another way, remove the old packages to avoid conflicts. If none are installed, apt will say so and you can move on:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y $pkg; done

2. Add Docker's official repository

sudo apt-get update
sudo apt-get install -y 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.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

During the last command you should see lines from download.docker.com. On Ubuntu 24.04 the codename is noble.

3. Install Docker Engine and the Compose plugin

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

The service starts automatically and is enabled at boot. Let's verify:

sudo systemctl status docker --no-pager
docker --version
docker compose version

There is nothing extra to download for Docker Compose: docker-compose-plugin provides the docker compose command (v2, with a space). The old hyphenated docker-compose tool is deprecated.

4. First test: hello-world

sudo docker run hello-world

Docker pulls the image from Docker Hub, starts a container and prints "Hello from Docker!". If you see that message, the installation works.

5. Using Docker without sudo

If you don't want to type sudo every time, add your user to the docker group:

sudo usermod -aG docker $USER
newgrp docker
docker ps

Logging out and back in works just as well as newgrp.

Security note: a member of the docker group effectively has root-equivalent access — they can mount the host's root filesystem into a container and change any file. Only add users you fully trust.

6. A real first container: Nginx

Let's run a web server and publish it on port 8080:

docker run -d --name web -p 8080:80 nginx:stable
  • -d: run in the background.
  • --name web: give the container a memorable name.
  • -p 8080:80: map the server's port 8080 to the container's port 80.

Open http://SERVER_IP:8080 in your browser and you will see the Nginx welcome page. The commands you will use every day:

docker ps              # running containers
docker ps -a           # all containers, including stopped ones
docker logs -f web     # follow logs (Ctrl+C to exit)
docker exec -it web sh # open a shell inside the container
docker stop web        # stop
docker rm web          # remove

7. A persistent service with Docker Compose

Instead of memorising long docker run commands, describe the service in a file. As an example, let's deploy Uptime Kuma, a handy monitor for your servers and websites:

mkdir -p ~/uptime-kuma && cd ~/uptime-kuma
nano compose.yaml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - kuma-data:/app/data

volumes:
  kuma-data:
docker compose up -d
docker compose ps
docker compose logs -f

Three settings matter here:

  • restart: unless-stopped: if the container crashes or the server reboots, it comes back automatically — unless you stopped it yourself. Other options are no, always and on-failure.
  • volumes: data lives in the kuma-data volume, so it survives image updates and container re-creation.
  • 127.0.0.1:3001:3001: the port is reachable only from the server itself; public access should go through a reverse proxy with HTTPS. For a quick test you can temporarily use "3001:3001".

To update:

docker compose pull
docker compose up -d

Important: published Docker ports bypass UFW

This is the most common beginner trap. Docker writes its own iptables rules for published ports such as -p 8080:80, and those rules are evaluated before UFW's. Even if you run ufw deny 8080, the port stays open to the internet.

The fix is simple:

  • When a service sits behind a reverse proxy (Nginx, Caddy), publish its port with the 127.0.0.1: prefix so it is only reachable locally.
  • Don't publish database ports (PostgreSQL, MySQL, Redis) at all; services in the same Compose file already reach each other by service name.
  • Check what is exposed regularly with ss -tulpn and docker ps.

Cleaning up disk space

Images and stopped containers pile up over time, which hurts on small disks:

docker system df       # how much space is Docker using?
docker system prune    # remove stopped containers, unused networks and dangling images

docker system prune -a removes all unused images; they will be downloaded again on next start. Think twice before adding --volumes — data in volumes cannot be recovered.

Docker on a low-RAM VPS

Docker itself is light, but your containers need memory. On a VPS with 512 MB or 1 GB of RAM, a single Nginx or a small bot runs comfortably; a database + app + monitoring stack can get tight. Tips:

  • Add swap to absorb memory spikes and keep containers from being OOM-killed. See our guide on adding swap to an Ubuntu VPS.
  • Watch per-container memory with docker stats.
  • Set limits in Compose, such as mem_limit: 256m, so one service can't eat all the RAM.
  • Prefer smaller alpine-based images where available.

Frequently Asked Questions

What is the difference between docker.io and docker-ce?

docker.io comes from Ubuntu's own repository and is usually older. docker-ce comes from Docker's official repository, is updated more often and ships the docker compose plugin alongside it. Don't install both.

How much server do I need for Docker?

Docker Engine itself uses little; real requirements depend on the apps you run. A small VPS is fine for a single web service or bot. Multi-container tools like n8n, or anything with a database, are more comfortable with 2 GB of RAM or more.

Can I run n8n with Docker?

Yes — Docker is one of n8n's recommended installation methods. See our step-by-step n8n installation guide.

A VPS ready for Docker

Our VPS plans start at $0.89/month and are deployed automatically with Ubuntu 24.04 within minutes of payment confirmation, so you can run every command in this guide right away with full root access. If you plan to keep several containers running around the clock, our VDS plans — from $1.69/month with dedicated vCPU and guaranteed RAM — give you more predictable performance. Every plan includes unlimited traffic, servers are located in Istanbul, Turkey, and payment is accepted in USDT (TRC20).