ThisCalculator

Everyday

How to Host Docker Containers on a VPS

Updated · Standard formula, shown below

This guide walks you through deploying Docker containers on a virtual private server (VPS), from initial setup to keeping containers running smoothly. You’ll learn how to install Docker, run your first container, manage ports and volumes, and use Docker Compose for multi-container apps—everything you need to move from a local dev environment to a live server.

What You’ll Need

  • A VPS with a public IP address (any provider: DigitalOcean, Linode, AWS EC2, Hetzner, etc.) running Ubuntu 22.04 or 24.04 LTS (other distros work, but commands may differ).
  • SSH access to the server (root or a user with sudo privileges).
  • A domain name pointing to your VPS IP if you plan to serve web traffic (optional but recommended).
  • Basic familiarity with the Linux command line.

Step-by-Step

  1. Connect to your VPS via SSH. Open a terminal and run: ssh user@your_server_ip. If you’re using a key pair, make sure the private key is available.
  2. Update the system. Run sudo apt update && sudo apt upgrade -y to get the latest package lists and security patches.
  3. Install Docker using the official repository. Run the following commands one by one:
    sudo apt 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 "$VERSION_CODENAME") stable" | \
      sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update
        
  4. Install Docker Engine and related tools. Run sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin. This installs the daemon, CLI, and Compose plugin.
  5. Verify Docker is running. Execute sudo systemctl status docker (should show “active (running)”) or simply sudo docker --version.
  6. Add your user to the docker group. Run sudo usermod -aG docker $USER to avoid typing sudo for every Docker command. Log out and back in for the change to take effect.
  7. Test with a simple container. Run docker run hello-world. If you see the “Hello from Docker!” message, everything works.
  8. Run your first real container. For example, to run an Nginx web server: docker run -d --name web -p 80:80 nginx:alpine. The -d flag runs it detached, and -p 80:80 maps the container’s port 80 to the host’s port 80.
  9. Check that it’s accessible. Open your browser and visit http://your_server_ip. You should see the Nginx welcome page.
  10. Manage containers. Use docker ps to list running containers, docker logs web to view logs, docker stop web to stop it, and docker rm web to remove it.
  11. Persist data with volumes. When a container is removed, its data is lost. To keep data, create a volume: docker volume create mydata, then mount it: docker run -d --name db -v mydata:/var/lib/postgresql/data postgres:16. This way the database survives container recreation.
  12. Use Docker Compose for multi-container apps. Create a docker-compose.yml file in a directory. For a simple app with Nginx and Redis:
    services:
      web:
        image: nginx:alpine
        ports:
          - "80:80"
      redis:
        image: redis:alpine
        

    Then run docker compose up -d to start everything. This is far easier than managing individual docker run commands.

  13. Set up a firewall. If you’re using UFW, allow SSH and HTTP/HTTPS: sudo ufw allow OpenSSH, sudo ufw allow 80, sudo ufw allow 443, then enable with sudo ufw enable. Be careful not to lock yourself out—always allow SSH first.
  14. Enable Docker to start on boot. Run sudo systemctl enable docker to ensure the daemon starts automatically after a reboot.
  15. Keep Docker updated. Regularly run sudo apt update && sudo apt upgrade -y to get security patches for Docker itself.

Common Mistakes

  • Forgetting to map ports. If you can’t reach your container, check that you used -p host_port:container_port. The container’s internal port is not automatically exposed.
  • Running containers as root. Many official images support a non-root user. Use --user or set USER in your Dockerfile to reduce security risks.
  • Not using volumes for databases. If you don’t mount a volume, deleting the container deletes your data.
  • Binding to port 80 without a firewall. Your container might be exposed to the internet even if you think it’s private. Always configure a firewall.
  • Using latest tags in production. Tags like nginx:latest change over time and can break your setup. Pin to a specific version like nginx:1.27.0.

Tips

  • Use Docker Compose from the start. Even for a single container, having a docker-compose.yml makes it easy to recreate and document your setup.
  • Set restart policies. Add restart: unless-stopped to your compose file or --restart unless-stopped to docker run so containers come back after a reboot or crash.
  • Monitor resource usage. Use docker stats to see CPU and memory usage per container. This helps you spot leaks or misconfigurations.
  • Use named volumes over bind mounts. Named volumes are easier to back up and move between hosts.
  • Keep images small. Prefer Alpine-based images when possible—they reduce disk usage and attack surface.
  • Set up a reverse proxy. For web apps, use Nginx or Traefik as a reverse proxy to handle SSL and route traffic to multiple containers on different ports.

Troubleshooting

  • Docker daemon not starting. Check sudo systemctl status docker for errors. Common causes: missing kernel modules or a full disk. Run df -h to check disk space and sudo systemctl restart docker.
  • Port already in use. If docker run -p 80:80 fails with “address already in use”, another process (or container) is using port 80. Use sudo lsof -i :80 to find it and stop it or change the host port.
  • Container exits immediately. Run docker logs container_name to see the error. Often it’s a missing configuration or the process fails because it has no terminal. Use -it for interactive processes or check the image’s documentation.
  • Cannot connect to the internet from inside a container. Check your host’s network and DNS. Try docker run --rm alpine ping 8.8.8.8; if that works but ping google.com fails, your DNS is broken—edit /etc/docker/daemon.json to set "dns": ["8.8.8.8"] and restart Docker.
  • Permission denied when running Docker commands. You haven’t added your user to the docker group or haven’t logged out/in after doing so. Use sudo as a temporary workaround.

Frequently Asked Questions

Do I need a VPS with a lot of RAM?

It depends on your containers. A basic Nginx container uses about 50 MB. A small Node.js app might use 200 MB. For most small projects, 1 GB RAM is enough. For databases or multiple services, go with 2 GB or more.

Can I host multiple websites on one VPS using Docker?

Yes. Run each site in its own container, map them to different host ports (e.g., 8080, 8081), and use a reverse proxy like Nginx or Traefik to route domain names to the correct container.

How do I update a running container to a newer image?

Pull the new image (docker pull image:tag), stop and remove the old container (docker stop name && docker rm name), then run a new container with the same options. With Compose, just run docker compose pull and docker compose up -d.

Is it safe to use Docker on a public-facing VPS?

Yes, if you follow security best practices: keep Docker updated, run containers as non-root, use a firewall, and avoid exposing the Docker daemon socket (port 2375) to the internet.

What’s the difference between an image and a container?

An image is a read-only template with the application and its dependencies. A container is a running instance of that image. You can have many containers from the same image.

How do I back up data from a Docker volume?

Use a temporary container to archive the volume: docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar czf /backup/mydata.tar.gz -C /data .. This creates a tar file in your current directory.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.