Thực tế hay gặp: bạn phải bảo trì Odoo 17 cho một khách cũ, đồng thời phát triển dự án mới trên Odoo 19 — cả hai trên cùng một máy chủ. Hoặc đơn giản là muốn một instance "chạy thật" và một instance "thử nghiệm" tách biệt. Chuyện này hoàn toàn làm được: Odoo không "độc chiếm" máy, chỉ cần mỗi bản dùng tài nguyên riêng. Sau bài nhiều database, đây là bước tách xa hơn — nhiều tiến trình Odoo.
Phân biệt hai khái niệm
- Nhiều database, một Odoo: một tiến trình phục vụ nhiều db (bài trước). Chỉ hợp khi các db dùng cùng phiên bản Odoo và cùng bộ module.
- Nhiều instance Odoo: nhiều tiến trình độc lập, có thể khác phiên bản (17 vs 19), khác bộ addons. Đây là nội dung bài này.
Khi cần chạy hai phiên bản Odoo khác nhau, bắt buộc phải là nhiều instance.
Ba thứ phải khác nhau
Mỗi instance là một tiến trình riêng, và ba thứ tuyệt đối không được đụng nhau:

Hình 1: Hai file cấu hình cho hai instance. Ba thứ bắt buộc khác: (1) http_port + gevent_port — hai instance nghe cùng cổng sẽ đụng nhau; (2) data_dir — nơi chứa session và filestore, dùng chung là ghi đè lên nhau; (3) db_name/db-filter — để mỗi bản đúng database của nó.
Chạy thật — hai instance cùng lúc
Tôi khởi chạy một instance Odoo thứ hai (trỏ shop19, cổng 8070) bên cạnh instance chính (blog19, cổng 8069), và đây là bằng chứng thật:

Hình 2: Bằng chứng thật. ps cho thấy hai tiến trình master độc lập — PID 1 (cổng 8069, blog19) và PID 702 (cổng 8070, shop19, với --http-port=8070 --gevent-port=8073 --db-filter=^shop19$). Cả hai cổng đều trả HTTP 200. Hai bản chạy song song, hoàn toàn tách biệt.
nginx đứng trước: mỗi tên miền một instance
Người dùng không gõ cổng. Bạn đặt nginx phía trước, mỗi tên miền proxy vào một instance:
server {
server_name blog.congty.vn;
location / { proxy_pass http://127.0.0.1:8069; }
}
server {
server_name shop.congty.vn;
location / { proxy_pass http://127.0.0.1:8070; }
}
Cần cấu hình proxy đúng (WebSocket cho cổng gevent, header X-Forwarded-*) — đây cũng đúng mô hình mà blog này đang chạy trên máy chủ thật.
Cách gọn hơn: mỗi instance một container
Với Docker, thay vì tự quản cổng và data_dir, bạn cho mỗi instance một container — cách ly hoàn toàn:
services:
odoo17:
image: odoo:17
ports: ["8069:8069"]
volumes: ["./o17-data:/var/lib/odoo", "./o17-addons:/mnt/extra-addons"]
odoo19:
image: odoo:19
ports: ["8070:8069"] # ánh xạ ra cổng host khác
volumes: ["./o19-data:/var/lib/odoo", "./o19-addons:/mnt/extra-addons"]
Mỗi container có phiên bản, addons, và data_dir riêng — không lo đụng nhau. Đây là lý do Docker rất hợp để chạy nhiều phiên bản Odoo.
Những cái bẫy
- Quên đổi
data_dir: hai instance ghi đè session/filestore của nhau — lỗi lạ, ảnh mất. - Quên
gevent_port: cổng longpolling/websocket mặc định 8072 cũng phải khác giữa các bản. - Chung PostgreSQL: các instance có thể dùng chung một PostgreSQL (khác database), hoặc mỗi bản một server — tuỳ tải. Dùng chung thì nhớ đủ
db_maxconn.
Nhớ ba ý
- Nhiều database ≠ nhiều instance: khác phiên bản Odoo (17 vs 19) thì bắt buộc nhiều tiến trình riêng.
- Ba thứ phải khác nhau giữa các bản:
http_port+gevent_port,data_dir, và database — tôi đã chứng minh 2 bản chạy thật trên cổng 8069/8070. - Đặt nginx phía trước để map tên miền → instance; hoặc gọn hơn, mỗi instance một container Docker để cách ly hoàn toàn.
Đã biết chạy nhiều instance, ta quay lại làm cho môi trường dev thật tiện. Phần sau dựng một Docker Compose cho dev với addons mount nóng — sửa code trên máy, container thấy ngay.