Docker - Basic Administration Guide

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

1
docker --version

Check Docker Compose:

1
docker compose version

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:

1
sudo apt update

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:

1
groups

Test:

1
docker ps

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:

1
docker ps

Show all containers:

1
docker ps -a

Alternative syntax:

1
docker container ls
1
docker container ls -a

6. Run a container

Run Nginx:

1
docker run nginx

Run in detached mode:

1
docker run -d nginx

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:

1
http://SERVER_IP:8080

7. Start, stop, restart, and remove containers

Stop a container:

1
docker stop web

Start it:

1
docker start web

Restart it:

1
docker restart web

Remove it:

1
docker rm web

Force-remove a running container:

1
docker rm -f web

8. View container logs

Show logs:

1
docker logs web

Follow logs:

1
docker logs -f web

Show the last 100 lines:

1
docker logs --tail 100 web

Show timestamps:

1
docker logs -t web

9. Execute commands inside a container

Open a shell:

1
docker exec -it web bash

If Bash is not available:

1
docker exec -it web sh

Run a single command:

1
docker exec web ls -la

10. Inspect a container

1
docker inspect web

Get the container IP:

1
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web

Show container resource usage:

1
docker stats

11. List Docker images

1
docker images

Alternative:

1
docker image ls

12. Pull an image

1
docker pull nginx

Specific version:

1
docker pull nginx:1.27

13. Remove Docker images

Remove an image:

1
docker rmi nginx

Force removal:

1
docker rmi -f nginx

Remove dangling images:

1
docker image prune

14. Build an image

From a directory containing a Dockerfile:

1
docker build -t myapp .

With a version tag:

1
docker build -t myapp:1.0.0 .

List images afterward:

1
docker images

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:

1
docker login

Login to a specific registry:

1
docker login registry.example.com

Logout:

1
docker 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:

1
docker volume ls

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:

1
docker volume prune

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:

1
docker network ls

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:

1
api -> postgres:5432

Instead of:

1
api -> localhost:5432

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:

1
unless-stopped

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:

1
docker compose up

Start in background:

1
docker compose up -d

Stop and remove containers:

1
docker compose down

Restart:

1
docker compose restart

25. Docker Compose build

Build services:

1
docker compose build

Build without cache:

1
docker compose build --no-cache

Build and start:

1
docker compose up -d --build

26. Docker Compose status

List services:

1
docker compose ps

Show logs:

1
docker compose logs

Follow logs:

1
docker compose logs -f

Follow logs for one service:

1
docker compose logs -f api

27. Docker Compose pull and update

Pull newer images:

1
docker compose pull

Recreate services:

1
docker compose up -d

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:

1
2
.env
.env.production

29. View Docker disk usage

1
docker system df

Detailed view:

1
docker system df -v

30. Clean unused Docker resources

Remove stopped containers:

1
docker container prune

Remove unused images:

1
docker image prune

Remove unused networks:

1
docker network prune

Remove unused volumes:

1
docker volume prune

Remove most unused Docker resources:

1
docker system prune

Also remove unused images not referenced by containers:

1
docker system prune -a

Be careful with cleanup commands on production servers.


31. Check container resource usage

Live CPU and memory usage:

1
docker stats

For a single container:

1
docker stats web

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

1
docker port web

Or:

1
docker ps

34. Check container processes

1
docker top web

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

1
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:

1
docker ps

Check stopped containers:

1
docker ps -a

Check logs:

1
docker logs container-name

Inspect container:

1
docker inspect container-name

Check networks:

1
docker network ls

Check ports:

1
sudo ss -tulpn

Check Docker disk usage:

1
docker system df

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:

1
docker compose up -d

Check status:

1
docker compose ps

Follow logs:

1
docker compose logs -f

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.