This guide contains common Docker commands and practical examples useful for managing Docker on a Linux server or VPS.
1. Check whether Docker is installed
Check Docker Compose:
Check Docker service status:
1
| sudo systemctl status docker
|
2. Install Docker on Ubuntu
Update packages:
1 2
| sudo apt update sudo apt upgrade -y
|
Install required packages:
1
| sudo apt install -y ca-certificates curl
|
Create the Docker keyring directory:
1
| sudo install -m 0755 -d /etc/apt/keyrings
|
Download Docker’s official GPG key:
1
| sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
Set permissions:
1
| sudo chmod a+r /etc/apt/keyrings/docker.asc
|
Add the Docker repository:
1
| echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
Update package information:
Install Docker Engine and Docker Compose:
1
| sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
Test Docker:
1
| sudo docker run hello-world
|
3. Start, stop, and enable Docker
Start Docker:
1
| sudo systemctl start docker
|
Stop Docker:
1
| sudo systemctl stop docker
|
Restart Docker:
1
| sudo systemctl restart docker
|
Enable Docker at boot:
1
| sudo systemctl enable docker
|
Check status:
1
| sudo systemctl status docker
|
4. Run Docker without sudo
Add your current user to the docker group:
1
| sudo usermod -aG docker $USER
|
Then log out and log back in.
Check membership:
Test:
Membership in the docker group effectively grants root-level privileges on the host. Only trusted users should be added to this group.
5. List containers
Show running containers:
Show all containers:
Alternative syntax:
6. Run a container
Run Nginx:
Run in detached mode:
Run with a custom name:
1
| docker run -d --name web nginx
|
Expose a port:
1
| docker run -d --name web -p 8080:80 nginx
|
This maps:
1
| host port 8080 -> container port 80
|
Open:
7. Start, stop, restart, and remove containers
Stop a container:
Start it:
Restart it:
Remove it:
Force-remove a running container:
8. View container logs
Show logs:
Follow logs:
Show the last 100 lines:
1
| docker logs --tail 100 web
|
Show timestamps:
9. Execute commands inside a container
Open a shell:
1
| docker exec -it web bash
|
If Bash is not available:
Run a single command:
10. Inspect a container
Get the container IP:
1
| docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
|
Show container resource usage:
11. List Docker images
Alternative:
12. Pull an image
Specific version:
13. Remove Docker images
Remove an image:
Force removal:
Remove dangling images:
14. Build an image
From a directory containing a Dockerfile:
With a version tag:
1
| docker build -t myapp:1.0.0 .
|
List images afterward:
15. Tag an image
1
| docker tag myapp:1.0.0 username/myapp:1.0.0
|
Example for a registry:
1
| docker tag myapp:1.0.0 registry.example.com/myapp:1.0.0
|
16. Docker login and logout
Login to a container registry:
Login to a specific registry:
1
| docker login registry.example.com
|
Logout:
17. Push an image
1
| docker push username/myapp:1.0.0
|
Or:
1
| docker push registry.example.com/myapp:1.0.0
|
18. Environment variables
Pass an environment variable:
1
| docker run -e APP_ENV=production myapp
|
Multiple variables:
1
| docker run -e APP_ENV=production -e PORT=8080 myapp
|
Load variables from a file:
1
| docker run --env-file .env myapp
|
Do not commit production secrets, passwords, API keys, or tokens to Git.
19. Volumes
List volumes:
Create a volume:
1
| docker volume create app-data
|
Inspect it:
1
| docker volume inspect app-data
|
Use it:
1
| docker run -d --name app -v app-data:/data myapp
|
Remove it:
1
| docker volume rm app-data
|
Remove unused volumes:
20. Bind mounts
Mount a host directory inside a container:
1
| docker run -d --name web -v /opt/app/data:/app/data myapp
|
Modern syntax:
1
| docker run -d --mount type=bind,source=/opt/app/data,target=/app/data myapp
|
21. Docker networks
List networks:
Create a network:
1
| docker network create app-network
|
Run a container on that network:
1
| docker run -d --name api --network app-network myapi
|
Connect an existing container:
1
| docker network connect app-network web
|
Disconnect:
1
| docker network disconnect app-network web
|
Remove a network:
1
| docker network rm app-network
|
22. Container DNS between services
Containers on the same user-defined Docker network can communicate using container names.
Example:
Instead of:
Inside a container, localhost refers to that container itself.
23. Restart policies
Automatically restart a container:
1
| docker run -d --restart unless-stopped --name web nginx
|
Common policies:
1 2 3 4
| no always unless-stopped on-failure
|
For long-running VPS services, this is commonly useful:
24. Docker Compose basics
Example compose.yaml:
1 2 3 4 5 6
| services: web: image: nginx:latest ports: - "8080:80" restart: unless-stopped
|
Start services:
Start in background:
Stop and remove containers:
Restart:
25. Docker Compose build
Build services:
Build without cache:
1
| docker compose build --no-cache
|
Build and start:
1
| docker compose up -d --build
|
26. Docker Compose status
List services:
Show logs:
Follow logs:
Follow logs for one service:
1
| docker compose logs -f api
|
27. Docker Compose pull and update
Pull newer images:
Recreate services:
Typical update workflow:
1 2
| docker compose pull docker compose up -d
|
28. Docker Compose environment file
Example .env:
1 2 3
| APP_ENV=production POSTGRES_DB=appdb POSTGRES_USER=appuser
|
Example Compose usage:
1 2 3 4 5 6 7 8 9 10 11
| services: api: image: myapi environment: APP_ENV: ${APP_ENV}
postgres: image: postgres:17 environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER}
|
Keep secret .env files out of Git.
Example .gitignore:
29. View Docker disk usage
Detailed view:
30. Clean unused Docker resources
Remove stopped containers:
Remove unused images:
Remove unused networks:
Remove unused volumes:
Remove most unused Docker resources:
Also remove unused images not referenced by containers:
Be careful with cleanup commands on production servers.
31. Check container resource usage
Live CPU and memory usage:
For a single container:
32. Copy files between host and container
Copy from host to container:
1
| docker cp file.txt web:/tmp/file.txt
|
Copy from container to host:
1
| docker cp web:/tmp/file.txt ./file.txt
|
33. Check a container’s ports
Or:
34. Check container processes
35. Rename a container
1
| docker rename old-name new-name
|
36. Health checks
Check container health:
1
| docker inspect --format='{{json .State.Health}}' container-name
|
Example Compose health check:
1 2 3 4 5 6 7 8
| services: web: image: nginx healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 30s timeout: 5s retries: 3
|
37. View Docker events
Useful for debugging container starts, stops, restarts, and network events.
38. Docker daemon logs
Check Docker service logs:
1
| sudo journalctl -u docker
|
Follow them:
1
| sudo journalctl -u docker -f
|
39. Common troubleshooting commands
Check running containers:
Check stopped containers:
Check logs:
1
| docker logs container-name
|
Inspect container:
1
| docker inspect container-name
|
Check networks:
Check ports:
Check Docker disk usage:
Check daemon status:
1
| sudo systemctl status docker
|
40. Example production directory structure
A simple application deployment directory can look like:
1 2 3 4 5 6
| /opt/app ├── compose.yaml ├── .env ├── config/ ├── data/ └── backups/
|
Recommended ownership:
1
| sudo chown -R deployuser:deployuser /opt/app
|
41. Example multi-service Compose file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| services: api: image: registry.example.com/api:latest restart: unless-stopped env_file: - .env networks: - internal
web: image: registry.example.com/web:latest restart: unless-stopped networks: - internal
postgres: image: postgres:17 restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres-data:/var/lib/postgresql/data networks: - internal
networks: internal:
volumes: postgres-data:
|
Start it:
Check status:
Follow logs:
42. Update a Dockerized application
A common deployment flow:
1 2 3 4
| cd /opt/app docker compose pull docker compose up -d docker image prune
|
If images are built locally:
1 2
| cd /opt/app docker compose up -d --build
|
43. Backup a Docker volume
One simple approach:
1
| docker run --rm -v app-data:/data -v $(pwd):/backup alpine tar czf /backup/app-data-backup.tar.gz -C /data .
|
Restore:
1
| docker run --rm -v app-data:/data -v $(pwd):/backup alpine tar xzf /backup/app-data-backup.tar.gz -C /data
|
For databases such as PostgreSQL, prefer database-aware backup tools such as pg_dump.
44. Useful commands cheat sheet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| docker ps docker ps -a docker images docker logs -f container-name docker exec -it container-name bash docker inspect container-name docker stats docker network ls docker volume ls docker system df docker compose ps docker compose logs -f docker compose pull docker compose up -d docker compose up -d --build docker compose down
|
Security recommendations
For Docker on a public VPS:
- do not expose database ports publicly unless necessary;
- expose only required ports;
- use a firewall such as UFW;
- avoid running containers as
root when possible;
- do not mount the Docker socket into containers unless absolutely necessary;
- keep Docker and the host OS updated;
- use specific image versions instead of relying on
latest for production;
- keep secrets outside Git;
- use read-only mounts where possible;
- configure restart policies;
- back up persistent volumes and databases;
- periodically review unused images, containers, networks, and volumes;
- only add trusted users to the
docker group.