Cuộc Gọi Lúc 2 Giờ Sáng
Bạn đang deploy một service mới, mọi thứ trông ổn, rồi bỗng nhiên gặp cái này:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info: dial unix /var%2Frun%2Fdocker.sock: connect: permission denied
Bạn chẳng thay đổi gì cả. Hôm qua Docker còn chạy tốt. Bây giờ thì không. Hai lệnh sau sẽ cho bạn biết chính xác điều gì đã hỏng — và việc sửa chỉ mất chưa đến một phút.
Chuyện Gì Đang Xảy Ra
Docker giao tiếp với daemon thông qua một Unix socket tại /var/run/docker.sock. Socket đó thuộc sở hữu của root và nhóm docker, với quyền 660. Nếu user của bạn không thuộc nhóm docker, hệ điều hành sẽ từ chối kết nối hoàn toàn.
Điều này thường xảy ra khi:
- Một tài khoản user mới được tạo mà không được thêm vào nhóm docker
- Bạn vừa cài Docker và chưa đăng xuất rồi đăng nhập lại
- Một CI/CD runner đang chạy dưới dạng tài khoản service không có quyền
- Ai đó đã chạy
deluserhoặc thay đổi thành viên nhóm trong quá trình dọn dẹp hệ thống
Debug Trước Đã
Trước khi đụng vào bất cứ thứ gì, hãy xác nhận nguyên nhân gốc rễ. Chạy các lệnh này theo thứ tự:
1. Kiểm tra user hiện tại và các nhóm
whoami
groups
Không thấy docker trong kết quả? Đó chính là câu trả lời của bạn.
2. Kiểm tra quyền của socket
ls -la /var/run/docker.sock
Kết quả mong đợi:
srw-rw---- 1 root docker 0 Mar 17 02:14 /var/run/docker.sock
Owner phải là root:docker, quyền 660. Nếu bạn thấy 600 hoặc nhóm khác, đó chính là thủ phạm.
3. Xác nhận nhóm docker có tồn tại không
getent group docker
Không có kết quả nghĩa là nhóm chưa tồn tại. Bạn cần tạo nhóm trước khi thêm ai vào đó.
Cách Sửa
Cách 1: Thêm user vào nhóm docker (sửa vĩnh viễn)
Phù hợp cho máy dev và mọi server mà bạn sở hữu tài khoản.
# Thêm user hiện tại vào nhóm docker
sudo usermod -aG docker $USER
# Áp dụng thay đổi nhóm mà không cần đăng xuất
newgrp docker
newgrp docker mở một shell mới với nhóm docker được kích hoạt ngay lập tức. Kiểm tra thử:
docker ps
Nếu lệnh này chạy được, bạn đã xong cho phiên làm việc này. Đăng xuất và đăng nhập lại để thay đổi có hiệu lực trên tất cả terminal trong tương lai.
Nhắm vào một user cụ thể thay vì chính bạn:
sudo usermod -aG docker username
Cách 2: Sửa quyền socket (giải pháp tạm thời khẩn cấp)
Cần Docker chạy ngay bây giờ mà không thể đăng xuất?
sudo chmod 666 /var/run/docker.sock
Có hiệu lực ngay lập tức. Đánh đổi là: mọi user local trên máy đều có thể điều khiển Docker — tương đương quyền root. Ổn trên máy dev cá nhân. Nhưng là vấn đề nghiêm trọng trên server dùng chung.
Ngoài ra: Docker sẽ đặt lại quyền này khi khởi động lại, nên đây không phải giải pháp lâu dài.
Cách 3: Tạo nhóm docker nếu chưa tồn tại
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
Cách 4: Dùng sudo (không khuyến nghị lâu dài)
sudo docker ps
Giúp bạn thoát khỏi tình trạng bị chặn trong hai giây. Tuy nhiên về lâu dài, cách này tạo ra đau đầu về quyền volume — các file được ghi bên trong container sẽ thuộc sở hữu của root trên máy host. Dùng cách này để debug một lần, không phải là workflow hàng ngày.
Xác Nhận Bản Sửa
Sau khi áp dụng bản sửa, xác nhận Docker phản hồi mà không cần sudo:
# Kiểm tra kết nối đầy đủ
docker info
# Kết quả mong đợi: khối thông tin server với số lượng container, storage driver, v.v.
# Client:
# Context: default
# Debug Mode: false
# Server:
# Containers: 3
# Running: 1
# ...
# Chạy một container từ đầu đến cuối
docker run --rm hello-world
Khối Server trong docker info không có lỗi nghĩa là kết nối socket đã sạch.
CI/CD và Môi Trường Tự Động Hóa
Các self-hosted runner cho GitHub Actions, GitLab CI, hoặc Jenkins thường chạy dưới tài khoản service chuyên dụng. Cách sửa tương tự — chỉ cần nhắm vào tài khoản đó:
# Tìm xem runner chạy dưới user nào
ps aux | grep runner
# Thêm user đó vào nhóm
sudo usermod -aG docker gitlab-runner
sudo systemctl restart gitlab-runner
Các setup Docker-in-Docker mount host socket vào container là một trường hợp khác:
docker run -v /var/run/docker.sock:/var/run/docker.sock your-image
User trong container cần khớp với GID của nhóm docker trên máy host. Nếu GID không khớp, bạn sẽ gặp đúng lỗi permission đó — nhưng lần này là bên trong container.
Giải Mã Các Bit Phân Quyền
Khi nhìn chằm chằm vào srw-rw---- lúc nửa đêm mà não bạn không chịu hoạt động, Unix Permissions Calculator trên ToolCraft dịch những bit đó sang tiếng người bình thường ngay lập tức. Chạy trên trình duyệt, không gửi gì đi đâu cả.
Bài Học Rút Ra
- Tích hợp bước cài đặt nhóm docker vào script provisioning của bạn. Ansible, cloud-init, Terraform user data, một runbook thủ công — không quan trọng cái nào. Thêm
usermod -aG dockernhư một bước tiêu chuẩn ngay sau khi cài Docker. Lỗi này gần như không bao giờ xuất hiện trên những máy được provisioning đúng cách. newgrp dockerlà người bạn tốt nhất của bạn ở đây. Không cần đăng xuất. Nó cho bạn một shell nhận biết nhóm ngay lập tức để xác nhận bản sửa trước khi bạn đóng bất cứ thứ gì.- Đừng chmod 777 socket.
666đã là một sự đánh đổi có chủ ý rồi.777thêm các bit execute không có mục đích gì và sẽ bị gắn cờ trong bất kỳ lần quét bảo mật nào đáng kể. - Phát hiện quyền CI runner ngay từ ngày đầu. Khi dựng môi trường CI mới, hãy làm
docker pslà bước đầu tiên trong pipeline. Năm giây kiểm tra còn hơn 30 phút debug một pipeline thất bại một tuần sau đó.

