Câu Hỏi Thường Gặp (FAQ) về Phối Hợp ServBay & Docker
Khi phát triển web cục bộ với ServBay, bạn có thể muốn kết hợp Docker để tận dụng môi trường container hóa. FAQ này nhằm giải đáp các thắc mắc thường gặp khi sử dụng ServBay cùng Docker, hỗ trợ cả môi trường macOS và Windows, bao gồm cách truy cập dịch vụ của ServBay từ Docker và dùng ServBay làm proxy ngược đến các ứng dụng trong container Docker.
Q1: Tại sao ServBay chỉnh sửa file hosts
của hệ thống? Tôi có thể ngăn điều này không?
ServBay tự động thêm các mục vào file hosts
của hệ thống (ví dụ: mysite.servbay.demo 127.0.0.1
) để bạn có thể truy cập website phát triển cục bộ qua tên miền tùy chỉnh như mysite.servbay.demo
. Các website này thực tế đều chạy trên địa chỉ 127.0.0.1
của máy bạn.
Nhưng do cơ chế của Docker, file hosts từ hệ điều hành (macOS hoặc Windows) có thể được Docker container đọc vào, khiến mysite.servbay.demo
cũng phân giải về 127.0.0.1
– và trong Docker, địa chỉ này lại trỏ đến chính container đó, dẫn đến truy cập sai dịch vụ!
Bản chất vấn đề:
- Khi bạn tạo một website mới trên ServBay và đặt tên miền (ví dụ:
example.servbay.demo
), ServBay sẽ tự động ánh xạ tên miền đó về127.0.0.1
. - Đây là chuẩn thông dụng để truy cập website cục bộ qua domain thân thiện. Nếu không chỉnh sửa file
hosts
, bạn buộc phải dùng dạng địa chỉ nhưhttp://127.0.0.1:PORT
mà không truy cập được bằng tên miền tùy chỉnh.
Có thể ngăn việc này không?
Về lý thuyết, bạn có thể thủ công xóa các dòng ServBay đã thêm, nhưng sẽ làm mất khả năng truy cập website qua tên miền do ServBay cấu hình – đi ngược lại tiện ích mà ServBay cung cấp cho phát triển cục bộ. Một trong các chức năng cốt lõi của ServBay là đơn giản hóa việc tạo và truy cập website cục bộ. Nếu bạn không muốn ServBay quản lý mục hosts cho tên miền nào đó, tốt nhất đừng cấu hình website cho tên miền đó trong ServBay.
Phần lớn các lập trình viên đều mong muốn ServBay tự động quản lý file hosts
, vì nó rất thuận tiện cho phát triển local.
Q2: Làm sao Docker container có thể truy cập đúng website do ServBay quản lý trên máy chủ qua domain (vd: mysite.servbay.demo
)?
Đây là nhu cầu phổ biến, nhưng cần xử lý đúng để tránh lỗi. Khi ServBay chạy một site trên host (như mysite.servbay.demo
ánh xạ tới 127.0.0.1
), thì trong Docker, 127.0.0.1
lại trỏ đến container chứ không phải host.
Cách KHÔNG đúng: Dùng luôn host.docker.internal
làm tên miền trong URL
Docker Desktop trên Mac (và Windows) cung cấp tên DNS đặc biệt host.docker.internal
để container có thể truy cập IP của host. Nhưng KHÔNG NÊN dùng trực tiếp nó trong URL để truy cập website của ServBay (ví dụ, dùng http://host.docker.internal/
thay vì domain thực).
Vì nếu làm vậy, header HTTP Host
sẽ là host.docker.internal
, ServBay web server (Caddy, Nginx...) sẽ không thể định tuyến đến website mong muốn, hoặc trong môi trường HTTPS, sẽ gặp lỗi SNI (Server Name Indication) vì chứng chỉ SSL được cấp cho mysite.servbay.demo
chứ không phải host.docker.internal
.
GIẢI PHÁP đúng: Thêm mapping vào /etc/hosts
của container lúc khởi tạo
Để ứng dụng trong Docker gửi request đúng domain thực (vd: mysite.servbay.demo
) với HTTP Host
chuẩn, bạn nên thêm một dòng hosts bên trong container, ánh xạ domain này về IP host. Có thể làm qua extra_hosts
trong docker-compose.yml
hoặc --add-host
khi dùng docker run
, để trỏ domain về địa chỉ host.docker.internal
hoặc tốt hơn nữa là host-gateway
.
Dùng
docker run
:bashdocker run --add-host=mysite.servbay.demo:host-gateway ... your_image
1(
host-gateway
là giá trị đặc biệt, Docker sẽ ánh xạ nó thành IP nội bộ của host. Từ phiên bản Docker 20.10+, nó là dạng nâng cấp so vớihost.docker.internal
.)Dùng
docker-compose.yml
:yamlversion: '3.8' # hoặc cao hơn services: myapp: image: your_image extra_hosts: - "mysite.servbay.demo:host-gateway" # hoặc "mysite.servbay.demo:host.docker.internal" # ... cấu hình khác
1
2
3
4
5
6
7
Sau khi cấu hình, bên trong Docker container:
- Khi ứng dụng truy cập
http://mysite.servbay.demo
hoặchttps://mysite.servbay.demo
, file/etc/hosts
của container sẽ phân giải domain tới địa chỉ IP của host. - Request sẽ gửi đến web server ServBay chạy trên host.
- HTTP header
Host
sẽ đúng làmysite.servbay.demo
, giúp ServBay router chính xác và cấp đúng chứng chỉ SSL (nếu dùng HTTPS).
Q3: Làm sao container Docker kết nối với database (ví dụ MySQL, PostgreSQL) hoặc các dịch vụ không phải HTTP, do ServBay quản lý?
Khác với truy cập web service qua domain, kết nối tới database hoặc dịch vụ TCP không phụ thuộc SNI, cách khuyến nghị là dùng host.docker.internal
làm hostname của server – đơn giản, hiệu quả.
Các bước:
- Đảm bảo database/ dịch vụ đã được bật trên ServBay, cấu hình cho phép kết nối từ host (thường mặc định OK cho phát triển cục bộ).
- Cấu hình chuỗi kết nối database bên trong Docker container:
- Host (hostname/server): dùng
host.docker.internal
. - Port: dùng port do ServBay thiết lập (MySQL thường là
3306
, PostgreSQL thường là5432
). - Username/password: dùng chính thông tin bạn đã cấu hình trong ServBay.
- Host (hostname/server): dùng
Ví dụ (kết nối MySQL do ServBay quản lý): Giả sử MySQL trên ServBay chạy ở port mặc định 3306
. Kết nối từ ứng dụng trong Docker sẽ là:
- Host:
host.docker.internal
- Port:
3306
- User:
your_db_user
- Password:
your_db_password
Q4: Làm sao để container Docker tin tưởng CA do ServBay cấp khi truy cập HTTPS qua domain với cấu hình extra_hosts
?
Giả sử bạn đã làm đúng hướng dẫn Q2, ánh xạ domain (vd: secure.servbay.demo
) sang host thông qua host-gateway
. Nếu website đó dùng SSL do ServBay User CA cấp, container Docker thường không tự động tin cậy CA này, dẫn đến lỗi handshake SSL.
Vị trí file CA của ServBay:
- ServBay User CA Root Certificate:
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- File PEM tổng hợp các CA của ServBay, Public CA và Mozilla:
- macOS (ARM):
/Applications/ServBay/package/common/openssl/3.2/cacert.pem
- macOS (Intel):
/Applications/ServBay/package/common/openssl/1.1.1u/cacert.pem
- Windows:
C:\ServBay\package\common\openssl\3.3\cacert.pem
- macOS (ARM):
Các giải pháp để Docker container tin tưởng ServBay CA:
- Cách 1: Tin cậy hệ thống cấp ảnh dựng (qua Dockerfile) – tốt cho trường hợp bạn chủ động build lại image và muốn tất cả phần mềm đều tin cậy CA.
- Cách 2: Tin cậy cấp ứng dụng, runtime (qua bind mount và biến môi trường) – phù hợp khi chỉ ứng dụng cụ thể cần trust CA hoặc không muốn build lại image.
- Cách 3: Tin cậy hệ thống cấp runtime (bind mount + lệnh khởi động custom) – khi cần hệ thống container trust CA nhưng không muốn build lại image.
Cách 1: Tin cậy cấp hệ thống khi build Docker image (Dockerfile)
Cách này là tích hợp CA vào kho tin cậy của hệ điều hành ngay khi build image.
- Chuẩn bị file CA: Copy file ServBay User CA vào thư mục context (cùng Dockerfile):
- macOS:
/Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt
- Windows:
C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt
- macOS:
- Dockerfile ví dụ (Debian/Ubuntu):dockerfile
# Dockerfile FROM ubuntu:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \ update-ca-certificates && \ rm -rf /var/lib/apt/lists/*
1
2
3
4
5
6 - Dockerfile ví dụ (Alpine):dockerfile
# Dockerfile FROM alpine:latest COPY ServBay-Private-CA-ECC-Root.crt /usr/local/share/ca-certificates/ServBay-User-CA.crt RUN apk add --no-cache ca-certificates && update-ca-certificates
1
2
3
4 - Docker Compose build:yaml
# docker-compose.yml version: '3.8' services: myapp: build: context: ./app_service # chứa Dockerfile & ServBay-Private-CA-ECC-Root.crt dockerfile: Dockerfile extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
Cách 2: Tin cậy CA cấp ứng dụng (bind mount + biến môi trường)
Bind mount file CA vào container, cấu hình ứng dụng cụ thể dựa vào biến môi trường để tin cậy CA new này.
- Ví dụ
docker-compose.yml
:yamlCần kiểm tra tài liệu của ứng dụng để biết chính xác biến môi trường cần dùng.version: '3.8' services: myapp: image: some-base-image volumes: # Đường dẫn macOS mẫu - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro # Đường dẫn Windows mẫu (tùy OS thực tế) # - C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt:/etc/ssl/certs/MyCustomCA.crt:ro environment: # Ví dụ cho Node.js: - NODE_EXTRA_CA_CERTS=/etc/ssl/certs/MyCustomCA.crt # Python (requests): # - REQUESTS_CA_BUNDLE=/etc/ssl/certs/MyCustomCA.crt # SSL_CERT_FILE tổng quát: # - SSL_CERT_FILE=/etc/ssl/certs/MyCustomCA.crt extra_hosts: ["secure.servbay.demo:host-gateway"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Cách 3: Tin cậy cấp hệ thống khi runtime (bind mount + custom command)
Bind mount file CA và thực hiện thêm thủ tục cập nhật kho tin cậy lúc khởi động container, không cần build lại image.
- Ví dụ
docker-compose.yml
(Debian/Ubuntu):yamlLưu ý:version: '3.8' services: myapp: image: ubuntu:latest # miễn là image có thể chạy update-ca-certificates volumes: # Bind file CA từ host sang container đúng thư mục # macOS mẫu - /Applications/ServBay/ssl/private/ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # Windows mẫu (tùy OS thực tế) # - C:\ServBay\ssl\private\ServBay-Private-CA-ECC-Root.crt:/usr/local/share/ca-certificates/ServBay-User-CA.crt:ro # Đổi command để khi startup thì update CA rồi chạy app # Nhớ container phải chạy bằng user có quyền (thường là root) command: > sh -c " echo 'Attempting to update CA certificates...' && if command -v update-ca-certificates > /dev/null; then if [ ! -f /usr/bin/update-ca-certificates ]; then apt-get update && apt-get install -y --no-install-recommends ca-certificates; fi && update-ca-certificates && echo 'CA certificates updated.' else echo 'update-ca-certificates command not found, skipping CA update.' fi && echo 'Starting application...' && exec your_original_application_command_here # Thay bằng CMD gốc của image/app bạn " extra_hosts: ["secure.servbay.demo:host-gateway"] # Nếu cần quyền root cho update-ca-certificates nhưng ứng dụng chạy bằng non-root, nên dùng entrypoint script phức tạp hơn # user: root # hoặc xử lý quyền bằng script riêng
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28- Độ phức tạp: Sửa lệnh
command
hoặcentrypoint
có thể khá rắc rối với những image chứa logic khởi động phức tạp. Đảm bảo app của bạn vẫn chạy đúng. - Quyền hạn:
update-ca-certificates
cần quyền root. Nếu mặc định chạy bằng non-root, thao tác này có thể bị lỗi. - Phụ thuộc: Cần đảm bảo có sẵn các tiện ích (
ca-certificates
,update-ca-certificates
) trong image. Script ví dụ trên sẽ tự cài (nếu dùng hệ apt). - Thời gian khởi động: Mỗi lần khởi động đều chạy check & update sẽ mất thêm thời gian.
- Alpine Linux: Nếu dùng Alpine, lệnh thay bằng
apk add --no-cache ca-certificates && update-ca-certificates
.
- Độ phức tạp: Sửa lệnh
Chọn cách nào?
- Nếu chủ động build lại image và muốn mọi phần mềm đều trust CA, cách 1 là tốt nhất.
- Nếu không muốn sửa image, chỉ app riêng biệt trust CA, cách 2 nhanh gọn.
- Nếu không build image, không muốn thay thế hệ thống, vẫn cần cấp hệ thống trust CA, cách 3 là hợp lý.
Với chứng chỉ của các CA phổ thông (Let's Encrypt, v.v.): Nếu website ServBay dùng ACME để lấy SSL cert từ public CA (vd: Let's Encrypt), hầu hết các image Docker đều đã trust sẵn các CA này – không cần cấu hình gì thêm.
Q5: Làm sao dùng ServBay để đặt tên miền & proxy ngược đến ứng dụng bên trong Docker container?
Bạn có thể chạy ứng dụng trong Docker container (ví dụ Node.js trên port 3000 container), muốn gán tên miền đẹp (vd: myapp.servbay.demo
) để truy cập từ browser, và sử dụng chứng chỉ SSL do ServBay cấp.
Các bước:
Chạy Docker container & ánh xạ port về 127.0.0.1 trên host: Đảm bảo application trong container được publish port sang host qua IP
127.0.0.1
, giúp port chỉ accessible ở môi trường local trên host, bảo vệ khỏi truy cập ngoài.bash# Ví dụ app trong container nghe port 3000, ánh xạ về port 3001 của host docker run -d -p 127.0.0.1:3001:3000 your-docker-app-image
1
2App trong container sẽ lắng nghe ở
3000
, còn host thì truy cập app quahttp://127.0.0.1:3001
.Thêm mới website trên ServBay và cấu hình proxy ngược:
- Mở giao diện quản trị ServBay.
- Click “Thêm website”.
- Domain: Gõ tên miền muốn dùng (vd:
myapp.servbay.demo
). - Loại website: Chọn “Proxy ngược” từ menu.
- IP: Nhập
127.0.0.1
. - Port: Nhập đúng port đã ánh xạ (vd:
3001
). - Nhấn “Lưu” hoặc “Thêm”.
(Tùy chọn) Cấu hình SSL: Sau khi thêm site, vào cài đặt website để bật SSL. ServBay hỗ trợ tự động xin chứng chỉ Let's Encrypt từ các CA công cộng qua ACME, hoặc bạn có thể dùng ServBay User CA/Public CA. ServBay sẽ xử lý SSL termination, kết nối từ ServBay sang container bên dưới dùng HTTP (không cần SSL, ví dụ
http://127.0.0.1:3001
).Kiểm tra truy cập: Sau khi cấu hình xong, bạn có thể truy cập browser tại
http://myapp.servbay.demo
hoặchttps://myapp.servbay.demo
(nếu đã bật SSL). ServBay sẽ proxy request tới app trong Docker container.
Luồng hoạt động: Trình duyệt người dùng ->
https://myapp.servbay.demo
->
ServBay (xử lý SSL, proxy) ->
http://127.0.0.1:3001
(port trên host) ->
ứng dụng bên trong Docker container.
Tổng Kết
ServBay làm đơn giản hóa tối đa quy trình phát triển web cục bộ trên macOS và Windows. Khi dùng kèm Docker:
- Để truy cập website ServBay từ Docker container, dùng
extra_hosts
hoặc--add-host
ánh xạ domain vềhost-gateway
, đảm bảo headerHost
đúng và tránh lỗi SNI. - Để truy cập database hoặc dịch vụ không phải HTTP từ Docker, dùng
host.docker.internal
làm hostname là nhanh, ổn định. - Để Docker container tin tưởng chứng chỉ SSL do ServBay User CA cấp, cần copy CA vào image hoặc mount vào container và cập nhật kho tin cậy.
- Để proxy ngược ứng dụng trong container qua ServBay, tạo site kiểu “proxy ngược” và trỏ về port Docker đã ánh xạ sang host
127.0.0.1
.
Luôn đảm bảo các phần mềm liên quan trong ServBay (web server, database, v.v.) và Docker container đều được cấu hình đúng và đang hoạt động để phát triển thuận lợi trên môi trường local.