Odoo và PostgreSQL là hai thứ khác nhau: một tiến trình Odoo có thể phục vụ nhiều database cùng lúc trên cùng một PostgreSQL. Tiện cho hosting nhiều khách hàng, nhưng nếu không cấu hình đúng, máy chủ sẽ hiện danh sách mọi database cho bất kỳ ai vào — lộ thông tin và mời gọi rắc rối. Bài này mở đầu chương vận hành, giải quyết đúng chuyện đó bằng --db-filter.

Thực tế: nhiều database trên một máy chủ

Tôi đã tạo thêm một database Odoo thứ hai (shop19) bên cạnh blog19 của loạt bài, cùng nằm trên PostgreSQL odoo19-db:

Sơ đồ một máy chủ Odoo phục vụ nhiều database chọn bằng db-filter: thực tế có hai database Odoo trên PostgreSQL là blog19 với res_users bằng 7 và shop19 với res_users bằng 4, cùng database hệ thống postgres; vấn đề là để trống filter thì Odoo hiện danh sách chọn db làm lộ tên database, cờ -d chỉ là mặc định chứ không khoá; giải pháp là db-filter nhận một biểu thức chính quy chọn database theo tên, ví dụ db-filter mũ blog19 đô la chỉ phục vụ đúng blog19, hoặc ghép ký hiệu phần trăm h là host và phần trăm d là subdomain để một tiến trình phục vụ nhiều site như blog.congty.vn chọn db blog và shop.congty.vn chọn db shop; chốt an toàn cho production trong odoo.conf gồm dbfilter mũ blog19 đô la, list_db bằng False để tắt trang liệt kê và trình quản lý, và admin_passwd đặt mật khẩu chủ để khoá Manage databases

Hình 1: Hai database Odoo thật (blog19 có 7 người dùng, shop19 có 4) trên cùng PostgreSQL. Cờ -d chỉ đặt database mặc định chứ không khoá — nếu bật liệt kê, khách vẫn thấy và chọn được database khác. --db-filter mới là thứ giới hạn database nào được phục vụ.

Vấn đề: trang chọn database

Khi có nhiều database và không lọc, Odoo hiện một trang chọn database cho mọi người vào. Đây là ảnh thật của máy chủ loạt bài (chưa cấu hình filter):

Ảnh chụp thật trang chọn database của Odoo 19: logo Odoo ở trên, một khung cảnh báo màu vàng ghi Warning your Odoo database manager is not protected please set a master password to secure it, bên dưới là danh sách hai database blog19 và shop19 dạng link bấm được, và dòng Manage databases để vào trình quản lý database

Hình 2: Trang chọn database thật — nó liệt kê cả blog19 lẫn shop19 cho bất kỳ ai truy cập, kèm cảnh báo vàng "database manager chưa được bảo vệ". Trên production, đây là điều không được phép: lộ tên database và mở cửa trình quản lý (tạo/xoá/sao lưu db).

Giải pháp: --db-filter là một regex

--db-filter nhận một biểu thức chính quy; chỉ database có tên khớp mới được phục vụ:

# Chỉ phục vụ đúng blog19, không hiện database nào khác
odoo --db-filter='^blog19$' -d blog19

Sức mạnh thật sự là ghép với tên miền. Odoo thay hai ký hiệu đặc biệt trong filter:

  • %h → hostname đầy đủ của request (ví dụ blog.congty.vn).
  • %d → subdomain (phần đầu tiên, ví dụ blog).
# Một tiến trình Odoo phục vụ nhiều site, mỗi tên miền một database
odoo --db-filter='^%d$'
#   blog.congty.vn  → chọn database "blog"
#   shop.congty.vn  → chọn database "shop"

Đây chính là cách một máy chủ Odoo hosting nhiều khách hàng: mỗi khách một database, tự động chọn đúng theo tên miền họ truy cập.

Chốt an toàn cho production

Chỉ db-filter chưa đủ. Trong odoo.conf production nên có đủ ba dòng:

[options]
dbfilter = ^blog19$
list_db = False          ; tắt trang liệt kê + trình quản lý database
admin_passwd = <mật khẩu chủ mạnh>  ; khoá "Manage databases"
  • dbfilter: giới hạn database được phục vụ.
  • list_db = False: tắt hẳn trang liệt kê và trình quản lý — khách không thấy database nào, không vào được trình tạo/xoá.
  • admin_passwd: mật khẩu chủ, khoá các thao tác quản lý database. Cảnh báo vàng ở Hình 2 chính là vì thiếu cái này.

Vài lệnh quản lý nhiều database

odoo -d blog19 -u quan_ca_phe --stop-after-init   # nâng cấp 1 module trên 1 db
docker exec odoo19-db psql -U odoo -d postgres \
  -c "SELECT datname FROM pg_database WHERE datistemplate=false;"  # liệt kê db

Lưu ý: không dùng -i/-u với nhiều database cùng lúc (-d db1,db2) — Odoo báo lỗi, vì cài/nâng cấp phải làm từng database một.

Nhớ ba ý

  1. Một tiến trình Odoo phục vụ nhiều database trên cùng PostgreSQL; -d chỉ đặt mặc định, không khoá.
  2. --db-filter là regex chọn database được phục vụ; ghép %h/%d để tự chọn database theo tên miền — nền tảng của hosting đa khách hàng.
  3. Production phải đủ bộ ba: dbfilter + list_db = False + admin_passwd để không lộ danh sách và khoá trình quản lý database.

Một máy chủ phục vụ nhiều database rồi, còn khi cần chạy nhiều phiên bản Odoo khác nhau trên cùng một máy thì sao? Phần sau hướng dẫn chạy nhiều phiên bản Odoo song song bằng cổng và cấu hình tách biệt.