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(可選)
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-proxy、acme-companion與各服務的VIRTUAL_HOST/LETSENCRYPT_HOST環境變數,改在odoo/pgadmin/mailcatcher加上ports(例如8069:8069、5050:80、1080:1080)。 - 正式 SMTP:將
config/odoo.conf的 SMTP 指向你的真實郵件服務(例如 Google Workspace、SendGrid),並移除 Mailcatcher。 - 備份:定期備份 volumes(
odoo-web-data、odoo-db-data、pgadmin-data)與自訂模組原始碼(addons/)。 - 安全:請務必更改所有預設密碼,並限制 pgAdmin 的公開存取(必要時加 Basic Auth 或僅內網存取)。