Cài Đặt Docker và Chạy Container Đầu Tiên

K
Kai··4 min read

Hai bài trước giải thích Docker hoạt động thế nào. Từ bài này ta thực hành. Mục tiêu: cài Docker, chạy container đầu tiên, và nắm vòng đời của một container — tạo, chạy, xem, dừng, xóa.

Cài đặt Docker

Cách cài tùy hệ điều hành. Luôn lấy bản mới từ trang chính thức:

  • macOS / Windows: cài Docker Desktop (tải tại trang Get Docker của docker.com). Nhớ từ Bài 1: trên macOS/Windows, Docker Desktop chạy một VM Linux ở dưới, daemon nằm trong đó.
  • Linux: cài Docker Engine theo hướng dẫn cho distro của bạn (Ubuntu, Debian, Fedora...). Trên Linux không cần VM vì đã có sẵn nhân Linux.

Sau khi cài, kiểm tra:

docker version

Nếu thấy cả khối Client lẫn Server (như đã nói ở Bài 1), nghĩa là client kết nối được tới daemon. Nếu báo "Cannot connect to the Docker daemon", daemon chưa chạy (mở Docker Desktop, hoặc trên Linux chạy sudo systemctl start docker).

Trên Linux, nếu phải gõ sudo trước mọi lệnh docker, thêm user vào nhóm docker: sudo usermod -aG docker $USER rồi đăng nhập lại. Lý do liên quan tới quyền truy cập socket /var/run/docker.sock đã nói ở Bài 1.

Chạy thử container kiểm tra (image này chỉ in một dòng chào rồi thoát):

docker run hello-world

Nếu thấy dòng "Hello from Docker!", mọi thứ đã sẵn sàng.

Chạy container đầu tiên đúng nghĩa

hello-world chạy rồi thoát ngay. Giờ chạy một thứ "sống" — web server nginx:

docker run -d --name web -p 8080:80 nginx:alpine

Ba cờ quan trọng ở đây:

  • -d (detached): chạy nền, trả lại terminal cho bạn. Không có -d, container chạy ở foreground và chiếm terminal cho tới khi nó dừng.
  • --name web: đặt tên cho container. Không đặt thì Docker tự sinh một tên ngẫu nhiên (kiểu nostalgic_curie).
  • -p 8080:80: ánh xạ cổng. Cổng 80 bên trong container (nơi nginx lắng nghe) được "publish" ra cổng 8080 trên máy bạn. Cú pháp là -p <host>:<container>. Bài 7 sẽ giải thích cơ chế bên dưới.

Mở trình duyệt vào http://localhost:8080, bạn sẽ thấy trang chào nginx. Nó đang được phục vụ từ container vừa tạo.

Vòng đời một container

Một container đi qua các trạng thái sau:

   docker run
       │
       ▼
   [Created] ──► [Running] ──stop──► [Exited]
                    ▲                   │
                    └──── start ────────┘
                                        │
                                       rm
                                        ▼
                                   [Removed]

Điểm hay nhầm: dừng (stop) không phải xóa (rm). Container dừng vẫn còn đó (kèm writable layer của nó), chỉ là không chạy. Phải rm mới xóa hẳn.

Xem container đang chạy:

docker ps
NAMES   STATUS         PORTS
web     Up 2 seconds   0.0.0.0:8080->80/tcp

Thêm -a để xem cả container đã dừng:

docker ps -a

Tương tác với container đang chạy

Xem log (hữu ích nhất khi gỡ lỗi):

docker logs web

Thêm -f để theo dõi log mới theo thời gian thực (như tail -f), Ctrl+C để thoát:

docker logs -f web

Chạy một lệnh bên trong container đang chạy bằng exec:

docker exec web hostname

Mở hẳn một shell tương tác bên trong container để xem xét (cờ -it = interactive + cấp một terminal):

docker exec -it web sh

Giờ bạn đang ở bên trong container. Thử ls, cat /etc/nginx/nginx.conf, ps. Nhớ từ Bài 2: ps chỉ thấy tiến trình của container, hostname là id container. Gõ exit để ra.

Phân biệt runexec: run tạo container mới từ một image; exec chạy lệnh trong container đang chạy sẵn. Người mới hay nhầm dùng run khi thực ra muốn exec.

Dừng, chạy lại, xóa

docker stop web      # gửi tín hiệu dừng, container sang trạng thái Exited
docker start web     # chạy lại container đã dừng (giữ nguyên writable layer)
docker restart web   # stop rồi start

Xóa container (phải dừng trước, hoặc dùng -f để ép):

docker stop web
docker rm web

Một mẹo hay dùng khi thử nghiệm: --rm để container tự xóa ngay khi dừng, khỏi phải dọn tay:

docker run --rm -d --name tmp -p 8081:80 nginx:alpine
# khi container này dừng, nó tự biến mất

🧹 Dọn dẹp

Container và image tích lại sẽ chiếm ổ đĩa. Cuối mỗi bài ta dọn phần vừa tạo.

Dừng và xóa container của bài:

docker rm -f web tmp 2>/dev/null

Xem những container còn lại:

docker ps -a

Xóa image đã kéo về nếu không cần giữ:

docker rmi nginx:alpine hello-world

Hoặc dọn gọn mọi thứ không dùng (container đã dừng, image không gắn với container nào, network thừa, build cache) bằng một lệnh:

docker system prune

Lệnh này hỏi xác nhận trước khi xóa. Xem trước máy đang tốn bao nhiêu cho Docker:

docker system df

Tổng kết

Bạn đã cài Docker, chạy một web server trong container, và đi qua trọn vòng đời: run (tạo + chạy), ps (xem), logs/exec (tương tác), stop/start (tắt/bật), rm (xóa). Quy tắc cần khắc: stop ≠ rm, và run (container mới) ≠ exec (vào container có sẵn).

Bài 4 ta tìm hiểu image — thứ mà docker run dựa vào: nó đến từ đâu (registry/Docker Hub), gồm những layer gì (nối tiếp Bài 2), và cách quản lý image trên máy.