建與權(quán)限配置實戰(zhàn))
簡介本資源是一份面向企業(yè)級Odoo運維工程師與SaaS平臺架構(gòu)師的實戰(zhàn)部署指南聚焦基于Docker的多租戶Odoo實例自動化管理方案解決中小企業(yè)快速交付定制化SaaS服務、統(tǒng)一維護數(shù)百租戶環(huán)境及實現(xiàn)訂閱制計費等核心痛點。內(nèi)容涵蓋Python依賴安裝docker/erppeek/paramiko、Odoo-SaaS-Data等關鍵目錄結(jié)構(gòu)搭建、Nginx虛擬主機與PostgreSQL配置、基礎Docker鏡像構(gòu)建含UID/GID對齊要點、遠程容器部署支持及SaaS訂閱計劃配置全流程并提供模塊上傳、域名管理、日志排查、備份恢復等高頻運維場景的排錯思路。資源為1個3.99MB的PDF文檔內(nèi)容完整覆蓋環(huán)境準備、安裝步驟、權(quán)限配置、測試驗證與常見問題處理結(jié)構(gòu)清晰、指令明確適合作為生產(chǎn)環(huán)境部署前的標準化參考手冊。目前已有140人學習下載適合具備Linux服務器管理、Odoo二次開發(fā)及基礎Docker經(jīng)驗的技術(shù)人員深度研讀與落地實施。1. Odoo SaaS Kit 不是“一鍵部署”而是你親手搭出來的多租戶黑匣子它把每個客戶塞進獨立 Docker 容器用 Nginx 做門衛(wèi)、PostgreSQL 當賬房、Odoo 當掌柜——但凡一個 UID 沒對齊、一個 vhost 模板少個斜杠、一個 saas.conf 路徑寫錯整個租戶系統(tǒng)就卡在“創(chuàng)建中…”不動彈。這不是插件安裝是基礎設施編排不靠點擊向?qū)Э磕銓ocker build的耐心、對/etc/sudoers的敬畏、對pg_hba.confCIDR 規(guī)則的肌肉記憶。適合剛從單體 Odoo 運維跳出來、正被客戶反復問“能不能給我單獨一個后臺”的工程師——你得信自己能管住 50 個容器、200 個數(shù)據(jù)庫、300 個子域名而不是指望某個按鈕替你扛下所有邊界條件。2. 從零構(gòu)建 Odoo SaaS 基礎鏡像Dockerfile 里藏了三個必須死磕的硬核細節(jié)Odoo SaaS Kit 的核心不是 Python 模塊是那個被docker build編譯出來的基礎鏡像。它不是官方 Odoo 鏡像的簡單復刻而是一套嚴格對齊宿主機環(huán)境的“鏡像契約”。一旦鏡像 UID/GID 錯位、entrypoint 權(quán)限缺失、或配置路徑硬編碼錯誤后續(xù)所有客戶端容器都會在啟動時靜默失敗——日志里只有一行Permission denied連報錯堆棧都不給你。下面這三步每一步都踩過血淚坑不能跳。2.1 UID/GID 對齊為什么你的容器永遠掛載不了 /var/lib/odoo/dataOdoo SaaS Kit 的設計哲學是宿主機上的文件所有權(quán)必須和容器內(nèi)完全一致。它不走 volume 綁定的“寬松模式”而是用-v /host/path:/container/path:z強制映射且要求chown -R odoo:odoo /host/path后容器內(nèi)id -u odoo必須等于宿主機id -u odoo。否則容器內(nèi) Odoo 進程根本打不開odoo.conf更別說寫入 session 或附件。提示別查whoami查/etc/passwd。執(zhí)行g(shù)rep odoo /etc/passwd拿到類似odoo:x:998:998::/opt/odoo:/bin/bash:/sbin/nologin的行其中998:998就是你要死記的 UID:GID。在 Dockerfile 開頭必須顯式聲明用戶 ID# Dockerfile FROM ubuntu:20.04 # 關鍵必須與宿主機 odoo 用戶 UID/GID 嚴格一致 ARG ODIO_UID998 ARG ODIO_GID998 # 創(chuàng)建同名用戶組和用戶UID/GID 硬編碼 RUN groupadd -g ${ODIO_GID} odoo \ useradd -m -u ${ODIO_UID} -g ${ODIO_GID} -s /bin/bash odoo # 切換到 odoo 用戶后續(xù)所有 RUN、CMD 都在此上下文 USER odoo:odoo參數(shù)說明ARG ODIO_UID/GID是構(gòu)建時傳入的變量方便不同環(huán)境復用同一份 Dockerfilegroupadd -g和useradd -u中的-g-u參數(shù)強制指定 GID/UID避免系統(tǒng)自動分配USER odoo:odoo必須放在所有RUN apt install之后、COPY之前——因為apt install需要 root但COPY --chownodoo:odoo后的文件必須由USER指定的用戶來讀取。2.2 entrypoint.sh那個被忽略的“容器啟動守門人”O(jiān)doo SaaS Kit 不直接docker run odoo:14.0而是通過自定義entrypoint.sh控制整個生命周期。這個腳本干三件事校驗配置路徑、動態(tài)生成odoo.conf、檢查 PostgreSQL 連通性。如果它沒被執(zhí)行或者權(quán)限不對容器會秒退docker logs里空空如也。先確保entrypoint.sh在宿主機上具備可執(zhí)行權(quán)限并歸屬 odoo 用戶# 在宿主機執(zhí)行假設 Dockerfile 和 entrypoint.sh 同目錄 chmod x entrypoint.sh chown odoo:odoo entrypoint.shDockerfile 中必須 COPY 并設權(quán)# Dockerfile續(xù) COPY --chownodoo:odoo entrypoint.sh /home/odoo/entrypoint.sh RUN chmod x /home/odoo/entrypoint.sh # 設置入口點注意不是 CMD ENTRYPOINT [/home/odoo/entrypoint.sh]entrypoint.sh的關鍵邏輯節(jié)選帶注釋#!/bin/bash # entrypoint.sh # 1. 校驗 saas.conf 是否存在且可讀這是 odoo_saas_kit 模塊的配置中樞 if [ ! -f /home/odoo/saas.conf ]; then echo ERROR: /home/odoo/saas.conf not found. This is required by Odoo SaaS Kit. exit 1 fi # 2. 動態(tài)生成 odoo.conf從模板注入 client_id、db_host、db_port 等運行時參數(shù) # SaaS Kit 在創(chuàng)建容器時會通過 --env 注入這些變量 cat /etc/odoo/odoo.conf EOF [options] admin_passwd ${ADMIN_PASSWD:-change_me} db_host ${DB_HOST:-localhost} db_port ${DB_PORT:-5432} db_user ${DB_USER:-odoo} db_password ${DB_PASSWORD:-odoo} addons_path /usr/lib/python3/dist-packages/odoo/addons,/mnt/extra-addons data_dir /var/lib/odoo logfile /var/log/odoo/odoo-server.log log_level info EOF # 3. 等待 PostgreSQL 就緒避免容器啟動快于 DB導致 Odoo 初始化失敗 until pg_isready -h ${DB_HOST:-localhost} -p ${DB_PORT:-5432} -U ${DB_USER:-odoo}; do echo Waiting for PostgreSQL at ${DB_HOST:-localhost}:${DB_PORT:-5432}... sleep 2 done # 4. 最終執(zhí)行 Odoo 啟動命令 exec /usr/bin/odoo $參數(shù)說明--env注入的變量如DB_HOST,ADMIN_PASSWD必須與odoo_saas_kit模塊在調(diào)用docker run時傳入的完全一致pg_isready是 PostgreSQL 自帶的健康檢查工具比sleep 10可靠十倍exec是關鍵它用 Odoo 進程替換當前 shell 進程保證docker stop能正常發(fā)送 SIGTERM。2.3 構(gòu)建與推送docker build命令末尾那個點不是裝飾構(gòu)建命令本身極簡但路徑、上下文、標簽三者必須咬合# 切換到 Dockerfile 所在目錄絕對路徑 cd /opt/odoo/docker-build/ # 構(gòu)建命令注意最后的 . 是當前目錄上下文不可省略 docker build \ --build-arg ODIO_UID998 \ --build-arg ODIO_GID998 \ -t odoosaas:14.0-ubuntu20.04 \ . # 驗證鏡像是否包含正確用戶 docker run --rm odoosaas:14.0-ubuntu20.04 id -u odoo # 應輸出 998 docker run --rm odoosaas:14.0-ubuntu20.04 ls -l /etc/odoo/odoo.conf # 應顯示 odoo:odoo 所有者常見失敗現(xiàn)象與排查docker build報錯unable to prepare context: path .../Dockerfile not found→ 檢查當前目錄是否真有DockerfileLinux 區(qū)分大小寫構(gòu)建成功但docker run啟動即退出 →docker logs container_id查看90% 是entrypoint.sh權(quán)限問題或saas.conf路徑錯誤docker run啟動后ps aux | grep odoo沒進程 →docker exec -it container_id bash進去手動執(zhí)行sh -x /home/odoo/entrypoint.sh看哪一行卡住。3. Odoo 服務賬戶提權(quán)給 odoo 用戶開三把鎖一把都不能少Odoo SaaS Kit 的模塊代碼運行在 Odoo 進程內(nèi)但它要干的事遠超普通業(yè)務邏輯它要調(diào)用docker命令創(chuàng)建容器、要sudo nginx -t sudo systemctl reload nginx重載虛擬主機、還要psql連 PostgreSQL 創(chuàng)建數(shù)據(jù)庫。默認的odoo用戶什么權(quán)限都沒有——你得親手給它開三把鎖缺一不可。3.1 Docker 組權(quán)限讓 odoo 用戶成為容器調(diào)度員Docker 守護進程默認只允許root或docker組成員操作。odoo_saas_kit模塊底層調(diào)用的是docker-pyPython 的 Docker SDK它最終會觸發(fā)docker.sock的 Unix socket 通信。所以必須把odoo用戶加進docker組# 添加用戶到 docker 組立即生效需重新登錄或重啟 odoo 服務 sudo usermod -a -G docker odoo # 驗證切換到 odoo 用戶測試能否列出鏡像 sudo -u odoo docker images # 若報錯 Got permission denied...說明組未生效執(zhí)行 newgrp docker # 臨時刷新組權(quán)限僅當前 shell注意newgrp docker只影響當前終端會話。生產(chǎn)環(huán)境務必重啟 Odoo 服務sudo systemctl restart odoo讓 Odoo 進程以新組權(quán)限啟動。3.2 Nginx 免密控制讓 odoo 用戶能 reload 配置而不輸密碼SaaS Kit 在創(chuàng)建客戶端時會自動生成 Nginx 虛擬主機配置如/opt/odoo/Odoo-SAAS-Data/docker_vhosts/client1.example.com.conf然后執(zhí)行sudo nginx -t sudo systemctl reload nginx。這意味著odoo用戶必須被授權(quán)執(zhí)行這兩條命令且無需密碼。編輯/etc/sudoers必須用visudo禁止直接 vimsudo visudo在文件末尾添加嚴格按格式空格和標點不能錯# 允許 odoo 用戶免密執(zhí)行 nginx 測試和重載 odoo ALL(ALL) NOPASSWD: /usr/sbin/nginx -t, /bin/systemctl reload nginx驗證方式切到 odoo 用戶執(zhí)行sudo -u odoo sudo nginx -t # 應輸出 syntax is ok sudo -u odoo sudo systemctl reload nginx # 應無報錯Nginx 配置熱更新提示systemctl reload nginx在 Ubuntu 20.04 是安全的它等價于nginx -s reload不會中斷現(xiàn)有連接。3.3 PostgreSQL 數(shù)據(jù)庫權(quán)限不只是登錄是建庫建用戶的權(quán)力SaaS Kit 創(chuàng)建客戶端時會連接 PostgreSQL 并執(zhí)行CREATE DATABASE client1;和CREATE USER client1 WITH PASSWORD xxx;。這意味著odoo用戶連接 PostgreSQL 時必須擁有CREATEDB和CREATEROLE權(quán)限。登錄 PostgreSQL用 postgres 用戶sudo -u postgres psql執(zhí)行授權(quán)假設你的 PostgreSQL 超級用戶是postgresSaaS Kit 連接用的用戶是odoo-- 確保 odoo 用戶存在若不存在則創(chuàng)建 CREATE USER odoo WITH PASSWORD your_strong_password; -- 授予創(chuàng)建數(shù)據(jù)庫和角色的權(quán)限 ALTER USER odoo CREATEDB CREATEROLE; -- 驗證 \du odoo -- 輸出中應看到 Create DB 和 Create role 為 true同時必須修改 PostgreSQL 的訪問控制文件pg_hba.conf允許odoo用戶從 Docker 網(wǎng)絡通常是172.17.0.0/16連接# 編輯 /etc/postgresql/*/main/pg_hba.conf在末尾添加 # TYPE DATABASE USER ADDRESS METHOD host all odoo 172.17.0.0/16 md5 host all odoo 127.0.0.1/32 md5然后重載配置sudo systemctl reload postgresql避坑 / 常見問題 / 排查現(xiàn)象SaaS Kit 創(chuàng)建客戶端時卡在 “Creating database…” 10 分鐘日志里只有psycopg2.OperationalError: timeout expired原因pg_hba.conf沒加172.17.0.0/16規(guī)則或postgresql.conf中l(wèi)isten_addresses沒設為localhost,127.0.0.1默認只監(jiān)聽本地 socket解決檢查sudo cat /etc/postgresql/*/main/postgresql.conf | grep listen_addresses確保為listen_addresses localhost,127.0.0.1再確認pg_hba.conf規(guī)則已加并重載?,F(xiàn)象sudo -u odoo docker images正常但 Odoo 后臺點擊“創(chuàng)建客戶端”報錯Command docker not found原因odoo用戶的$PATH環(huán)境變量里沒有/usr/binDocker 二進制通常在此解決編輯/etc/systemd/system/odoo.service在[Service]段添加EnvironmentPATH/usr/local/bin:/usr/bin:/bin然后sudo systemctl daemon-reload sudo systemctl restart odoo?,F(xiàn)象Nginx 虛擬主機配置生成了但sudo nginx -t報錯unknown directive upstream原因odoo_saas_kit生成的.conf文件里用了upstream塊但你的 Nginx 編譯時沒啟用http_upstream_module極少見但某些精簡版鏡像會有解決nginx -V 21 | grep -o with-http_upstream_module若無輸出則重裝標準 Nginxsudo apt install --reinstall nginx-full。現(xiàn)象odoo_saas_kit模塊安裝后后臺“SaaS 服務器”配置頁空白F12 看 Network 有 500 錯誤原因saas.conf文件路徑配置錯誤或odoo_saas_kit/models/lib/saas.conf里寫的nginx_vhosts /wrong/path導致 Python 讀取失敗解決進入 Odoo 服務端 Python shellsudo -u odoo python3 -c from odoo_saas_kit.models.lib import saas; print(saas.nginx_vhosts)確認路徑是否真實存在且odoo用戶可讀。4. SaaS 服務器與遠程節(jié)點配置跨服務器部署不是加臺機器是重建信任鏈Odoo SaaS Kit 支持“主控服務器 多臺遠程計算節(jié)點”的架構(gòu)。但這不是簡單的docker run分發(fā)而是一整套 SSH、Docker、PostgreSQL 的信任鏈重建。主服務器上的odoo_saas_kit模塊會通過paramiko庫 SSH 登錄遠程服務器再調(diào)用其本地docker命令。任何一環(huán)斷開遠程部署就變成灰色按鈕。4.1 遠程服務器初始化UID/GID 必須和主服務器 odoo 用戶完全一致這是跨服務器部署的第一鐵律。遠程服務器上新建的odoo用戶UID/GID 必須和主服務器odoo用戶一模一樣。否則當主服務器通過paramiko執(zhí)行docker run -v /host/path:/container/path時容器內(nèi)進程會因 UID 不匹配而無法讀寫掛載卷。在遠程服務器上執(zhí)行假設主服務器odooUID998, GID998# 創(chuàng)建系統(tǒng)用戶UID/GID 強制指定 sudo adduser --system --home /opt/odoo --shell /bin/bash --uid 998 --gid 998 odoo # 設置密碼SaaS Kit 用密碼 SSH不用密鑰 sudo passwd odoo # 安裝 Docker同主服務器步驟 curl -fsSL https://get.docker.com | sh sudo usermod -aG docker odoo提示--system創(chuàng)建的是無登錄 shell 的系統(tǒng)用戶符合 Odoo 生產(chǎn)部署規(guī)范--home /opt/odoo路徑必須和主服務器一致因為odoo_saas_kit模塊會硬編碼該路徑生成配置。4.2 Docker 守護進程暴露tcp://0.0.0.0:2375 是把雙刃劍odoo_saas_kit調(diào)用docker-py連接遠程 Docker 守護進程用的是 TCP 協(xié)議docker://tcp://remote-ip:2375。這意味著遠程服務器的 Docker 必須監(jiān)聽 TCP 端口而非默認的 Unix socket。修改/lib/systemd/system/docker.service# 找到 ExecStart 行改為 ExecStart/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375然后重載并重啟sudo systemctl daemon-reload sudo systemctl restart docker但暴露 2375 端口極其危險必須立即配置防火墻只允許主服務器 IP 訪問# Ubuntu UFW假設主服務器內(nèi)網(wǎng) IP 是 192.168.1.100 sudo ufw allow from 192.168.1.100 to any port 2375 sudo ufw enable提示ufw status verbose可查看規(guī)則是否生效。若用 iptables命令為sudo iptables -A INPUT -p tcp --dport 2375 -s 192.168.1.100 -j ACCEPT。4.3 主服務器連接測試用 Python 腳本代替 Odoo 后臺點點點在主服務器上寫一個最小化測試腳本繞過 Odoo 框架直連遠程 Docker驗證鏈路是否打通# test_remote_docker.py import docker # 替換為你的遠程服務器 IP 和端口 client docker.DockerClient(base_urltcp://192.168.1.200:2375) try: # 列出遠程鏡像驗證連接 images client.images.list() print(f? 連接成功遠程有 {len(images)} 個鏡像) # 嘗試拉取一個輕量鏡像可選 # client.images.pull(alpine:latest) # print(? alpine:latest 拉取成功) except Exception as e: print(f? 連接失敗{e})執(zhí)行sudo -u odoo python3 test_remote_docker.py只有這個腳本能跑通SaaS Kit 的遠程部署才可能成功。后臺配置里的“測試連接”按鈕本質(zhì)就是跑這段邏輯。5. SaaS 訂閱計劃與客戶端實例從“創(chuàng)建模板”到“客戶收到郵件”的全鏈路拆解SaaS Kit 的商業(yè)閉環(huán)始于一個訂閱計劃Plan終于一封發(fā)給客戶的激活郵件。但中間每一步都是可編程的模板數(shù)據(jù)庫的初始化、客戶端容器的啟動參數(shù)、Nginx 虛擬主機的動態(tài)生成、甚至郵件內(nèi)容里的重置密碼鏈接。這一章我們拆開odoo_saas_kit模塊里最關鍵的三個動作創(chuàng)建模板、創(chuàng)建客戶端、發(fā)送郵件。5.1 創(chuàng)建數(shù)據(jù)庫模板不是備份還原是 Odoo 的“全新安裝 模塊預裝”點擊“創(chuàng)建數(shù)據(jù)庫模板”按鈕odoo_saas_kit實際執(zhí)行的是調(diào)用erppeek連接 PostgreSQL執(zhí)行CREATE DATABASE plan_template_123;啟動一個臨時 Odoo 容器用你配置的odoo_image連接此新庫在該容器內(nèi)執(zhí)行odoo-bin -d plan_template_123 --init base,web,mail,hr,...--init后跟你在 Plan 中勾選的“相關模塊”初始化完成后停掉臨時容器模板庫plan_template_123就緒。關鍵參數(shù)在 Plan 配置頁數(shù)據(jù)庫模板字段填my_plan_template則庫名是my_plan_template留空則自動生成plan_template_123相關模塊這里勾選的模塊會作為--init參數(shù)傳給 Odoo。注意這些模塊必須存在于common_addons目錄且版本兼容如 Odoo 14.0 的模塊不能 init 到 12.0 容器計費周期純業(yè)務邏輯不影響技術(shù)流程但決定了后續(xù)發(fā)票生成頻率。5.2 創(chuàng)建客戶端實例docker run命令的完整展開式當你點擊“創(chuàng)建并確認客戶端”odoo_saas_kit會拼出一條完整的docker run命令。我們可以從源碼反推其結(jié)構(gòu)odoo_saas_kit/models/saas_client.pydocker run -d \ --name client_john_doe \ --restart unless-stopped \ -p 8080:8069 \ -v /opt/odoo/Odoo-SAAS-Data/client_john_doe/data-dir:/var/lib/odoo \ -v /opt/odoo/Odoo-SAAS-Data/client_john_doe/odoo.conf:/etc/odoo/odoo.conf \ -v /opt/odoo/common_addons:/mnt/extra-addons \ -e DB_HOST192.168.1.100 \ -e DB_PORT5432 \ -e DB_USERclient_john_doe \ -e DB_PASSWORDstrong_pass_123 \ -e ADMIN_PASSWDmaster_key_456 \ --network bridge \ odoosaas:14.0-ubuntu20.04各參數(shù)含義--name client_john_doe容器名也是客戶端域名如john.doe.example.com-v .../data-dir:/var/lib/odoo掛載數(shù)據(jù)目錄odoo_saas_kit會在此目錄下生成filestore/和session/-v .../odoo.conf:/etc/odoo/odoo.conf掛載配置文件odoo_saas_kit會根據(jù) Plan 配置動態(tài)生成-v /opt/odoo/common_addons:/mnt/extra-addons掛載通用模塊所有客戶端共享-e DB_*數(shù)據(jù)庫連接參數(shù)指向為該客戶端創(chuàng)建的專屬 PostgreSQL 用戶odoosaas:14.0-ubuntu20.04你構(gòu)建的基礎鏡像。5.3 郵件發(fā)送機制鏈接里的 token 是怎么生成的客戶收到的郵件里有這樣一個鏈接https://john.doe.example.com/web/reset_password?tokenabc123def456...這個token不是隨機字符串而是 Odoo 標準的reset_passwordtoken由res.users模型的action_reset_password()方法生成。odoo_saas_kit在創(chuàng)建客戶端后會調(diào)用self.env[res.users].create({...})創(chuàng)建管理員用戶郵箱為客戶填寫的郵箱調(diào)用user.action_reset_password()生成 token 并存入res_users表的login_date字段實際是password_write_date拼接 URLhttps://{client_domain}/web/reset_password?token{token}。驗證方式進入 Odoo 后臺打開“設置 用戶 公司 用戶”找到該客戶用戶點擊“重置密碼”看彈出的鏈接是否和郵件里一致。提示如果郵件沒收到先檢查 Odoo 的郵件服務器配置Settings General Settings Email再檢查odoo_saas_kit模塊里models/saas_client.py的_send_welcome_email()方法是否被正確調(diào)用可在日志里搜welcome email sent。6. 日志、備份與故障定位當“創(chuàng)建中…”卡住時你該看哪 5 個地方SaaS Kit 的后臺界面很友好但它的“友好”是建立在大量后臺異步任務之上的。一旦卡在“創(chuàng)建中…”界面不會告訴你錯在哪。你得像老中醫(yī)一樣望聞問切——看日志、查進程、驗網(wǎng)絡、翻配置、試命令。下面這五個位置是我每次翻車必查的“后悔藥”。6.1 Odoo 服務端日志/var/log/odoo/odoo-server.log里的第一行線索這是最頂層的日志。搜索關鍵詞# 查看最近 100 行過濾 saas 相關 sudo tail -100 /var/log/odoo/odoo-server.log | grep -i saas # 查看 ERROR 和 CRITICAL sudo grep -E (ERROR|CRITICAL) /var/log/odoo/odoo-server.log | tail -20典型線索odoo.addons.odoo_saas_kit.models.saas_client: Error creating client: Command [docker, run, ...] returned non-zero exit status 1→ Docker 命令失敗轉(zhuǎn)去看docker logspsycopg2.OperationalError: FATAL: password authentication failed for user client_xyz→ PostgreSQL 用戶密碼不對檢查odoo_saas_kit/models/saas_client.py里create_db_user()的密碼生成邏輯ValueError: invalid literal for int() with base 10: None→saas.conf里某個路徑配置為空比如odoo_saas_data 后面沒填路徑。6.2 Docker 容器日志docker logs -f container_name是真相發(fā)生地當 Odoo 日志說“Docker 命令失敗”立刻docker ps -a找到對應容器狀態(tài)可能是Exited (1)然后# 查看退出容器的日志-f 無效用 --tail docker logs --tail 100 client_john_doe # 如果容器還在運行實時跟蹤 docker logs -f client_john_doe高頻錯誤Could not open config file /etc/odoo/odoo.conf: Permission denied→ UID/GID 不匹配容器內(nèi)odoo用戶無法讀宿主機掛載的文件psycopg2.OperationalError: could not connect to server: Connection refused→DB_HOST配錯了不是localhost容器內(nèi) localhost 是自己而是主服務器或遠程 PostgreSQL 的 IPImportError: No module named hr→common_addons目錄里沒放hr模塊或模塊版本與 Odoo 版本不兼容。6.3 Nginx 錯誤日志/var/log/nginx/error.log揭露 502 的真正兇手客戶端域名能解析但打開是 502 Bad Gateway一定是 Nginx 沒轉(zhuǎn)發(fā)到后端 Odoo 容器。查sudo tail -50 /var/log/nginx/error.log | grep client_john_doe關鍵線索connect() failed (111: Connection refused) while connecting to upstream→ Nginx 配置里的proxy_pass http://127.0.0.1:8080;但容器沒映射8080端口或容器根本沒起來open() /etc/nginx/conf.d/client_john_doe.conf failed (2: No such file or directory)→odoo_saas_kit沒生成 vhost 文件檢查docker_vhosts目錄權(quán)限和saas.conf里nginx_vhosts路徑no resolver defined to resolve client_john_doe→ Nginx 配置用了域名解析但沒配resolver改用 IP 地址。6.4 PostgreSQL 日志/var/log/postgresql/postgresql-*-main.log里的連接審計當 Odoo 報“數(shù)據(jù)庫連接失敗”但psql -h 192.168.1.100 -U odoo能連問題可能出在客戶端專屬用戶上。查 PG 日志sudo tail -50 /var/log/postgresql/postgresql-*-main.log | grep -E (client_john_doe|FATAL)典型記錄FATAL: password authentication failed for user client_john_doe→ 密碼不匹配檢查odoo_saas_kit創(chuàng)建用戶時的password字段FATAL: database client_john_doe does not exist→ 數(shù)據(jù)庫沒創(chuàng)建成功回溯 Odoo 日志里CREATE DATABASE是否執(zhí)行connection received: host172.17.0.3 port54322→ 看host后的 IP確認是不是 Docker 網(wǎng)絡 IP172.17.x.x如果不是說明DB_HOST配錯了。6.5 手動模擬創(chuàng)建流程用 5 行命令復現(xiàn)整個鏈路當所有日志都模糊我就會放棄 GUI用最原始的方式手動走一遍# 1. 手動創(chuàng)建 PostgreSQL 用戶和庫 sudo -u postgres psql -c CREATE DATABASE client_test; sudo -u postgres psql -c CREATE USER client_test WITH PASSWORD test123; # 2. 手動啟動一個客戶端容器復用你的基礎鏡像 docker run -d \ --name client_test \ -v /opt/odoo/Odoo-SAAS-Data/client_test/data-dir:/var/lib/odoo \ -v /opt/odoo/Odoo-SAAS-Data/client_test/odoo.conf:/etc/odoo/odoo.conf \ -e DB_HOST192.168.1.100 \ -e DB_USERclient_test \ -e DB_PASSWORDtest123 \ -e ADMIN_PASSWDmaster123 \ odoosaas:14.0-ubuntu20.04 # 3. 查看容器日志 docker logs -f client_test # 4. 如果成功手動創(chuàng)建 Nginx vhost復制一份 template cp /opt/odoo/Odoo-SAAS-Data/docker_vhosts/vhosttemplate.txt /opt/odoo/Odoo-SAAS-Data/docker_vhosts/client_test.conf sed -i s/{domain}/client.test.example.com/g; s/{port}/8080/g /opt/odoo/Odoo-SAAS-Data/docker_vhosts/client_test.conf sudo nginx -t sudo systemctl reload nginx # 5. 瀏覽器訪問 client.test.example.com看是否能進 Odoo 登錄頁從那以后我每次遇到“創(chuàng)建中…”卡住都強制走一遍這 5 行命令——它逼我把所有隱式依賴路徑、權(quán)限、網(wǎng)絡、配置全部顯式化。往往走到第 2 步docker run就報錯真相瞬間大白。希望幫到你。本文還有配套的精品資源點擊獲取