Docker on a VPS: getting started

Docker lets you run a bot, a website, a database and monitoring on one server without them getting in each other's way, and moving to another VPS comes down to copying a couple of files and the data. Installation takes five minutes; the real trouble starts later: database ports exposed to the internet, logs growing to tens of gigabytes and data that vanished along with a container. Here is how to avoid all of that from the start.

Updated 01.11.2026 · Find a VPS for your needs →

A container is an application packaged into an image together with all its libraries and settings. On a server it starts with one command and behaves the same on any Linux. For a VPS this means you do not have to match Python, Node.js or PostgreSQL versions to the system, several projects can share one server, and a compose.yaml file describes the whole set of services so that it can be brought up on a new server in minutes.

What kind of VPS Docker needs

Virtualization: KVM. Docker relies on Linux kernel features: namespaces, cgroups and its own network rules. On KVM the server has its own kernel, and Docker works without restrictions. On OpenVZ and LXC the kernel is shared with other customers, and Docker either does not start at all or runs with restrictions that depend on the host. More in KVM or OpenVZ.

Memory and cores. Docker itself is light; it is the containers that eat memory. Guidelines:

  • 1 GB — one or two light containers: a bot, a small API, monitoring;
  • 2 cores and 2 GB — a website with a database and a reverse proxy, a few small services;
  • 2–4 cores and 4 GB — several projects, PostgreSQL, Redis, building images right on the server;
  • 8 GB or more — GitLab, n8n with many workflows, Elasticsearch and other heavy services.

Disk. Images take up space: a base image with Python or Node.js weighs hundreds of megabytes, and old versions pile up with every update. Take at least 30 GB on NVMe, and more if you build images on the server.

According to the accsly catalog as of 1 November 2026, a KVM plan with 2 cores and 2 GB of memory costs about $15 a month at the middle of the market, and a quarter of such plans are cheaper than about $9. With 2 cores and 4 GB the median is about $20, with a quarter cheaper than about $12 (the catalog stores prices in roubles; dollar figures are rounded). Selections: VPS for Docker, KVM VPS, VPS with 4 GB. For experiments, hourly billing is handy: a server for an evening costs pocket change.

Before installing

Take a fresh Ubuntu 22.04 or 24.04 LTS or Debian 12 and do the basic hardening first: updates, key-based sign-in, a separate user, a firewall. All of it is in The first 10 steps after buying a VPS. A hosting control panel is usually unnecessary on a container server; why is explained in Server control panels.

Installing from the official repository

The docker.io package from the Ubuntu repository often lags behind the current version and does not always include Compose. Installing from Docker's own repository is more reliable. The commands for Ubuntu, following the official documentation:

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

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
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

For Debian the commands are the same, except that linux/ubuntu in the URLs becomes linux/debian, and VERSION_CODENAME is used instead of UBUNTU_CODENAME. Check the installation:

sudo docker run hello-world
docker compose version

There is also a one-command installer at get.docker.com, but Docker's own documentation advises against it for production servers: it installs many packages without asking and always takes the latest version.

The docker group. To avoid typing sudo before every command, the user is added to the docker group: sudo usermod -aG docker $USER, then sign in again. Keep in mind that this equals root rights: a member of the group can start a container with access to the server's entire file system. Add only your own working account to it.

A first Docker Compose project

Separate docker run commands with a dozen options are quickly forgotten. It is more convenient to describe the project in a compose.yaml file in its own directory, for example /opt/app. Here is a web application with a PostgreSQL database:

services:
  app:
    image: ghcr.io/example/app:1.4.2
    restart: unless-stopped
    environment:
      DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      - db
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data

volumes:
  db-data:

Put the password next to it in a .env file with the line DB_PASSWORD=... and make it unreadable for other users: chmod 600 .env. Start with docker compose up -d, follow the log with docker compose logs -f app, stop with docker compose down.

Three things in this example matter:

  • restart: unless-stopped — the containers come back up after a server reboot;
  • the database has no ports section: the application reaches it by the name db on the project's internal network, and it is not reachable from outside;
  • the application port is published only on 127.0.0.1, and nginx or Caddy with a TLS certificate serves it to the outside world.

Ports and the firewall

This is the main trap for beginners. When a container publishes a port as "5432:5432", Docker adds iptables rules itself, and that port is opened to the internet regardless of your ufw or firewalld rules. Docker's documentation warns about this directly: published container ports are not subject to the firewall rules. This is exactly how PostgreSQL, MongoDB and Redis databases without a password most often end up on the internet.

The rule is simple: publish externally only what should be reachable by everyone — usually ports 80 and 443 of the reverse proxy. Everything else goes either without a ports section or bound to 127.0.0.1. You can check what the server is actually listening on with ss -tlnp, and from outside, from another computer, with nc -zv server-IP 5432.

Logs and disk space

By default Docker writes container output to JSON files with no size limit. A chatty application fills the disk in a couple of months, and the server stops working. Limit logs for all containers in /etc/docker/daemon.json:

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

Then run sudo systemctl restart docker. The setting applies to containers created after it, so recreate your projects: docker compose up -d --force-recreate.

The second disk hog is old images. docker system df shows how much space is used, and docker image prune -a removes unused images. Do not run docker system prune --volumes unless you understand it: it also deletes the volumes of stopped projects along with their data.

Where data lives and how to back it up

Anything the application wrote inside a container disappears when the container is recreated. Only what lives in volumes (volumes) or in mounted server directories survives. Before running any image, check its documentation for which directories need to go into a volume: for PostgreSQL it is /var/lib/postgresql/data, other applications have their own paths.

Copying database files while the database is running is unreliable. Take a dump through the container itself:

docker compose exec -T db pg_dump -U app app | gzip > /backup/app-$(date +%F).sql.gz

Add this command to cron and send the copies off the server, together with compose.yaml and .env. How to set up external storage and test the copies is covered in VPS backups.

Updating containers

Pin a specific image version in compose.yaml (postgres:16, app:1.4.2) rather than latest: then an update happens when you plan it, not on a random restart. The update procedure:

  1. take a database dump;
  2. change the version in compose.yaml;
  3. docker compose pull and docker compose up -d;
  4. check the log and that the application works, then remove the old image.

Major database versions, for example PostgreSQL 16 → 17, cannot be updated this way: the new version needs the data moved over with a dump and restore. Update the server's system and Docker itself with the usual apt upgrade.

Where to go next

Once a server hosts several projects, it is worth adding a reverse proxy that obtains certificates on its own, plus uptime monitoring. A bot in Python or Node.js in a container needs only a small server; details in VPS for a Telegram bot. If containers multiply and one server is no longer enough, the next step is several servers under an orchestrator; plans are in VPS for Kubernetes. For automation and CI in containers there are the VPS for n8n and VPS for GitLab selections.

FAQ

Can I run Docker on any VPS?

You need KVM or another full virtualization with its own kernel. On OpenVZ and LXC the kernel is shared with other customers, and Docker either does not work there or works with restrictions.

How much memory does a VPS for Docker need?

One or two light containers fit in 1 GB. For a website with a database and a reverse proxy, take 2 cores and 2 GB; for several projects with PostgreSQL and Redis, 4 GB. Disk: at least 30 GB on NVMe.

How do I install Docker on Ubuntu?

Add the official Docker repository and install the docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin and docker-compose-plugin packages. Check the installation with sudo docker run hello-world.

Why does ufw not close a container port?

Docker adds its own iptables rules for published ports, and they apply regardless of ufw. Do not publish database ports, and bind application ports to 127.0.0.1 and serve them through a reverse proxy.

Why did Docker fill up the whole disk?

Most often the culprits are container logs, which have no size limit by default, and old images. Set max-size and max-file in /etc/docker/daemon.json and periodically remove unused images with docker image prune -a.

Will data be lost if I delete a container?

Yes, if it was stored inside the container. Only data in volumes and mounted server directories survives. Additionally back up databases as dumps stored off the server.

Plans on this topic

VPS for CI/CD runnersBest VPS hosting 2026

More in the guide

  • How to move a website from shared hosting to a VPSThe move itself takes a couple of hours; the mistakes usually happen around it: a forgotten cron job, .htaccess rules that nginx does not read, an AAAA record with the old address, or mail that disappeared along with the IP change. Below is the order of steps with commands and checks for a PHP and MySQL site.
  • Server control panels: ISPmanager, FASTPANEL, aaPanelA panel turns a VPS into the kind of dashboard you know from shared hosting: sites, databases, mail and certificates are set up with a few clicks instead of editing config files. The three panels most often installed on Russian and budget international servers are ISPmanager, FASTPANEL and aaPanel. They differ in price, memory requirements and how much of the server they take over.
  • Windows VPS for 1CA rented server for 1C saves you from the office PC under a desk that nobody updates or backs up. But 1C on a VPS has its own quirks: the software licence is tied to the parameters of the virtual machine, users need both 1C and Windows licences, and core speed matters more than core count. Here is how to put together a 1C server for a small company.
  • Windows VPS: licensing, RDP and secure sign-inA Windows server costs more than Linux not only because of memory: the price includes a licence, and how it is arranged decides whether you are compliant and how many people can connect. An exposed RDP port is also the most common way such servers get hacked. Here are both topics.
  • When to move from shared hosting to a VPSA VPS does not make a site faster by itself: it gives you resources and freedom, and with them the job of running a server. Here is how to tell that hosting has become too small, when the problem can be solved without moving, and how to migrate a site so visitors notice nothing.
  • VPS backups: strategies and toolsOn a VPS, backups are your job, even if the plan says "backups included". We go through what exactly to back up, why a host snapshot is not enough, how to set up restic or BorgBackup in half an hour, and how to make sure you can actually restore from a backup.
  • First 10 steps after buying a VPS: securityBots start guessing passwords on a new server within minutes of it getting a public IP. Below are ten steps that close the most common holes in about an hour: commands for Ubuntu and Debian, the differences for AlmaLinux and Rocky Linux, and the checks that keep you from locking yourself out of your own server.
  • How to choose a country for your serverPut the server where your visitors are. For an audience across Europe, Germany, the Netherlands and Finland are convenient; for North America, the US East Coast. If you serve EU users, keeping the data in the EU makes GDPR simpler. Price hardly decides it: at the same host a server in Frankfurt, Amsterdam or New York usually costs the same, and only Asia and Australia are noticeably more expensive.
  • Hourly billing: when it pays offHourly billing pays off if you need the server for less than three weeks a month: for a test, a build, a one-off heavy job. At most hosts an hour costs exactly the monthly price divided by 730 hours, so over a full month you hardly overpay. The overpayment hides elsewhere: hourly plans are dearer on average, and for a server that runs all year, monthly billing or a year paid in advance usually comes out cheaper.
  • How much RAM and how many cores a website needsMost websites are fine with 2 GB of memory and one or two cores; a shop with thousands of products needs 4 GB and two cores. Memory matters more than cores: when it runs out, the site slows down or crashes, while an extra core without memory adds almost nothing. Below I show how to work out the memory for your site and how to see what it actually uses.
  • KVM or OpenVZ: which to chooseIn 2026 KVM is almost always the right pick: it costs a dollar or two more per month than OpenVZ, but everything runs on it, from Docker to Windows. OpenVZ makes sense in one narrow case, explained below, and at the end you will find the commands to check your own server in a minute.
  • NVMe or SSD: does it matter for a websiteFor a small site the difference between NVMe and SSD is barely noticeable, because pages are served from memory rather than from disk. It shows up in shops and sites with a large database. At the same host NVMe costs only about $0.50–1 a month more, and sometimes less, so what usually decides it is not the disk type but its size and how the host has limited it.
  • What is a VPS, in plain EnglishA VPS is a slice of a powerful physical server that you rent and that behaves like a separate computer, with its own operating system, its own IP address and full control. Below is how it differs from shared hosting, who needs one, what it costs and what to check right after you buy it.
  • VPS for a Telegram bot: what the bot needs and how to pick a planA bot with a menu and a few commands runs fine on the cheapest server, while a bot with broadcasts, files and a database hits completely different limits. Here is what a bot really consumes, which Telegram limits shape the choice of server and how to avoid overpaying.
  • How to test VPS ping and speed before you payThe numbers in a plan do not tell you the latency to your users or how fast the disk really is. Most of this can be measured before you pay, the rest in the first hour after launch. Here are the tools and how to read the results.
  • Corporate network on a VPS: remote access to the officeA rented server can become the hub of a company's private network: remote employees and branch offices connect through it to the ERP, file server, CRM and Git. Here are the common layouts, protocols, server requirements and security basics.
  • How to choose a VPS: the 7 specs that matterTwo plans with the same "2 cores, 4 GB, 50 GB" can differ several times in speed and twice in price a year later. Here is what stands behind each line of a VPS plan and what to check before you pay.
  • VPS vs VDS: is there a difference and what actually mattersIn most markets VPS and VDS mean the same thing: a virtual server. The difference that really affects your work is hidden not in the name but in the virtualization type and whether resources are guaranteed.