Lỗi Gặp Phải
go: could not create module cache: mkdir /go/pkg/mod: permission denied
Go không thể ghi vào thư mục cache module của nó. Lỗi này thường xuất hiện khi build trong Docker container, chạy job trong CI/CD pipeline, hoặc sau khi ai đó chạy lệnh go với sudo — khiến cache bị gán quyền sở hữu root và chặn người dùng thông thường của bạn.
Nguyên Nhân
Go lưu cache các module đã tải xuống tại $GOPATH/pkg/mod. Trong Docker image, đường dẫn này thường là /go/pkg/mod; trên máy Linux hoặc macOS thông thường, mặc định là ~/go/pkg/mod.
Các nguyên nhân phổ biến nhất:
- Docker image chạy bước trước đó với quyền root, tạo ra
/go/pkg/modvới quyền sở hữu root trước khi user ứng dụng chạygo build. - Ai đó đã chạy
sudo go gethoặcsudo go buildtrên máy dùng chung, khiến cache được tạo với quyền root. - GOPATH trỏ tới thư mục hệ thống (
/go,/usr/local/go) mà user hiện tại không có quyền ghi. - CI/CD runner mount volume hoặc cache được tạo bởi user khác trong job trước đó.
Cách Sửa 1 — Đổi Quyền Sở Hữu Thư Mục Cache (Phổ Biến Nhất)
Cache đã bị root chiếm quyền. Hãy lấy lại:
# Check who owns it
ls -la $(go env GOPATH)/pkg/mod
# Fix ownership (replace $USER with your username if needed)
sudo chown -R $USER:$USER $(go env GOPATH)/pkg/mod
Chạy lại go build hoặc go mod download — lệnh sẽ hoạt động ngay lập tức.
Cách Sửa 2 — Trỏ GOMODCACHE Đến Thư Mục Có Quyền Ghi
Trên máy chủ dùng chung hoặc môi trường bị giới hạn quyền mà bạn không thể chown, hãy chuyển hướng cache sang nơi bạn đã có quyền sở hữu:
# Temporary (current session only)
export GOMODCACHE=$HOME/go/pkg/mod
# Permanent — add to ~/.bashrc or ~/.zshrc
echo 'export GOMODCACHE=$HOME/go/pkg/mod' >> ~/.bashrc
source ~/.bashrc
# Verify
go env GOMODCACHE
Chạy go mod download sau khi thiết lập. Go sẽ tạo đường dẫn cache mới trong thư mục home của bạn và sử dụng từ đó trở đi.
Cách Sửa 3 — Sửa GOPATH (Nếu Đang Trỏ Tới Thư Mục Hệ Thống)
Kiểm tra GOPATH hiện tại đang trỏ tới đâu:
go env GOPATH
Kết quả như /go hoặc /usr/local/go chính là thủ phạm — những đường dẫn đó thuộc sở hữu của root. Hãy đặt lại về vị trí thuộc quyền user:
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
# Add to shell profile for persistence
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc
Cách Sửa 4 — Sửa Trong Docker Container
Docker là nơi lỗi này xuất hiện thường xuyên nhất. Một layer chạy lệnh go với quyền root, gán quyền sở hữu root cho /go/pkg/mod. Sau đó bước tiếp theo chuyển sang user không phải root — và user đó không thể truy cập cache.
Phương án A — Chạy mọi thứ với cùng một user:
FROM golang:1.22
# All go commands run as root — consistent, no permission mismatch
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o myapp .
Phương án B — Tạo user không phải root và đặt GOPATH trong home của họ:
FROM golang:1.22
RUN useradd -m -u 1001 appuser
USER appuser
WORKDIR /home/appuser/app
# GOPATH defaults to ~/go, which appuser owns
COPY --chown=appuser:appuser go.mod go.sum ./
RUN go mod download
COPY --chown=appuser:appuser . .
RUN go build -o myapp .
Phương án C — Chỉ định GOMODCACHE trỏ tới đường dẫn có quyền ghi trong Dockerfile:
ENV GOMODCACHE=/tmp/gomodcache
RUN go mod download
Cách Sửa 5 — CI/CD Pipeline (GitHub Actions / GitLab CI)
Cache Go module giữa các lần chạy pipeline giúp tăng tốc độ — nhưng một cache volume cũ bị sở hữu bởi user sai sẽ làm hỏng mọi thứ. Cách an toàn nhất: để action setup chính thức xử lý GOMODCACHE, và không ghi đè GOPATH thủ công.
# GitHub Actions example
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
# The setup-go action sets GOMODCACHE correctly — don't override GOPATH manually
- name: Download modules
run: go mod download
Đang dùng self-hosted runner? Một job trước đó có thể đã để lại cache với quyền root. Hãy xóa và bắt đầu lại từ đầu:
sudo rm -rf ~/go/pkg/mod
go mod download
Kiểm Tra Sau Khi Sửa
Chạy các lệnh sau khi đã áp dụng bất kỳ cách sửa nào ở trên:
# Check cache directory exists and is accessible
ls -la $(go env GOMODCACHE)
# Try downloading modules fresh
go mod download
# Or just build your project
go build ./...
Không còn lỗi phân quyền và build thành công có nghĩa là bạn đã xong.
Mẹo Phòng Ngừa
- Không bao giờ dùng
sudo go ...— nếu lệnhgocần quyền nâng cao, có gì đó trong cài đặt của bạn đang sai. Hãy sửa vấn đề phân quyền gốc thay vì dùng sudo. - Trong Docker: quyết định dùng root hay non-root ngay từ đầu khi thiết kế Dockerfile và giữ nhất quán trong toàn bộ các layer chạy lệnh
go. - Đặt GOPATH rõ ràng trong shell profile thay vì dựa vào mặc định, đặc biệt trên máy chủ mà nhiều user dùng chung cùng một cài đặt Go.
- Kiểm tra quyền thư mục trực quan: nếu bạn không chắc lệnh
chmodvàchowncó cho ra kết quả đúng không, Unix Permissions Calculator trên ToolCraft cho phép bạn xây dựng và kiểm tra chuỗi phân quyền ngay trên trình duyệt — hữu ích khi xử lý các thiết lập Docker nhiều user và muốn kiểm tra lại con số trước khi áp dụng.

