跳轉至

title: 完整堆疊 icon: material/server date_created: 2026-09-14 date_modified: 2026-09-14


完整堆疊

這是「一台機器同時要 HTTPS、Odoo、pgAdmin、Mailcatcher」的單檔 Compose 範本,適合自己實驗整包服務。若開發與正式要分開維護,請用 Docker 部署dev/prod/。密碼一律改掉,pgAdmin 不要無防護地暴露在公網。

專案結構

.
├─ docker-compose.yml
├─ .env
├─ config/
│  └─ odoo.conf
├─ addons/
├─ logs/
├─ dev/
│  ├─ Dockerfile
│  └─ requirements.txt  #(可選,用來安裝自訂套件)
└─ .devcontainer/
   └─ devcontainer.json

.env(請依實際情況修改)

# ==== 通用設定 ====
TZ=Asia/Taipei

# ==== 網域與憑證(務必修改) ====
DOMAIN=odoo.example.com
LETSENCRYPT_EMAIL=you@example.com

# ==== 資料庫 ====
POSTGRES_DB=postgres
POSTGRES_USER=odoo
POSTGRES_PASSWORD=change_me_strong
PGDATA=/var/lib/postgresql/data/pgdata

# ==== Odoo 管理密碼(進入資料庫管理用) ====
ODOO_ADMIN_PASS=change_me_admin

# ==== pgAdmin 登入 ====
PGADMIN_DEFAULT_EMAIL=admin@example.com
PGADMIN_DEFAULT_PASSWORD=change_me_pgadmin

注意:DOMAIN 必須先在 DNS 指到你的主機;LETSENCRYPT_EMAIL 用於憑證申請通知;所有密碼請改為安全值。


docker-compose.yml

version: '3.8'

networks:
  proxy:
    external: false
  default:

volumes:
  odoo-web-data:
  odoo-db-data:
  pgadmin-data:
  nginx-certs:
  nginx-vhost:
  nginx-html:
  nginx-dhparam:

services:
  # 反向代理(自動 HTTPS)
  nginx-proxy:
    image: nginxproxy/nginx-proxy:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - nginx-certs:/etc/nginx/certs
      - nginx-vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html
      - nginx-dhparam:/etc/nginx/dhparam
    networks:
      - proxy
    restart: unless-stopped

  acme-companion:
    image: nginxproxy/acme-companion
    container_name: nginx-proxy-acme
    environment:
      - DEFAULT_EMAIL=${LETSENCRYPT_EMAIL}
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - nginx-certs:/etc/nginx/certs
      - nginx-vhost:/etc/nginx/vhost.d
      - nginx-html:/usr/share/nginx/html
      - nginx-dhparam:/etc/nginx/dhparam
    networks:
      - proxy
    depends_on:
      - nginx-proxy
    restart: unless-stopped

  # Odoo 應用
  odoo:
    image: odoo:18.0
    container_name: odoo18
    depends_on:
      - db
    environment:
      - HOST=db
      - USER=${POSTGRES_USER}
      - PASSWORD=${POSTGRES_PASSWORD}
      - LANG=zh_TW.UTF-8
      # 供 nginx-proxy / acme 使用
      - VIRTUAL_HOST=${DOMAIN}
      - LETSENCRYPT_HOST=${DOMAIN}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
    volumes:
      - odoo-web-data:/var/lib/odoo
      - ./config:/etc/odoo
      - ./addons:/mnt/extra-addons
      - ./logs:/var/log/odoo
    networks:
      - proxy
      - default
    restart: unless-stopped

  # Postgres
  db:
    image: postgres:15
    container_name: odoo18-db
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - PGDATA=${PGDATA}
      - TZ=${TZ}
    volumes:
      - odoo-db-data:${PGDATA}
    restart: unless-stopped

  # pgAdmin(資料庫管理)
  pgadmin:
    image: dpage/pgadmin4
    container_name: odoo18-pgadmin
    depends_on:
      - db
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD}
      - TZ=${TZ}
      # 對外網域(可選,若要透過 HTTPS 走代理)
      - VIRTUAL_HOST=pgadmin.${DOMAIN}
      - LETSENCRYPT_HOST=pgadmin.${DOMAIN}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
    networks:
      - proxy
      - default
    restart: unless-stopped

  # Mailcatcher(開發測試用 SMTP)
  mailcatcher:
    image: dockage/mailcatcher:0.9.0
    container_name: odoo18-mailcatcher
    environment:
      - TZ=${TZ}
      # 讓它也走反向代理(可選)
      - VIRTUAL_HOST=mail.${DOMAIN}
      - LETSENCRYPT_HOST=mail.${DOMAIN}
      - LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
    networks:
      - proxy
      - default
    restart: unless-stopped

啟動後:

  • Odoo:https://$DOMAIN
  • pgAdmin:https://pgadmin.$DOMAIN
  • Mailcatcher UI:https://mail.$DOMAIN(Web UI 其實是 1080 介面)
  • 若只在本機測試、不需憑證,可移除 nginx-proxy 與 acme-companion,改用 ports: - "8069:8069" 直接暴露 Odoo。

config/odoo.conf

[options]
; ——— 核心設定 ———
admin_passwd = ${ODOO_ADMIN_PASS}
db_host = db
db_port = 5432
db_user = ${POSTGRES_USER}
db_password = ${POSTGRES_PASSWORD}

; ——— 模組與日誌 ———
addons_path = /mnt/extra-addons
logfile = /var/log/odoo/odoo.log
log_level = info

; ——— 郵件(開發:指向 mailcatcher)———
smtp_server = odoo18-mailcatcher
smtp_port = 1025
smtp_ssl = False
smtp_user =
smtp_password =

說明:smtp_server 指向服務名稱 odoo18-mailcatcher(Compose 內部 DNS 可解析)。正式環境請改成真實 SMTP。


dev/Dockerfile(開發用:可安裝額外套件)

FROM odoo:18.0

# 可加裝常用工具或系統相依套件(視需要增減)
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        git nano curl build-essential \
    && rm -rf /var/lib/apt/lists/*

# 可選:若有 Python 相依,集中在 requirements.txt
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt || true

# 設定 TZ(讀取 .env 的 TZ)
ENV TZ=Asia/Taipei

若沒有額外需求,可直接使用官方 odoo:18.0,此 Dockerfile 只在需要客製時使用。


dev/requirements.txt(可選)

# 範例:額外 Python 相依套件
# psycopg2-binary==2.9.9
# xlrd==2.0.1

VS Code:.devcontainer/devcontainer.json

{
  "name": "Odoo 18 Dev",
  "dockerComposeFile": ["../docker-compose.yml"],
  "service": "odoo",
  "workspaceFolder": "/workspace",
  "shutdownAction": "stopCompose",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-azuretools.vscode-docker",
        "batisteo.vscode-django",
        "grapecity.gc-excelviewer"
      ]
    }
  },
  "remoteEnv": {
    "PYTHONUNBUFFERED": "1"
  },
  "postCreateCommand": "python -V && pip -V"
}

使用方式:VS Code 安裝 Dev Containers 擴充,開啟專案後選「Reopen in Container」。


啟動步驟

# 1) 建立目錄結構
mkdir -p config addons logs dev .devcontainer

# 2) 建立檔案(依上方內容填好)
#    - .env
#    - docker-compose.yml
#    - config/odoo.conf
#    - dev/Dockerfile(可選)
#    - dev/requirements.txt(可選)
#    - .devcontainer/devcontainer.json

# 3) 啟動
docker compose up -d

# 4) 首次進站
#    - Odoo: https://$DOMAIN  (建立資料庫、選語言)
#    - pgAdmin: https://pgadmin.$DOMAIN  (Add New Server,Host 填 db,User/Pass 依 .env)
#    - Mailcatcher: https://mail.$DOMAIN  (Web UI 看信)

常見問題與備註

  • 憑證一直申請不到 / 502:DNS 尚未生效或網域未指向主機;請確認 80/443 對外開放,且無其他 Nginx 佔用。
  • 只想本機測試:移除 nginx-proxyacme-companion 與各服務的 VIRTUAL_HOST/LETSENCRYPT_HOST 環境變數,改在 odoo / pgadmin / mailcatcher 加上 ports(例如 8069:80695050:801080:1080)。
  • 正式 SMTP:將 config/odoo.conf 的 SMTP 指向你的真實郵件服務(例如 Google Workspace、SendGrid),並移除 Mailcatcher。
  • 備份:定期備份 volumes(odoo-web-dataodoo-db-datapgadmin-data)與自訂模組原始碼(addons/)。
  • 安全:請務必更改所有預設密碼,並限制 pgAdmin 的公開存取(必要時加 Basic Auth 或僅內網存取)。

進一步學習