HTTPS cho Docker Local: Setup “ổ khóa xanh” xịn xò với mkcert và Nginx

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Code trên http://localhost:3000 hay 8080 thường khá “hiền”. Nhưng mọi thứ sẽ bắt đầu rắc rối khi bạn cần test OAuth2, Service Workers, hay nhận Webhook từ bên thứ ba. Lúc này, việc thiếu SSL “xịn” trên máy local không chỉ khiến trình duyệt báo đỏ mà còn làm các API từ chối kết nối thẳng thừng.

Ngày xưa, mình hay dùng OpenSSL để tự ký chứng chỉ. Cực nhất là mỗi lần vào web lại phải click qua mấy lớp cảnh báo “Your connection is not private” của Chrome. Sau này, khi làm các dự án lớn, mình chuyển sang combo mkcert + Nginx Reverse Proxy. Cách này sạch, chuyên nghiệp và quan trọng là “xanh” ngay lập tức.

Vấn đề: Tại sao không nên dùng http://localhost?

Có 3 lý do thực tế mà mình luôn khuyên anh em nên setup HTTPS ngay từ đầu:

  • Khớp với Production: Tránh tình trạng lỗi “Mixed Content” khi deploy. Đặc biệt là các thuộc tính Cookie như Secure hay SameSite=None buộc phải có HTTPS mới hoạt động.
  • Tính năng đặc thù: Geolocation, Push Notifications hay các bộ framework hiện đại như Next.js thường yêu cầu môi trường bảo mật (Secure Context).
  • Tâm lý: Nhìn ổ khóa xanh trên thanh địa chỉ mang lại cảm giác an tâm và “pro” hơn hẳn khi làm việc.

Thực tế, mình từng mất cả buổi chiều debug lỗi không nhận được session sau khi redirect từ cổng thanh toán Stripe. Hóa ra nguyên nhân chỉ vì cookie ở local thiếu flag Secure – thứ mà ở môi trường HTTPS thật luôn mặc định phải có.

Công cụ cần thiết

Để bắt đầu, bạn cần chuẩn bị:

  1. Docker & Docker Compose: Công cụ đóng gói ứng dụng tiêu chuẩn.
  2. mkcert: “Ma thuật” giúp tạo Local CA đáng tin cậy chỉ với một dòng lệnh.
  3. Nginx: Đóng vai trò là “người gác cổng” (Reverse Proxy) để nhận traffic HTTPS và phân phối vào container.

Cài đặt mkcert

Nếu dùng macOS, bạn chỉ cần gõ lệnh qua Homebrew:

brew install mkcert
brew install nss # Cần thiết nếu bạn dùng Firefox

Với Windows, hãy sử dụng Chocolatey:

choco install mkcert

Cài xong, hãy chạy lệnh sau để đăng ký Local CA vào hệ thống. Bạn chỉ cần làm việc này duy nhất một lần trên máy tính:

mkcert -install

Thực hành: Setup HTTPS cho dự án Docker

Giả sử bạn có ứng dụng chạy ở cổng 8080 và muốn truy cập qua domain ảo itfromzero.test.

Bước 1: Tạo chứng chỉ SSL

Trong thư mục dự án, hãy tạo folder để chứa certificate:

mkdir -p certs
mkcert -cert-file certs/local-cert.pem -key-file certs/local-key.pem itfromzero.test "*.itfromzero.test" localhost 127.0.0.1

Lúc này trong folder certs sẽ có 2 file .pem. Lưu ý: Tuyệt đối không commit file key lên Git để đảm bảo an toàn.

Bước 2: Cấu hình Nginx làm Reverse Proxy

Tạo file nginx.conf để điều hướng traffic:

server {
    listen 80;
    server_name itfromzero.test;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name itfromzero.test;

    ssl_certificate /etc/nginx/certs/local-cert.pem;
    ssl_certificate_key /etc/nginx/certs/local-key.pem;

    location / {
        proxy_pass http://web_app:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Bước 3: File Docker Compose

Đây là nơi chúng ta kết nối mọi thứ. Ta sẽ mount các file cert và config vào container Nginx.

version: '3.8'

services:
  web_app:
    image: nginx:alpine
    # App của bạn đang listen ở cổng 8080
    command: ["nginx", "-g", "daemon off;"]

  nginx_proxy:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - web_app

Bước 4: Cấu hình file Hosts

Vì domain itfromzero.test không có thật, bạn cần “lừa” máy tính trỏ domain này về IP local.

Mở file /etc/hosts (Linux/macOS) hoặc C:\Windows\System32\drivers\etc\hosts (Windows) và thêm dòng:

127.0.0.1 itfromzero.test

Kiểm tra kết quả

Khởi động hệ thống bằng lệnh quen thuộc:

docker-compose up -d

Bây giờ, hãy mở trình duyệt và truy cập https://itfromzero.test. Bạn sẽ thấy ổ khóa xanh hiện lên ngay lập tức mà không cần nhấn thêm bất kỳ nút xác nhận bảo mật nào.

Lưu ý để tránh lỗi “ngớ ngẩn”

Có 3 điểm mình thường thấy anh em hay vấp phải:

  • Quyền hạn file: Trên Linux, nếu Nginx báo không đọc được cert, hãy thử chmod 644 certs/* để phân quyền lại.
  • Tên Service: proxy_pass trong Nginx phải trùng khớp hoàn toàn với tên service bạn đặt trong docker-compose.yml.
  • DNS Cache: Nếu sửa file hosts mà chưa nhận ngay, hãy thử flush DNS hoặc restart trình duyệt để cập nhật.

Kết luận

Dùng mkcert giúp việc dev local trở nên chuyên nghiệp hơn rất nhiều. Bạn không còn phải loay hoay với cấu hình SSL riêng lẻ cho từng framework hay ngôn ngữ. Chỉ cần một cổng Nginx duy nhất, mọi project đều có HTTPS chuẩn chỉ. Chúc các bạn setup thành công!

Share: