5 phút để ‘tàng hình’ mật khẩu với Docker Secrets
Chắc hẳn bạn không muốn password database hiện ra lù lù trong log hệ thống đâu nhỉ? Đừng bao giờ ném API key trực tiếp vào mục environment của file docker-compose.yml. Thay vào đó, hãy dùng Docker Secrets để bảo mật đúng cách ngay từ môi trường local.
Bước 1: Tạo file chứa mật khẩu (ví dụ db_password.txt). Hãy nhớ thêm ngay file này vào .gitignore để tránh đẩy lên server công khai.
echo "my-super-secret-password" > db_password.txt
Bước 2: Khai báo secrets trong docker-compose.yml cực kỳ đơn giản:
services:
db:
image: postgres
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./db_password.txt
Bước 3: Gõ lệnh docker compose up -d là xong. Mật khẩu của bạn giờ đã nằm an toàn tại /run/secrets/db_password. Nếu ai đó tò mò chạy docker inspect, họ sẽ chỉ thấy một khoảng trống thay vì password thật.
Biến môi trường: ‘Kẻ hở’ lớn hơn bạn nghĩ
Sự thật là, chỉ cần một lệnh docker inspect <container_id>, mọi bí mật của bạn sẽ hiện ra ngay trước mắt đồng nghiệp hoặc bất kỳ ai có quyền truy cập server. Mình từng chứng kiến một hệ thống bị lộ toàn bộ thông tin nhạy cảm chỉ vì các biến môi trường này bị ghi đè vào log của công cụ giám sát tập trung.
Docker Secrets giải quyết triệt để vấn đề này nhờ các cơ chế sau:
- Lưu trữ trên RAM: Trong Docker Swarm, secret được lưu trong Raft log mã hóa và chỉ mount vào RAM (tmpfs) của container khi cần. Dữ liệu không bao giờ chạm xuống ổ cứng.
- Kiểm soát quyền truy cập: Chỉ những service được chỉ định cụ thể mới có quyền ‘nhìn’ thấy secret đó.
- Quản lý tập trung: Bạn dễ dàng deploy cùng một cấu hình lên nhiều môi trường mà không lo lẫn lộn dữ liệu giữa Dev và Prod.
Cơ chế vận hành thực tế
Khi gắn một secret vào service, Docker sẽ mount nó thành một file trong thư mục /run/secrets/ bên trong container. Đa số các image lớn như MariaDB, Postgres hay WordPress đều có sẵn tùy chọn hậu tố _FILE. Điều này cho phép ứng dụng đọc dữ liệu trực tiếp từ file thay vì từ biến môi trường thông thường.
Nâng tầm bảo mật với Docker Swarm
Nếu bạn đang vận hành cụm cluster với Docker Swarm, việc quản lý secret sẽ còn chuyên nghiệp hơn. Mọi dữ liệu nhạy cảm được đồng bộ giữa các node quản lý (Manager nodes) qua kênh mTLS mã hóa với độ bảo mật cực cao.
Đẩy Secret trực tiếp từ CLI
Bạn không cần tạo file vật lý trên server. Hãy đẩy thẳng giá trị vào database của Swarm bằng một dòng lệnh:
echo "serect_key_2024" | docker secret create api_key -
Triển khai với Stack Deploy
Trong file stack.yml, hãy sử dụng từ khóa external để tận dụng các secret đã tồn tại sẵn trên hệ thống:
version: '3.8'
services:
app:
image: my-app:latest
secrets:
- api_key
secrets:
api_key:
external: true
Cuối cùng, triển khai hệ thống bằng lệnh quen thuộc: docker stack deploy -c stack.yml my_web_app.
Kinh nghiệm từ những lần ‘vấp ngã’
Việc chuyển từ docker-compose v1 sang v2 mang lại trải nghiệm rất mượt mà. Ở bản v2 (sử dụng lệnh docker compose không dấu gạch ngang), tính năng secrets đã trở thành chuẩn chung ngay cả khi bạn không chạy Swarm. Bạn không còn phải dùng các thủ thuật giả lập phức tạp như trước đây nữa.
Viết code linh hoạt hơn
Để ứng dụng chạy tốt cả trên local lẫn production, mình thường viết một hàm nhỏ trong Python để ưu tiên đọc secret từ file trước khi tìm đến biến môi trường:
import os
def get_config(key, default=None):
# Ưu tiên đọc từ đường dẫn secret của Docker
secret_path = f"/run/secrets/{key}"
if os.path.exists(secret_path):
with open(secret_path, 'r') as f:
return f.read().strip()
# Fallback về biến môi trường nếu không tìm thấy file
return os.getenv(key, default)
Đừng để Secret ‘quá hạn’ (Secret Rotation)
Nhiều người có thói quen dùng một mật khẩu suốt 2-3 năm mà không đổi. Với Docker Swarm, secret là bất biến (immutable), nên bạn cần tạo version mới khi muốn cập nhật. Quy trình chuẩn thường là: Tạo api_key_v2, cập nhật file compose, deploy lại để Docker tự động thay thế container, và cuối cùng là xóa api_key_v1 khi mọi thứ đã ổn định.
Checklist để bạn ngủ ngon hơn
- Cấm commit file secret: Luôn kiểm tra
.gitignoređể chắc chắn không có file.txthay.keynào lọt lên Git. - Dùng Docker Configs đúng chỗ: Với các file cấu hình thông thường như
nginx.conf, hãy dùngconfigsthay vìsecretsđể đạt hiệu suất tốt nhất. - Nguyên tắc đặc quyền tối thiểu: Container chạy Frontend tuyệt đối không được phép truy cập vào secret của database master.
- Tận dụng RAM: Hãy nhớ rằng trong Swarm, secret chỉ nằm trên RAM. Điều này giúp bảo vệ dữ liệu ngay cả khi server bị chiếm quyền điều khiển ổ cứng vật lý.
Quản lý bảo mật không hề khó, quan trọng là chúng ta biến nó thành thói quen hàng ngày. Chúc các bạn xây dựng được hệ thống vừa mạnh mẽ vừa an toàn!

