Logo
Bearhost Logo

How to Install Docker on Your VPS

By Elliot, BearHost·

Docker lets you run applications in isolated containers, making deployment consistent and reproducible. This guide covers installation on Ubuntu/Debian.

Remove Old Docker Versions

sudo apt remove docker docker-engine docker.io containerd runc 2>/dev/null

Install Docker Engine

Add the Docker Repository

sudo apt update
sudo apt install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker

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

Verify Installation

sudo docker run hello-world

Run Docker Without Sudo

sudo usermod -aG docker $USER
newgrp docker
docker run hello-world

Log out and back in for the group change to take full effect.

Essential Docker Commands

| Command | Description | |---|---| | docker pull nginx | Download an image | | docker run -d -p 80:80 nginx | Run a container in the background | | docker ps | List running containers | | docker ps -a | List all containers | | docker stop CONTAINER_ID | Stop a container | | docker rm CONTAINER_ID | Remove a container | | docker logs CONTAINER_ID | View container logs | | docker exec -it CONTAINER_ID bash | Open a shell inside a container | | docker images | List downloaded images | | docker system prune -a | Remove all unused data |

Docker Compose

Docker Compose lets you define multi-container applications in a YAML file.

Nginx Example

Create a project directory and a docker-compose.yml:

mkdir ~/nginx-app && cd ~/nginx-app
nano docker-compose.yml
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    restart: unless-stopped
mkdir html
echo "<h1>Hello from Docker!</h1>" > html/index.html
docker compose up -d

WordPress with MySQL Example

services:
  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wppassword
    restart: unless-stopped

  wordpress:
    image: wordpress:latest
    depends_on:
      - db
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppassword
    volumes:
      - wp_data:/var/www/html
    restart: unless-stopped

volumes:
  db_data:
  wp_data:

Start with docker compose up -d and visit your VPS IP in a browser.

Docker Security Best Practices

  1. Run as non-root inside containers — use USER directive in Dockerfiles
  2. Set resource limits to prevent containers from consuming all resources:
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    
  3. Use read-only filesystems where possible: read_only: true
  4. Create custom networks instead of using the default bridge:
    networks:
      frontend:
      backend:
    
  5. Enable Docker Content Trust: export DOCKER_CONTENT_TRUST=1
  6. Keep images updated: docker compose pull && docker compose up -d

Logging Configuration

Prevent logs from filling your disk by adding to /etc/docker/daemon.json:

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

Restart Docker:

sudo systemctl restart docker

Useful Compose Commands

| Command | Description | |---|---| | docker compose up -d | Start all services in background | | docker compose down | Stop and remove all services | | docker compose logs -f | Follow logs for all services | | docker compose pull | Pull latest images | | docker compose restart | Restart all services |

Tags:#docker#containers#docker-compose#ubuntu#debian#devops#vps