How to install Docker on a VPS and run your first container
Docker packages an app and everything it needs into a container, so it runs the same way everywhere. It is handy on a VPS for running several apps without them clashing. The steps below follow Docker's official convenience script for Ubuntu and Debian. Commands may differ on other distributions, and the official Docker docs are the best reference for the latest method.
Before you start
- A VPS with a non-root sudo user
- At least 1 to 2 GB RAM, more if you run many containers
- Updated packages, with sudo apt update and sudo apt upgrade
Install Docker
- curl -fsSL https://get.docker.com -o get-docker.sh
- sudo sh get-docker.sh
- sudo systemctl enable --now docker
- sudo docker run hello-world
If you see a welcome message, Docker works. Reading a script before running it is good practice, so open get-docker.sh first if you want to check it.
Run Docker without sudo
- sudo usermod -aG docker $USER
- Log out and back in
- docker ps
Members of the docker group effectively have root power, so only add trusted users.
Everyday commands
- docker ps lists running containers, and docker ps -a lists all
- docker logs -f NAME follows a container's logs
- docker stop NAME and docker start NAME control it
- docker rm NAME deletes a stopped container
- docker images lists downloaded images
- docker system prune clears unused data, so read the prompt before confirming
Run a real example
- docker run -d --name web -p 8080:80 --restart unless-stopped nginx
- Visit http://YOUR_SERVER_IP:8080
- If a firewall is on, allow the port with sudo ufw allow 8080/tcp
The restart policy brings the container back after a reboot.
Docker Compose
Compose describes several containers in one docker-compose.yml file. Newer Docker installs include it as a plugin, so run docker compose up -d and docker compose down.
Tips
- Keep data in volumes with -v, or it disappears with the container
- Docker can fill the disk over time, so check df -h and docker system df
- Published ports can bypass UFW rules in some setups, so bind private services to 127.0.0.1, for example -p 127.0.0.1:8080:80
Need help? Our support team is on Discord and email.