Skip to content
  • Independent cloud account marketplace
  • Options and USD prices shown before checkout
  • Support available before and after ordering
Developer Workflows

Running Docker on a Cloud VPS: Setup and Best Practices

Install Docker on a DigitalOcean, Hetzner, or BinaryLane VPS, lock down port publishing and the Docker socket, run a stack with Compose, and manage volumes, backups, and image updates.

A single VPS running Docker is the most common way small teams ship web applications, and it works well right up to the point where nobody remembers how the containers were started. This guide covers installing Docker on a DigitalOcean Droplet, a Hetzner Cloud server, or a BinaryLane cloud server, the security defaults that matter on a public host, how to run a stack with Docker Compose so it survives a reboot, and how to handle images, volumes, and updates without turning the server into a snowflake.

Sizing the host and picking an image

Docker itself is light, but the containers are not. Budget RAM per container the same way you would for the process running natively, then add headroom for the kernel and for image builds if you build on the server. A general purpose plan with two or more vCPUs and enough memory for the heaviest container is the usual starting point; databases in containers benefit from the same memory optimized plans they would need outside Docker. Disk fills faster than expected because every image layer, stopped container, and build cache stays on disk until pruned, so pick a plan with room to spare or attach a block storage volume for the Docker data directory.

Start from a plain Ubuntu LTS or Debian image. DigitalOcean offers a Docker one-click image in its marketplace and Hetzner has a Docker CE app image; both are convenient but you still own the updates afterwards, and installing from Docker’s own package repository on a clean image keeps you on current releases. BinaryLane provides standard distribution images from which the same installation steps apply.

Installing Docker and locking down the defaults

Install Docker Engine and the Compose plugin from Docker’s official apt repository rather than the distribution’s older package, then enable the service so it starts on boot. Add your non-root user to the docker group only if you understand that membership is equivalent to root on the host, since anyone who can start a container can mount the root filesystem. For servers where several people log in, prefer running Docker commands through sudo or use rootless mode.

The default that bites people on a public VPS is port publishing. When a Compose file publishes a container port, Docker inserts its own iptables rules that take effect before ufw or firewalld rules, so a database published on port 5432 is reachable from the internet even if the host firewall says otherwise. The fix is to bind published ports to the loopback address or the private network address explicitly, and to rely on the provider firewall (DigitalOcean Cloud Firewalls, Hetzner Cloud Firewalls, BinaryLane’s firewall rules) as the outer layer that Docker cannot rewrite. Only a reverse proxy should publish on the public interface.

Running a stack with Docker Compose

Describe the application as a Compose file kept in version control: one service per process, named volumes for anything that must persist, and a restart policy of unless-stopped so the stack comes back after a reboot or a Docker upgrade. Put secrets in an environment file that is excluded from the repository and readable only by the deploying user, or use Docker secrets if you run in Swarm mode. Pin image tags to a specific version rather than latest so a redeploy is reproducible and a rollback is a one line change.

Front the stack with a reverse proxy container that terminates TLS. Caddy, Traefik, and nginx with a certificate helper all obtain Let’s Encrypt certificates automatically, and they are the only containers that should publish ports 80 and 443. Internal services talk to each other over the default Compose network by service name, which keeps them off the public interface entirely.

  1. Clone the repository containing the Compose file to a directory owned by the deploy user.
  2. Create the environment file with database credentials and application secrets, and restrict its permissions.
  3. Pull the pinned images, then start the stack in detached mode.
  4. Check the container logs and the proxy’s certificate status before pointing DNS at the server.
  5. Record the exact commands in the repository README so the next person can repeat them.

Volumes, backups, and keeping images current

Anything a container writes that must outlive it belongs in a named volume or a bind mount to a known directory, never in the container’s writable layer. Back those locations up on a schedule: for databases, run a dump inside the container and copy the result out, since copying live database files under a running process produces corrupt backups. Provider snapshots on DigitalOcean, Hetzner, and BinaryLane capture the whole disk and are a good complement, but they are not a substitute for logical database dumps stored off the server.

Updates come in three layers and each needs a routine. The host operating system gets unattended security updates like any VPS. Docker Engine itself is updated through the package manager, which briefly restarts containers unless live restore is enabled. Application images are updated by bumping the pinned tag in the Compose file, pulling, and recreating the affected services; automated tools exist that watch for new tags, but on a production host a deliberate, tested bump is safer than surprise upgrades. Prune unused images and build cache regularly, because a full disk stops every container at once.

Layer How it is updated Risk to watch
Host OS Unattended security updates, occasional reboot Kernel updates require a reboot to apply
Docker Engine Package manager from Docker’s repository Containers restart unless live restore is on
Application images Bump pinned tag, pull, recreate service Breaking changes in the new image version
Data volumes Not updated; backed up and restored Backups taken while a database is writing

Knowing when one VPS is not enough

A single Docker host has no redundancy: a kernel panic, a full disk, or a bad deploy takes the whole application down. That is an acceptable trade for many internal tools and early stage products, and the fix for most reliability problems is still monitoring plus backups rather than an orchestrator. The signs that you have outgrown the setup are needing zero downtime deploys, running the same containers on more than two hosts, or needing to scale one service independently of the rest. At that point, a managed Kubernetes offering such as DigitalOcean Kubernetes or a container platform like DigitalOcean App Platform removes the host maintenance entirely, at the cost of a steeper learning curve. Until then, keep the Compose file honest, keep the backups tested, and keep the host patched.

Where to go next

All three providers covered here run Docker well on their standard Linux images. The marketplace lists DigitalOcean accounts by Droplet limit, Hetzner accounts by server limit, and BinaryLane cloud accounts for Australian hosting.

Before you install Docker, work through the first cloud server checklist and the guide to firewalls, Fail2ban, and automatic updates. When the single host stops being enough, the comparison of managed Kubernetes across providers is the natural next read, and the Cloud Library hub lists everything else.

More from the Cloud Library

Telegram