Sửa lỗi Docker Compose không load biến .env: WARN variable is not set. Defaulting to a blank string.

beginner🐳 Docker2026-05-15| Docker Compose v2 (docker compose) và v1 (docker-compose), Linux/macOS/Windows WSL2, Docker Engine 20.10+

Error Message

WARN[0000] The "DB_PASSWORD" variable is not set. Defaulting to a blank string.
#docker-compose#env#.env#biến-môi-trường#cấu-hình

Lỗi Gặp Phải

Bạn chạy docker compose up và nhận được một loạt cảnh báo:

WARN[0000] The "DB_PASSWORD" variable is not set. Defaulting to a blank string.
WARN[0000] The "DB_HOST" variable is not set. Defaulting to a blank string.
WARN[0000] The "REDIS_URL" variable is not set. Defaulting to a blank string.

File .env của bạn vẫn tồn tại. Bạn nhìn thấy nó rõ ràng. Bạn đã kiểm tra tên biến ba lần rồi. Nhưng Docker Compose cứ làm như file đó không hề tồn tại. Trong khi đó, container database khởi động với mật khẩu trống và lập tức thất bại — lúc 2 giờ sáng, trên môi trường production, tất nhiên rồi.

Nguyên Nhân Gốc Rễ

Docker Compose có những quy tắc nghiêm ngặt về vị trí và cách đọc file .env. Vi phạm bất kỳ quy tắc nào, nó sẽ âm thầm bỏ qua file của bạn hoàn toàn:

  • Sai thư mục: File .env phải nằm trong cùng thư mục nơi bạn chạy lệnh docker compose, không phải nơi docker-compose.yml tọa lạc (nếu hai nơi khác nhau).
  • Sai tên file: File phải được đặt tên chính xác là .env — không phải .env.local, .env.production, hay env (thiếu dấu chấm).
  • Lỗi cú pháp: Giá trị có dấu ngoặc kép, khoảng trắng thừa quanh dấu =, hoặc ký tự xuống dòng kiểu Windows (\r\n) khiến các biến bị phân tích sai hoặc bị bỏ qua hoàn toàn.
  • Nhầm lẫn giữa env_file và thay thế biến: env_file truyền biến vào trong container. File .env cung cấp giá trị cho việc thay thế biến bên trong chính file compose.yml. Đây là hai cơ chế hoàn toàn khác nhau.
  • Quyền truy cập file: Trên Linux, nếu file .env không thể đọc được bởi người dùng hiện tại, Docker Compose sẽ bỏ qua nó mà không có bất kỳ thông báo nào.

Cách Sửa 1: Kiểm Tra Vị Trí và Tên File

Bắt đầu từ đây. Xác nhận bạn đang ở đúng thư mục:

# Kiểm tra bạn đang ở đâu
pwd

# Liệt kê các file ẩn trong thư mục hiện tại
ls -la | grep .env

# Kết quả nên hiển thị tương tự:
# -rw-r--r-- 1 user user 245 May 14 02:13 .env

Nếu file .env nằm trong thư mục con hoặc có tên khác, hãy di chuyển nó hoặc chỉ định trực tiếp cho Docker Compose bằng tham số --env-file:

docker compose --env-file ./config/.env.production up

Cách Sửa 2: Kiểm Tra Cú Pháp File .env

Cú pháp rất khắt khe. Mở file và tìm những bẫy cụ thể sau:

# Sai — có khoảng trắng quanh dấu =
DB_PASSWORD = mysecretpassword

# Sai — giá trị có dấu ngoặc kép (Docker Compose KHÔNG bỏ dấu ngoặc kép)
DB_PASSWORD="mysecretpassword"

# Sai — chú thích nội tuyến sau giá trị
DB_PASSWORD=mysecretpassword  # production password

# Đúng
DB_PASSWORD=mysecretpassword

Ví dụ thứ hai khiến rất nhiều người mắc bẫy. Docker Compose truyền giá trị có dấu ngoặc kép theo nghĩa đen — kể cả dấu ngoặc kép đó. Vì vậy DB_PASSWORD="mysecretpassword" sẽ trở thành chuỗi "mysecretpassword" với dấu ngoặc kép thực sự bên trong. Quá trình xác thực database của bạn sẽ thất bại theo cách khó hiểu.

Ký tự xuống dòng kiểu Windows là một kẻ giết người thầm lặng khác, đặc biệt khi file được tạo trên Windows hoặc đồng bộ qua Git mà không có cấu hình .gitattributes đúng:

# Kiểm tra ký tự carriage return
cat -A .env | head -5
# Sai: DB_PASSWORD=secret^M$
# Đúng: DB_PASSWORD=secret$

# Sửa ký tự xuống dòng kiểu Windows
sed -i 's/\r//' .env

Cách Sửa 3: Phân Biệt env_file và Thay Thế Biến .env

Hai cơ chế có tên tương tự nhau nhưng làm những việc khác nhau. Đây là sự phân biệt:

Cơ chế 1 — Thay thế biến trong compose.yml (dùng file .env tại thư mục gốc dự án):

# docker-compose.yml
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}  # ← được thay thế từ .env lúc phân tích cú pháp

Cơ chế 2 — Chỉ thị env_file (truyền biến trực tiếp vào container):

# docker-compose.yml
services:
  db:
    image: postgres
    env_file:
      - .env  # ← các biến trong file này đi VÀO môi trường container

Bạn đang dùng cú pháp ${DB_PASSWORD} trong file compose? Docker Compose cần file .env ở thư mục gốc dự án để thay thế các giá trị đó trước khi container khởi động. Bạn dùng env_file thay thế? File chỉ cần đọc được lúc chạy.

Cách Sửa 4: Kiểm Tra Những Gì Docker Compose Thực Sự Thấy

Thôi đừng đoán mò nữa. Hỏi thẳng Docker Compose:

# In ra cấu hình compose đã được giải quyết hoàn toàn (tất cả biến đã thay thế)
docker compose config

# Nếu DB_PASSWORD vẫn hiển thị trống hoặc rỗng, nghĩa là nó chưa được tải

Bạn cũng có thể tìm file .env nào Docker Compose đang thực sự sử dụng:

# Docker Compose v2 hiển thị điều này trong output verbose
docker compose --verbose config 2>&1 | grep -i env

Một kiểm tra hữu ích nữa — in ra mọi biến mà container sẽ nhận:

docker compose run --rm your_service env | sort

Cách Sửa 5: Truyền Biến Trực Tiếp Như Giải Pháp Tạm Thời

Cần mọi thứ chạy ngay bây giờ trong khi bạn tìm hiểu nguyên nhân gốc rễ? Bỏ qua file hoàn toàn:

# Truyền trực tiếp (không lý tưởng cho dữ liệu nhạy cảm)
DB_PASSWORD=temporaryfix docker compose up

# Hoặc export trước
export DB_PASSWORD=temporaryfix
docker compose up

Các biến môi trường shell luôn được ưu tiên hơn giá trị trong file .env, vì vậy cách này luôn hoạt động bất kể vấn đề file là gì.

Kiểm Tra Sau Khi Sửa

Sau khi áp dụng bản sửa lỗi, hãy chạy ba kiểm tra này trước khi tuyên bố thành công:

# 1. Chạy config và tìm biến của bạn
docker compose config | grep DB_PASSWORD
# Nên hiển thị giá trị thực, không phải trống

# 2. Không còn dòng WARN khi khởi động
docker compose up 2>&1 | grep WARN
# Nên trống (hoặc ít nhất không có cảnh báo về biến)

# 3. Xác nhận container nhận được giá trị đúng
docker compose run --rm db env | grep DB_PASSWORD

Phòng Ngừa

Hình thành những thói quen này ngay bây giờ và bạn sẽ không phải debug vào lúc 2 giờ sáng nữa:

  • Chạy docker compose config trước mỗi lần deploy. Nó phát hiện lỗi thay thế biến trước khi bất kỳ container nào khởi động. Chỉ mất năm giây.
  • Thêm .env vào .gitignore, nhưng commit một file .env.example chứa tất cả các khóa cần thiết và giá trị trống. Thành viên mới trong nhóm biết ngay cần những biến nào mà không cần đọc tài liệu.
  • Khai báo rõ ràng env file trong CI/CD. Dùng --env-file và chỉ định tên file. Đừng dựa vào việc tự động phát hiện .env trong pipeline — những gì hoạt động ở local thường không chạy được trong CI.
  • Tạo giá trị ngẫu nhiên mạnh cho các secret như DB_PASSWORD thay vì gõ tay. Trình Tạo Mật Khẩu của ToolCraft chạy hoàn toàn trên trình duyệt — không có gì được gửi lên server, điều này quan trọng khi bạn đang tạo thông tin xác thực database.
  • Kiểm tra YAML trong file compose nếu bạn thấy hành vi phân tích cú pháp bất thường. Công cụ YAML ↔ JSON Converter trên ToolCraft phát hiện YAML bị lỗi rất nhanh.

Tóm Tắt Nhanh: Quy Tắc File .env

# Vị trí: cùng thư mục nơi bạn chạy 'docker compose'
# Tên: phải là '.env' (hoặc chỉ định bằng --env-file)
# Cú pháp:
#   KEY=value          ✓ đúng
#   KEY = value        ✗ không được có khoảng trắng quanh =
#   KEY="value"        ✗ dấu ngoặc kép được hiểu theo nghĩa đen
#   KEY=value # note   ✗ không hỗ trợ chú thích nội tuyến
#   export KEY=value   ✗ không hỗ trợ từ khóa 'export'

DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_PASSWORD=use-a-real-random-password-here

Related Error Notes