# Docker Tutorial

![](https://s3.carens.dev/outline/uploads/c17bbc39-d0b7-4712-a623-413d732fde4e/ce9f9018-f169-42c2-a33f-614c08db47cd/Docker-Logo.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=xqLtTpLKf1IDk0NDEIVU%2F20261023%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261023T043000Z&X-Amz-Expires=86400&X-Amz-Signature=5fc9c50d635a70f5b5ca1108314df13aa67d9fd09e0a650a6779233ee2c9cc39&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject " =441x248")



---

### What is Docker?

* A tool for isolating an application into a prepared environment (image).
* Helps avoid the common issue of “it works on my local machine, but not on the server,” which usually stems from differences in tech stack versions.

### Uses of Docker

* Setting up consistent environments
* Avoiding dependency conflicts (e.g., if one server runs two programs—Program A uses DB version 1, while Program B uses the same DB but version 2)
* Deployment
* (Manual) Scaling


---

### Basic Components in Docker

* **Image** = the recipe or template for creating containers; defines the environment setup
* **Container** = the running instance created from an image
* **Volume** = used to store data
* **Network** = used for communication between containers


---

### How Docker Works

Diagram from the official documentation (<https://docs.docker.com/get-started/docker-overview/>)

 ![](https://s3.carens.dev/outline/uploads/c17bbc39-d0b7-4712-a623-413d732fde4e/e43435d4-0d14-476b-9c14-d2368a5d6c7a/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=xqLtTpLKf1IDk0NDEIVU%2F20261023%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261023T043000Z&X-Amz-Expires=86400&X-Amz-Signature=f3c9a5e9f9d34c36e7dad1d37a7878c100fe336ad0689191022d31c09d370b26&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

Docker daemon = the brain of Docker, responsible for processing all Docker actions


---

### Installing Docker

<https://docs.docker.com/engine/install/ubuntu/> (It's better to learn via CLI; if you need a UI, you can set up Portainer or use Docker Desktop)

Linux = can install Docker directly  
Windows & macOS require virtualization, WSL, Virtual Machine, etc.


---

### Differences Between Container and VM

| Container | VM  |
|-----------|-----|
| Uses the host OS directly | Uses a separate OS for each VM |
| Requires fewer resources | Requires more resources |
| Fast boot time | Slow boot time |

 ![](https://s3.carens.dev/outline/uploads/c17bbc39-d0b7-4712-a623-413d732fde4e/8be7ee9f-7ee8-4a35-9eb6-58ef9a94cabf/image%201.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=xqLtTpLKf1IDk0NDEIVU%2F20261023%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20261023T043000Z&X-Amz-Expires=86400&X-Amz-Signature=2339af04f5df15d3af665e612ab8071155b45c3269996388b9719271613811bc&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject " =1003x418")

### Common Docker Commands

* docker pull = downloads an image from a registry

```bash
# docker pull <image_name>
docker pull nginx
```

* docker run = runs an image as a container

```bash
# docker run <image_name>
docker run nginx

# Common flag options:

# -d = detach, run in the background
docker run -d nginx

# --name = assign a name to the created container
docker run --name my-nginx nginx

# -p = port mapping
# example: map container’s port 80 to host’s port 8080
docker run -p 8080:80 nginx

# --rm = remove the container when it stops
docker run --rm nginx

# -e = set environment variables accessible to the app
docker run -e MYVAR=root nginx

# --network = specify which network the container will join
docker run --network nginx-network nginx

# --restart = container restart policy
# no -> default, container won’t restart when stopped
# always -> always restart the container when it stops
# on-failure -> restart only if the container exits with an error
docker run --restart always nginx

# --memory = set memory usage limit
# --cpus = set CPU usage limit
docker run --memory 512m --cpus 1.5 nginx
```

* docker build = create an image from a Dockerfile

```bash
# -t <image_name>:<version> = assign a name and version to the image being built
# . (dot) at the end tells Docker where the Dockerfile is located
docker build -t my-app:1.0 .

# -f = specify a different Dockerfile
# by default, docker build looks for a file named "Dockerfile"
docker build -f custom.Dockerfile -t my-app .

# --build-arg = like -e on docker run, defines variables used in the Dockerfile
docker build --build-arg APP_ENV=production -t my-app .

# --no-cache = build without using cache
# by default, build uses cache to speed up subsequent builds
docker build --no-cache -t my-app .
```

* docker ps = view running containers

```bash
# -a = also show stopped containers
docker ps -a
```

* docker <container,image,network,volume> ls = list existing <container,image,network,volume>

```bash
# list existing containers
docker container ls

# list existing images
docker image ls

# list existing networks
docker network ls

# list existing volumes
docker volume ls
```

* docker system df = view Docker storage usage, usually shows reclaimable space (can be deleted to save storage)

```bash
docker system df

# example output:
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          29        6         10.28GB   7.843GB (76%)
Containers      6         4         150.3MB   148.9MB (99%)
Local Volumes   44        0         5.187kB   5.187kB (100%)
Build Cache     0         0         0B        0B
```

* docker <container,image,network,volume,builder,system> prune = remove dangling (temporary, unused) <container,image,network,volume,builder,system>
  * note: system = all of them (container, image, network, volume, builder)

```bash
# remove stopped containers
docker container prune

# remove dangling images (temporary, cache)
docker image prune

# remove images not used by any container
docker image prune -a

# remove unused networks
docker network prune

# remove unused volumes
docker volume prune

# remove unused builder cache
docker builder prune

# remove all dangling containers, images, networks, builders (except volumes)
docker system prune

# remove all dangling containers, images, networks, builders, and volumes
docker system prune --volumes

# remove all unused containers, images, networks, builders, and volumes
docker system prune -a
```

* docker logs <container> = view container logs

```bash
# view logs from start to end
docker logs nginx

# -f = follow logs live in real time
docker logs nginx -f

# --tail = show last n lines of logs
docker logs --tail 10 nginx  # last 10 log lines
```

* docker exec <container> = run commands inside a container

```bash
# docker exec <container> <command>
docker exec nginx pwd  # execute pwd inside nginx container

# -it = interactive + tty, usually combined when accessing shell
docker exec -it nginx bash
docker exec -it nginx sh

# -u <user> = execute command as specified user
docker exec -u root nginx pwd  # run pwd as root user
```

* docker stats = see resource usage for each container

```bash
docker stats

# example output:
CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %     NET I/O          BLOCK I/O         PIDS
35e6fdbdcd11   app       0.00%     309.4MiB / 15.45GiB   1.96%     634kB / 205kB    86.2MB / 1.68MB   42
4776744e7f8b   db-app    0.00%     9.953MiB / 15.45GiB   0.06%     332kB / 1.82kB   172kB / 1.16MB    13
```


---

### Dockerfile

What is a Dockerfile?

* A file used to create images; besides pulling published images, you can also create your own.

Dockerfile Optimization

* Use small-sized base images, utilize multistage builds.
* Combine RUN commands instead of splitting them, to avoid creating multiple layers.

Create your project with the following structure:

```bash
project/
├── Dockerfile
├── nginx.conf
└── html/
    └── index.html
```

Example Dockerfile:

```bash
# Use the Nginx image as the base image
FROM nginx:latest

# Copy the Nginx configuration file into the container
COPY nginx.conf /etc/nginx/nginx.conf

# Copy the website files into the Nginx root directory
COPY html/ /usr/share/nginx/html/

# Expose port 80 for HTTP access
EXPOSE 80

# Command to run Nginx
CMD ["nginx", "-g", "daemon off;"]
```

Example nginx.conf:

```bash
events { }

http {
    server {
        listen 80;
        server_name localhost;

        location / {
            root /usr/share/nginx/html;
            index index.html;
        }

        error_page 404 /404.html;
    }
}
```

Example index.html

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Learning Dockerfile</title>
  </head>
  <body>
    <h1>Learning Dockerfile</h1>
  </body>
</html>
```

Run with:

```bash
docker build -t coba-nginx-custom:1.0 .
docker run -d -p 80:80 --name my-application coba-nginx-custom:1.0
```


---

### Docker Compose

A configuration file used to run multi-container setups.

How to run using the previous Dockerfile:

Create `docker-compose.yml`:

```bash
version: '3.9'
services:
  app:
    build: .
    image: coba-nginx-custom:1.0
    container_name: aplikasi-saya
    ports:
      - '80:80'
```

Jalankan dengan

```bash
# build the image, same as `docker build -t coba-nginx-custom:1.0 .`
docker compose build

# run the container, similar to:
# docker run -d -p 80:80 --name aplikasi-saya coba-nginx-custom:1.0
docker compose up -d
```

Other examples:

<https://github.com/carenswijaya01/docker-setup-collection>


---

### Best Practices in Using Docker

* Avoid using the `latest` tag; specify exact versions to ease tracking.
* Use small base images and leverage multistage builds in Dockerfile creation.
* Use `.dockerignore` files to exclude unnecessary files from the build context.
* Minimize running containers as root user for security reasons.
* Regularly perform system pruning (`docker system prune`) to clean up unused resources.

---

**Documents**

- [About Me](https://wiki.carens.dev/s/9dff43a5-7aa3-48e0-9ec6-0fbbbaf1a301/doc/about-me-rUOLQ4InJh)
- [Wiki](https://wiki.carens.dev/s/9dff43a5-7aa3-48e0-9ec6-0fbbbaf1a301/doc/wiki-NtaYKKsSOi)