Skip to content

Buổi 1: Container là gì? Cài đặt Docker

🎯 Mục tiêu

  • Hiểu container là gì và tại sao cần dùng
  • Phân biệt Virtual Machine vs Container
  • Cài đặt Docker Desktop trên máy tính
  • Chạy được container đầu tiên: docker run hello-world
  • Làm quen với Docker CLI cơ bản

1. Vấn đề "It works on my machine"

Tình huống thực tế

Developer A: "App chạy ngon trên máy mình!"
Developer B: "Sao máy mình không chạy được?"
Ops: "Deploy lên server lỗi tùm lum 😱"

Nguyên nhân:

  • Khác phiên bản ngôn ngữ (Node 18 vs Node 20)
  • Khác hệ điều hành (Windows vs Linux)
  • Thiếu thư viện hệ thống
  • Khác cấu hình environment

Giải pháp: Đóng gói app + toàn bộ dependencies vào một container → chạy giống nhau ở mọi nơi.


2. Container là gì?

Định nghĩa

Container là một đơn vị phần mềm được đóng gói, chứa:

  • Code ứng dụng
  • Runtime (Node.js, Python, Java...)
  • Thư viện hệ thống
  • Cấu hình

Tất cả chạy trong một môi trường cách ly trên cùng một hệ điều hành.

Ví dụ trực quan

┌─────────────────────────────────────────┐
│              Host Machine               │
│  ┌───────────┐  ┌───────────┐           │
│  │ Container │  │ Container │           │
│  │           │  │           │           │
│  │  Node.js  │  │  Python   │           │
│  │  App A    │  │  App B    │           │
│  │  Port 3000│  │  Port 8000│           │
│  └───────────┘  └───────────┘           │
│                                         │
│         🐧 Linux Kernel (shared)        │
└─────────────────────────────────────────┘

Mỗi container chạy cách ly nhưng chia sẻ kernel của hệ điều hành host.


3. Virtual Machine vs Container

Kiến trúc so sánh

    Virtual Machine                    Container
┌───────────────────┐          ┌───────────────────┐
│   App A │  App B  │          │   App A │  App B  │
├─────────┼─────────┤          ├─────────┼─────────┤
│ Guest OS│ Guest OS│          │  Bins/  │  Bins/  │
│ (Linux) │(Windows)│          │  Libs   │  Libs   │
├─────────┴─────────┤          ├─────────┴─────────┤
│    Hypervisor      │          │   Container Engine │
│  (VMware/VBox)     │          │     (Docker)       │
├────────────────────┤          ├────────────────────┤
│    Host OS         │          │    Host OS         │
├────────────────────┤          ├────────────────────┤
│    Hardware        │          │    Hardware        │
└────────────────────┘          └────────────────────┘

Bảng so sánh chi tiết

Đặc điểmVirtual MachineContainer
Khởi động🐌 Phút⚡ Giây
Dung lượng💾 GB (có cả OS)📦 MB (chỉ app + libs)
Hiệu năng70-80% host~95% host
Cách ly✅ Hoàn toàn (có OS riêng)✅ Process-level
OSChạy bất kỳ OSChia sẻ kernel host
Số lượng5-10 VM/server100+ container/server
Use caseChạy OS khác nhauDeploy microservices

4. Docker là gì?

Docker là nền tảng container phổ biến nhất, gồm:

Thành phầnVai trò
Docker EngineRuntime chạy container
Docker CLIGiao diện dòng lệnh
Docker DesktopApp GUI cho Windows/macOS
Docker HubRegistry chia sẻ images
Docker ComposeQuản lý nhiều container

Kiến trúc Docker

┌─────────────────────────────────────────────┐
│                Docker CLI                    │
│         docker run, build, pull...           │
└──────────────────┬──────────────────────────┘
                   │ REST API

┌─────────────────────────────────────────────┐
│              Docker Daemon                   │
│            (dockerd service)                 │
├──────────┬──────────┬───────────────────────┤
│  Images  │Containers│  Networks & Volumes   │
└──────────┴──────────┴───────────────────────┘


┌─────────────────────────────────────────────┐
│           Container Runtime                  │
│        (containerd + runc)                   │
└─────────────────────────────────────────────┘

5. Cài đặt Docker

Windows

bash
# Yêu cầu: Windows 10/11 64-bit, WSL2
# Bước 1: Bật WSL2
wsl --install

# Bước 2: Tải Docker Desktop
# https://docs.docker.com/desktop/install/windows-install/

# Bước 3: Cài đặt và khởi động Docker Desktop
# → Chọn "Use WSL 2 based engine"

macOS

bash
# Dùng Homebrew
brew install --cask docker

# Hoặc tải từ trang chủ
# https://docs.docker.com/desktop/install/mac-install/

Linux (Ubuntu/Debian)

bash
# Cài đặt Docker Engine
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Thêm repository
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Cài đặt
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

# Chạy Docker không cần sudo
sudo usermod -aG docker $USER

Kiểm tra cài đặt

bash
# Kiểm tra phiên bản
$ docker --version
Docker version 27.5.1, build 9f9e405

# Kiểm tra chi tiết
$ docker info

# Kiểm tra Docker Compose
$ docker compose version
Docker Compose version v2.32.4

6. Container đầu tiên: Hello World

Chạy hello-world

bash
$ docker run hello-world

Output:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
e6590344b1a5: Pull complete
Digest: sha256:...
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image.
 4. The Docker daemon streamed that output to the Docker client.

Điều gì đã xảy ra?

┌──────────┐    ┌──────────┐    ┌──────────────┐
│ docker   │───▶│ Docker   │───▶│  Docker Hub  │
│ CLI      │    │ Daemon   │    │  (registry)  │
└──────────┘    └────┬─────┘    └──────────────┘
                     │               │
                     │  pull image   │
                     │◀──────────────┘

                     │  create container

                ┌──────────┐
                │Container │
                │hello-world│
                │  (exit)  │
                └──────────┘
  1. Docker CLI gửi lệnh đến Docker Daemon
  2. Daemon không tìm thấy image hello-world trên máy
  3. Daemon pull (tải) image từ Docker Hub
  4. Daemon tạo container từ image
  5. Container chạy, in ra message, rồi exit

7. Một số lệnh Docker cơ bản

bash
# Xem danh sách container đang chạy
$ docker ps

# Xem tất cả container (kể cả đã dừng)
$ docker ps -a

# Xem danh sách images trên máy
$ docker images

# Xem thông tin hệ thống Docker
$ docker info

# Xem help cho bất kỳ lệnh nào
$ docker run --help

Thử chạy một container tương tác

bash
# Chạy Ubuntu container và mở shell
$ docker run -it ubuntu bash

# Bạn đang ở TRONG container Ubuntu!
root@abc123:/# cat /etc/os-release
root@abc123:/# echo "Hello from container!"
root@abc123:/# exit
FlagÝ nghĩa
-iInteractive – giữ STDIN mở
-tTTY – cấp terminal giả
-itKết hợp: mở shell tương tác

Thử chạy Nginx web server

bash
# Chạy Nginx ở background, map port 8080 → 80
$ docker run -d -p 8080:80 --name my-nginx nginx

# Mở trình duyệt: http://localhost:8080
# → Thấy trang "Welcome to nginx!"

# Dừng container
$ docker stop my-nginx

# Xóa container
$ docker rm my-nginx
FlagÝ nghĩa
-dDetach – chạy nền (background)
-p 8080:80Map port host:container
--nameĐặt tên cho container

🏋️ Bài tập thực hành

Bài 1: Cài đặt và kiểm tra

  1. Cài đặt Docker Desktop trên máy
  2. Chạy docker --versiondocker info
  3. Chạy docker run hello-world thành công

Bài 2: Khám phá containers

  1. Chạy container Ubuntu: docker run -it ubuntu bash
  2. Bên trong container, thử các lệnh: ls, pwd, whoami
  3. Thoát container bằng exit
  4. Kiểm tra container đã dừng: docker ps -a

Bài 3: Chạy web server

  1. Chạy Nginx: docker run -d -p 8080:80 --name web nginx
  2. Mở trình duyệt, truy cập http://localhost:8080
  3. Dừng và xóa container: docker stop web && docker rm web

Bài 4: Tự khám phá

  1. Chạy docker run -it python:3.12 python3 – mở Python REPL trong container
  2. Chạy docker run -it node:20 node – mở Node.js REPL trong container
  3. Dọn dẹp tất cả container đã dừng: docker container prune