Installing Docker on a VPS: a step-by-step guide for web applications

Docker has become the de facto standard for packaging and running web applications. It lets you isolate services, simplify deployment, and eliminate the classic problem of something working locally but failing on the server. A VPS server is the ideal environment for Docker: you get full root access, choose your operating system, and manage resources without the restrictions typical of shared hosting. In this article we will walk through how to install Docker on a VPS running Ubuntu and launch your first web application.
Why a VPS is better suited for Docker than regular hosting
Shared hosting does not provide access to the operating system kernel, yet Docker requires exactly that — to manage namespaces and control groups. On a VPS you work with dedicated resources and full control over the system. This means you can install any version of Docker Engine, use Docker Compose, and configure network bridges to suit your stack. When choosing a plan on NodexGo, pay attention to the amount of RAM: for most web applications running several containers, 2 GB is enough to start, but the more complex the stack, the more memory you will need.
Preparing the server before installation
After gaining access to your VPS, the first thing to do is update the system packages with the command apt update && apt upgrade -y. Make sure curl and the gnupg utility are installed on the server — they will be needed to add the official Docker repository. It is also recommended to create a non-privileged user right away and add them to the sudo group so you are not constantly working as root. This is a basic security practice that is relevant regardless of what software you plan to run.
Installing Docker Engine on Ubuntu
The official way to install Docker involves connecting the proprietary repository from Docker Inc. First, add the repository GPG key: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg. Then add the repository itself to sources.list and run apt update && apt install docker-ce docker-ce-cli containerd.io. After installation, verify that everything is working with the command docker run hello-world — if the container starts and prints a greeting, everything is configured correctly. Do not forget to add your user to the docker group with usermod -aG docker $USER so you do not have to use sudo every time you call Docker.
Installing Docker Compose and running your first application
Docker Compose lets you describe multi-container applications in a single docker-compose.yml file and start the entire stack with one command. Starting with Docker version 20.10, the Compose plugin is included in the Docker CLI and installed alongside it — check its availability with docker compose version. For a typical web application, the Compose file will contain at least two services: the application itself and a database. The command docker compose up -d will start all containers in the background, while docker compose logs lets you monitor their output.
A minimal docker-compose.yml example for a Node.js application with PostgreSQL looks like this: you define an app service specifying either an image or a path to a Dockerfile, set environment variables via env_file, and declare a dependency on the db service. For the db service you use the official postgres image, set the POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB variables, and mount the data into a named volume so it persists between container restarts.
Configuring a reverse proxy and HTTPS
In a production environment, containers should not be exposed directly to the internet. The correct approach is to place a reverse proxy in front of them — for example Nginx or Traefik — which accepts incoming connections on ports 80 and 443 and forwards traffic to the appropriate container. Traefik is especially convenient when used with Docker: it automatically discovers containers through the Docker API and configures routing based on labels in docker-compose.yml. For obtaining Let's Encrypt TLS certificates, Traefik has built-in support for the ACME protocol — simply specify an email address and enable the corresponding resolver.
Security and performance tips
Never run containers with the --privileged flag unless absolutely necessary — it gives the container nearly full access to the host. Limit container resources using the mem_limit and cpus parameters in the Compose file so that a single service cannot consume all the VPS memory. Regularly update base images and scan them for vulnerabilities using docker scout or Trivy. Container logs are stored on the host by default and can take up significant disk space — configure log rotation via the logging parameter in Compose or globally in /etc/docker/daemon.json.
If you plan to deploy multiple projects on a single VPS, use separate Docker networks for each stack — this isolates services and prevents accidental interaction between projects. Monitoring containers is conveniently done with a combination of cAdvisor and Prometheus: they provide detailed CPU, memory, and network statistics for each container.
Conclusion
Docker on a VPS means flexibility, reproducibility, and easy scalability for any web project. A properly configured stack consisting of Docker Compose, a reverse proxy, and automatic certificates turns a server into a reliable platform for deploying applications of any complexity. If you are looking for a VPS with full root access, a stable network, and the ability to choose the right configuration for your stack, consider the offerings from NodexGo — rent a server, install Docker following this guide, and launch your application today.