odoo-service
4
总安装量
4
周安装量
#53262
全站排名
安装命令
npx skills add https://github.com/ahmed-lakosha/odoo-upgrade-skill --skill odoo-service
Agent 安装分布
openclaw
3
antigravity
3
github-copilot
3
codex
3
kimi-cli
3
gemini-cli
3
Skill 文档
Odoo Service Skill
1. Overview / Role
The odoo-service skill is the complete Odoo server lifecycle manager. It handles every aspect of running, deploying, initializing, and managing Odoo servers across ANY environment and ANY IDE.
What This Skill Does
- Server Management: Start, stop, restart Odoo processes across Windows, Linux, and macOS
- Environment Detection: Automatically detects whether you are in a local venv, Docker, or bare Python environment
- Environment Initialization: Creates virtual environments, installs dependencies, sets up PostgreSQL, generates config files
- Database Management: Backup, restore, create, drop, list databases; reset admin passwords
- Docker Orchestration: Generate Dockerfiles, docker-compose files, manage containers, exec into shells
- IDE Configuration: Generate PyCharm run configurations and VSCode tasks/launch/settings files
- Module Management: Install, update, scaffold Odoo modules from CLI or plugin commands
- Multi-Project Support: Manage multiple Odoo projects with different configs, ports, and databases simultaneously
Supported Odoo Versions
| Version | Status | Python Range | Notes |
|---|---|---|---|
| 14 | Supported | 3.7 – 3.10 | LTS, legacy projects |
| 15 | Supported | 3.8 – 3.11 | Community projects |
| 16 | Supported | 3.9 – 3.12 | Active enterprise |
| 17 | Supported | 3.10 – 3.13 | Primary development version |
| 18 | Supported | 3.10 – 3.13 | Active new projects |
| 19 | Supported | 3.10 – 3.13 | Latest features |
Quick Decision Matrix: Which Environment?
Are you deploying to production?
YES â Docker (isolation, reproducibility, easy scaling)
NO â
Do you have an existing venv/ or .venv/ directory?
YES â Local venv (keep using it)
NO â
Do you want isolation from system Python?
YES â Local venv (recommended for dev)
NO â Bare Python (simplest, least isolation)
2. Environment Detection Logic
The skill auto-detects the running environment using the following priority order:
Detection Algorithm
import os
from pathlib import Path
def detect_environment(project_root: str) -> str:
"""
Detect which Odoo environment is active.
Returns: 'venv', 'docker', or 'bare'
Priority: docker > venv > bare
"""
root = Path(project_root)
# 1. Check for Docker environment (highest priority)
if (root / 'docker-compose.yml').exists():
return 'docker'
if (root / 'docker-compose.yaml').exists():
return 'docker'
if (root / 'Dockerfile').exists():
return 'docker'
# 2. Check for virtual environment
venv_dirs = ['.venv', 'venv', 'env', '.env']
for venv_dir in venv_dirs:
venv_path = root / venv_dir
if venv_path.is_dir():
# Verify it's actually a venv (has python executable)
if (venv_path / 'Scripts' / 'python.exe').exists(): # Windows
return 'venv'
if (venv_path / 'bin' / 'python').exists(): # Linux/Mac
return 'venv'
# 3. Fall back to bare Python
return 'bare'
Detection Signals
.venv/Scripts/python.exe(Windows) or.venv/bin/python(Linux/Mac) â local-venvdocker-compose.ymlordocker-compose.yamlin project root â dockerDockerfileonly (no compose) â docker-build mode- None of the above â bare-python
Override Detection
You can force an environment by passing flags:
--env venvâ force local venv--env dockerâ force Docker--env bareâ force bare Python--dockerâ shorthand for--env docker
3. Local Virtual Environment Setup
Windows Setup (Step-by-Step)
# Step 1: Navigate to your Odoo version directory
cd C:\odoo\odoo17
# Step 2: Create virtual environment
python -m venv .venv
# Step 3: Activate
.\.venv\Scripts\activate
# Step 4: Upgrade pip
python -m pip install --upgrade pip
# Step 5: Install core Odoo requirements
pip install -r requirements.txt
# Step 6: Install project-specific requirements (if exists)
pip install -r projects\myproject\requirements.txt
# Step 7: Verify installation
python -c "import odoo; print('Odoo importable')"
Linux / macOS Setup
# Step 1: Navigate to Odoo directory
cd /opt/odoo17
# Step 2: Create virtual environment with specific Python version
python3.10 -m venv .venv
# Step 3: Activate
source .venv/bin/activate
# Step 4: Upgrade pip
pip install --upgrade pip
# Step 5: Install requirements
pip install -r requirements.txt
# Step 6: Project-specific requirements
pip install -r projects/myproject/requirements.txt
# Step 7: Verify
python -c "import odoo; print('Odoo importable')"
Python Version Requirements Table
| Odoo Version | Min Python | Max Python | Recommended | Notes |
|---|---|---|---|---|
| 14 | 3.7 | 3.10 | 3.8 | EOL versions, be careful with libraries |
| 15 | 3.8 | 3.11 | 3.9 | Stable range |
| 16 | 3.9 | 3.12 | 3.10 | Wider support |
| 17 | 3.10 | 3.13 | 3.11 | Primary dev version |
| 18 | 3.10 | 3.13 | 3.11 | New projects |
| 19 | 3.10 | 3.13 | 3.12 | Latest features |
Verifying Python Version Compatibility
import sys
def check_python_compatibility(odoo_version: int) -> bool:
"""Check if current Python is compatible with given Odoo version."""
version_ranges = {
14: ((3, 7), (3, 10)),
15: ((3, 8), (3, 11)),
16: ((3, 9), (3, 12)),
17: ((3, 10), (3, 13)),
18: ((3, 10), (3, 13)),
19: ((3, 10), (3, 13)),
}
current = sys.version_info[:2]
min_ver, max_ver = version_ranges.get(odoo_version, ((3, 10), (3, 13)))
return min_ver <= current <= max_ver
# Usage
if not check_python_compatibility(17):
print(f"WARNING: Python {sys.version} may not be compatible with Odoo 17")
Managing Multiple Venvs (Multi-Version Setup)
# Separate venv per Odoo version
C:\odoo\odoo14\.venv\ # Python 3.8
C:\odoo\odoo15\.venv\ # Python 3.9
C:\odoo\odoo17\.venv\ # Python 3.11
C:\odoo\odoo18\.venv\ # Python 3.11
# Each has its own requirements installed independently
# Never share venvs across Odoo versions
4. Server Startup (Local)
Basic Startup Commands
# Basic startup â reads all config from .conf file
python -m odoo -c conf\myproject.conf
# Explicit database override
python -m odoo -c conf\myproject.conf -d mydb
# Development mode â enables auto-reload, full tracebacks, asset recompilation
python -m odoo -c conf\myproject.conf --dev=all
# Development mode options (can combine):
# --dev=reload â auto-reload Python on file change
# --dev=qweb â detailed QWeb error reporting
# --dev=werkzeug â Werkzeug debugger
# --dev=xml â show XML errors in browser
# --dev=all â enable all dev options (recommended)
# With workers (production mode)
python -m odoo -c conf\myproject.conf --workers=4
# Custom port
python -m odoo -c conf\myproject.conf --http-port=8070
# Install module and stop
python -m odoo -c conf\myproject.conf -d mydb -i my_module --stop-after-init
# Update module and stop
python -m odoo -c conf\myproject.conf -d mydb -u my_module --stop-after-init
# Update ALL modules (slow â use only when necessary)
python -m odoo -c conf\myproject.conf -d mydb -u all --stop-after-init
Background Process (Windows)
# Method 1: Start-Process (PowerShell)
Start-Process python -ArgumentList "-m odoo -c conf\myproject.conf" -WindowStyle Hidden
# Method 2: Background job
$job = Start-Job -ScriptBlock { python -m odoo -c conf\myproject.conf }
$job.Id # Save this to stop later
# Method 3: With log file
Start-Process python -ArgumentList "-m odoo -c conf\myproject.conf" -WindowStyle Hidden -RedirectStandardOutput "logs\odoo.log" -RedirectStandardError "logs\odoo_err.log"
# Method 4: Windows service (nssm recommended for production)
nssm install OdooService "python" "-m odoo -c C:\odoo\odoo17\conf\myproject.conf"
nssm start OdooService
Background Process (Linux/Mac)
# Method 1: nohup (survives terminal close)
nohup python -m odoo -c conf/myproject.conf > logs/odoo.log 2>&1 &
echo $! > logs/odoo.pid # Save PID for later
# Method 2: screen session
screen -dmS odoo python -m odoo -c conf/myproject.conf
# Method 3: tmux session
tmux new-session -d -s odoo "python -m odoo -c conf/myproject.conf"
# Method 4: systemd service (production)
# Create /etc/systemd/system/odoo17.service:
[Unit]
Description=Odoo 17 Server
After=network.target postgresql.service
[Service]
Type=simple
User=odoo
WorkingDirectory=/opt/odoo17
ExecStart=/opt/odoo17/.venv/bin/python -m odoo -c conf/myproject.conf
Restart=on-failure
[Install]
WantedBy=multi-user.target
# Enable and start
systemctl enable odoo17
systemctl start odoo17
systemctl status odoo17
Startup Sequence Verification
# After starting, verify Odoo is running:
# 1. Check port is listening
netstat -ano | findstr :8069 # Windows
lsof -i :8069 # Linux/Mac
# 2. Check HTTP response
curl -s -o /dev/null -w "%{http_code}" http://localhost:8069/web/login
# Expected: 200
# 3. Check process
tasklist | findstr python # Windows
ps aux | grep odoo # Linux/Mac
5. Server Shutdown / Port Management
Windows: Kill by Port
# Method 1: netstat + taskkill (CMD)
FOR /F "tokens=5" %P IN ('netstat -ano ^| findstr :8069') DO taskkill /PID %P /F
# Method 2: PowerShell (more reliable)
$port = 8069
$process = Get-NetTCPConnection -LocalPort $port -ErrorAction SilentlyContinue
if ($process) {
Stop-Process -Id $process.OwningProcess -Force
Write-Host "Killed process on port $port"
} else {
Write-Host "No process found on port $port"
}
# Method 3: Kill all Python processes (nuclear option)
taskkill /IM python.exe /F
# Kill both Odoo ports (web + longpolling)
FOR /F "tokens=5" %P IN ('netstat -ano ^| findstr :8069') DO taskkill /PID %P /F
FOR /F "tokens=5" %P IN ('netstat -ano ^| findstr :8072') DO taskkill /PID %P /F
Linux / macOS: Kill by Port
# Method 1: lsof + kill
lsof -ti:8069 | xargs kill -9
# Method 2: fuser
fuser -k 8069/tcp
# Method 3: pkill for Odoo specifically
pkill -f "odoo.*8069"
# Kill both ports
lsof -ti:8069 | xargs kill -9
lsof -ti:8072 | xargs kill -9
# Verify port is free
lsof -i :8069 # Should return nothing
Find and Inspect Running Processes
# Windows: Find Odoo-related Python processes
Get-Process python | Where-Object {$_.CommandLine -like "*odoo*"}
# Windows: Detailed process with ports
netstat -ano | findstr :8069
# Linux/Mac: Inspect what's on port 8069
lsof -i :8069
ss -tlnp | grep 8069
Graceful vs Force Stop
import subprocess
import signal
import os
def stop_graceful(pid: int, timeout: int = 10):
"""Try SIGTERM first, then SIGKILL after timeout."""
try:
if os.name == 'nt': # Windows
subprocess.run(['taskkill', '/PID', str(pid), '/F'])
else: # Linux/Mac
os.kill(pid, signal.SIGTERM)
import time
time.sleep(timeout)
try:
os.kill(pid, 0) # Check if still alive
os.kill(pid, signal.SIGKILL) # Force kill
except ProcessLookupError:
pass # Already dead, good
except Exception as e:
print(f"Error stopping process {pid}: {e}")
6. Configuration File Reference (.conf)
Complete Annotated Configuration
[options]
# ==========================================================
# ADDON PATHS
# ==========================================================
# Comma-separated list of directories containing Odoo modules
# Order matters: modules found first take precedence
addons_path = odoo\addons,projects\myproject
# ==========================================================
# SECURITY
# ==========================================================
# Master password for the database manager UI
# Set to a strong password in production
admin_passwd = CHANGE_ME_IN_PRODUCTION
# ==========================================================
# DATABASE CONNECTION
# ==========================================================
db_host = localhost
db_port = 5432
db_user = odoo
db_password = odoo
# Database name (optional â can be specified at startup with -d)
# db_name = myproject17
# Database filter (regex pattern â only show matching databases)
# Multi-tenant: each project has its own prefix
dbfilter = myproject17.*
# Max database connections per worker
db_maxconn = 64
# ==========================================================
# NETWORK PORTS
# ==========================================================
# Main web interface port
http_port = 8069
# Longpolling port (chat, notifications, buses)
# Called gevent_port in v17+, longpolling_port in v14-16
gevent_port = 8072
# longpolling_port = 8072 # Use this for Odoo 14-16
# Interface to bind (0.0.0.0 = all, 127.0.0.1 = localhost only)
# http_interface = 0.0.0.0
# ==========================================================
# WORKER PROCESSES
# ==========================================================
# Number of worker processes
# 0 = single-threaded (development)
# >0 = multi-worker (production, requires --workers flag)
# Rule of thumb: 2 * CPU_CORES + 1
workers = 0
# Cron workers (background tasks)
max_cron_threads = 2
# ==========================================================
# MEMORY LIMITS (bytes)
# ==========================================================
# Soft limit: worker restarts after processing current request
limit_memory_soft = 2147483648 # 2 GB
# Hard limit: worker killed immediately
limit_memory_hard = 2684354560 # 2.5 GB
# ==========================================================
# TIME LIMITS (seconds)
# ==========================================================
# CPU time per request
limit_time_cpu = 600
# Real (wall clock) time per request
limit_time_real = 1200
# Time per cron task
limit_time_real_cron = 1800
# ==========================================================
# PROXY / PRODUCTION
# ==========================================================
# Set True when behind nginx/Apache reverse proxy
# Required for correct IP forwarding and SSL headers
proxy_mode = False
# ==========================================================
# LOGGING
# ==========================================================
# Log output file (omit or leave empty for console output)
logfile = logs\odoo.log
# Log level: debug, info, warning, error, critical
log_level = info
# Log handler format
# log_handler = :INFO
# ==========================================================
# DATA DIRECTORY
# ==========================================================
# Where Odoo stores file attachments, sessions, etc.
data_dir = data
# ==========================================================
# EMAIL (optional)
# ==========================================================
# smtp_server = localhost
# smtp_port = 25
# smtp_ssl = False
# smtp_user = False
# smtp_password = False
# ==========================================================
# REPORT RENDERING
# ==========================================================
# Path to wkhtmltopdf for PDF reports
# wkhtmltopdf_command = wkhtmltopdf # Auto-detected if in PATH
Config Templates by Environment
# --- DEVELOPMENT CONFIG ---
[options]
addons_path = odoo\addons,projects\myproject
admin_passwd = 123
db_host = localhost
db_port = 5432
db_user = odoo
db_password = odoo
dbfilter = myproject17_dev
http_port = 8069
gevent_port = 8072
workers = 0
log_level = debug
# --- PRODUCTION CONFIG ---
[options]
addons_path = odoo\addons,projects\myproject
admin_passwd = STRONG_RANDOM_PASSWORD_HERE
db_host = localhost
db_port = 5432
db_user = odoo
db_password = STRONG_DB_PASSWORD
dbfilter = myproject17_prod
http_port = 8069
gevent_port = 8072
workers = 4
limit_memory_soft = 2147483648
limit_memory_hard = 2684354560
limit_time_cpu = 600
limit_time_real = 1200
proxy_mode = True
logfile = logs\odoo_prod.log
log_level = warning
data_dir = data_prod
7. Module Operations
Install, Update, Scaffold
# ----------------------------------------
# INSTALL (new module, first time)
# ----------------------------------------
python -m odoo -c conf\myproject.conf -d mydb -i my_module --stop-after-init
# Install multiple modules
python -m odoo -c conf\myproject.conf -d mydb -i module1,module2,module3 --stop-after-init
# ----------------------------------------
# UPDATE (after code changes â most common)
# ----------------------------------------
python -m odoo -c conf\myproject.conf -d mydb -u my_module --stop-after-init
# Update multiple modules
python -m odoo -c conf\myproject.conf -d mydb -u module1,module2 --stop-after-init
# Update ALL modules (slow, use sparingly)
python -m odoo -c conf\myproject.conf -d mydb -u all --stop-after-init
# ----------------------------------------
# REFRESH MODULE LIST
# ----------------------------------------
# Run before installing a NEW module that wasn't there before
python -m odoo -c conf\myproject.conf -d mydb --update-list
# ----------------------------------------
# SCAFFOLD NEW MODULE
# ----------------------------------------
python odoo-bin scaffold my_new_module projects\myproject\
# Creates: projects/myproject/my_new_module/ with standard structure
Module Management in Docker
# Update module inside Docker container
docker-compose exec odoo python -m odoo \
-c /etc/odoo/odoo.conf \
-d mydb \
-u my_module \
--stop-after-init
# Install module inside Docker container
docker-compose exec odoo python -m odoo \
-c /etc/odoo/odoo.conf \
-d mydb \
-i my_module \
--stop-after-init
# Scaffold inside Docker
docker-compose exec odoo python /opt/odoo/source/odoo-bin scaffold my_module /opt/odoo/custom-addons/
Check Installed Modules
# Via Odoo shell
python odoo-bin shell -d mydb
>>> installed = self.env['ir.module.module'].search([('state', '=', 'installed')])
>>> print(installed.mapped('name'))
# Via psql directly
psql -U odoo -d mydb -c "SELECT name, state FROM ir_module_module WHERE state='installed' ORDER BY name;"
8. Database Operations
Backup and Restore
# ----------------------------------------
# BACKUP
# ----------------------------------------
# SQL format (human-readable, larger file)
pg_dump -U odoo -h localhost mydb > backups/mydb_$(date +%Y%m%d_%H%M%S).sql
# Custom format (compressed, faster restore)
pg_dump -U odoo -h localhost -Fc mydb > backups/mydb_$(date +%Y%m%d_%H%M%S).dump
# Directory format (parallel dump â fastest for large DBs)
pg_dump -U odoo -h localhost -Fd mydb -j 4 -f backups/mydb_dir/
# ----------------------------------------
# RESTORE
# ----------------------------------------
# From SQL file
createdb -U odoo new_mydb
psql -U odoo -d new_mydb < backups/mydb_20240101.sql
# From custom dump
createdb -U odoo new_mydb
pg_restore -U odoo -d new_mydb backups/mydb_20240101.dump
# From directory format
createdb -U odoo new_mydb
pg_restore -U odoo -d new_mydb -j 4 backups/mydb_dir/
# ----------------------------------------
# MANAGE
# ----------------------------------------
# Create database
createdb -U odoo newproject17
# Drop database (DANGER: irreversible)
dropdb -U odoo oldproject
# List all databases
psql -U odoo -l
# Connect interactively
psql -U odoo -h localhost -d mydb
Reset Admin Password
# Method 1: SQL UPDATE (fastest)
psql -U odoo -h localhost -d mydb -c \
"UPDATE res_users SET password='\$pbkdf2-sha512\$...' WHERE login='admin';"
# Better: Use Odoo's password hashing
psql -U odoo -h localhost -d mydb -c \
"UPDATE res_users SET password='newpassword' WHERE login='admin';"
# Note: Odoo hashes on next login attempt; for immediate hash use shell method
# Method 2: Odoo shell (recommended)
python odoo-bin shell -d mydb
>>> user = self.env['res.users'].search([('login', '=', 'admin')])
>>> user.write({'password': 'newpassword'})
>>> self.env.cr.commit()
Interactive Shell Usage
# Start shell
python odoo-bin shell -d mydb
# ---- COMMON SHELL OPERATIONS ----
# List all partners
env['res.partner'].search([], limit=10)
# Find specific record
env['res.partner'].search([('name', 'like', 'TAQAT')])
# Current user
env.user.name
env.user.id
# Raw SQL
env.cr.execute("SELECT id, name FROM res_partner LIMIT 5")
env.cr.fetchall()
# System parameters
env['ir.config_parameter'].sudo().get_param('web.base.url')
env['ir.config_parameter'].sudo().set_param('web.base.url', 'https://mysite.com')
# List installed modules
env['ir.module.module'].search([('state', '=', 'installed')]).mapped('name')
# Commit changes (required for writes)
env.cr.commit()
9. Docker Environment
Complete docker-compose.yml
version: '3.8'
services:
db:
image: postgres:15
container_name: odoo_db
environment:
POSTGRES_USER: ${POSTGRES_USER:-odoo}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-odoo}
POSTGRES_DB: postgres
volumes:
- odoo_db_data:/var/lib/postgresql/data
- ./backups:/backups
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-odoo}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 20s
restart: unless-stopped
odoo:
build:
context: .
dockerfile: Dockerfile
container_name: odoo_web
depends_on:
db:
condition: service_healthy
volumes:
- .:/opt/odoo/source:ro
- ./projects:/opt/odoo/custom-addons
- ./conf:/etc/odoo:ro
- odoo_filestore:/var/lib/odoo
- ./logs:/var/log/odoo
ports:
- "${ODOO_HTTP_PORT:-8069}:8069"
- "${ODOO_LONGPOLLING_PORT:-8072}:8072"
environment:
POSTGRES_HOST: db
POSTGRES_PORT: 5432
POSTGRES_USER: ${POSTGRES_USER:-odoo}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-odoo}
restart: unless-stopped
command: odoo -c /etc/odoo/odoo.conf
volumes:
odoo_db_data:
odoo_filestore:
Docker Management Commands
# ---- BUILD ----
docker-compose build
docker-compose build --no-cache # Force full rebuild
# ---- START / STOP ----
docker-compose up -d # Start in background
docker-compose up # Start in foreground (see logs)
docker-compose start # Start existing containers
docker-compose stop # Stop containers (preserves state)
docker-compose down # Stop and remove containers
docker-compose down -v # Also remove volumes (DANGER: deletes data)
docker-compose restart # Restart all
docker-compose restart odoo # Restart only Odoo service
# ---- REBUILD AFTER CHANGES ----
docker-compose up -d --build # Rebuild and restart
# ---- LOGS ----
docker-compose logs -f # Follow all logs
docker-compose logs -f odoo # Follow only Odoo logs
docker-compose logs --tail=100 odoo
# ---- SHELL ACCESS ----
docker-compose exec odoo bash # Bash shell in Odoo container
docker-compose exec db psql -U odoo # PostgreSQL in DB container
# ---- ODOO COMMANDS IN CONTAINER ----
docker-compose exec odoo python -m odoo -c /etc/odoo/odoo.conf -d mydb -u my_module --stop-after-init
docker-compose exec odoo python -m odoo shell -d mydb -c /etc/odoo/odoo.conf
# ---- STATUS ----
docker-compose ps
docker-compose top
# ---- DATABASE IN DOCKER ----
# Backup
docker exec odoo_db pg_dump -U odoo mydb > backup.sql
docker exec odoo_db pg_dump -U odoo -Fc mydb > backup.dump
# Restore
cat backup.sql | docker exec -i odoo_db psql -U odoo mydb
docker exec -i odoo_db pg_restore -U odoo -d mydb < backup.dump
10. Dockerfile Reference (Per Odoo Version)
Odoo 14 Dockerfile
FROM python:3.8-slim-buster
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
libxml2-dev \
libxslt1-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev \
node-less \
npm \
git \
postgresql-client \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
# Install wkhtmltopdf for PDF reports
RUN wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.buster_amd64.deb \
&& dpkg -i wkhtmltox_0.12.6.1-3.buster_amd64.deb \
&& rm wkhtmltox_0.12.6.1-3.buster_amd64.deb
WORKDIR /opt/odoo/source
COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt
EXPOSE 8069 8072
CMD ["python", "-m", "odoo", "-c", "/etc/odoo/odoo.conf"]
Odoo 17 Dockerfile (Primary)
FROM python:3.10-slim-bookworm
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
libxml2-dev \
libxslt1-dev \
libjpeg-dev \
libfreetype6-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev \
libffi-dev \
liblzma-dev \
npm \
git \
postgresql-client \
wget \
curl \
gettext-base \
fonts-noto-cjk \
fonts-noto-core \
&& rm -rf /var/lib/apt/lists/*
# Install wkhtmltopdf for PDF reports (Odoo 17 uses bookworm)
RUN wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& dpkg -i wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& rm wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
# Install rtlcss for RTL/Arabic support
RUN npm install -g rtlcss
WORKDIR /opt/odoo/source
COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt
# Install GeoIP2 for geolocation features
RUN pip install geoip2
RUN mkdir -p /var/lib/odoo /var/log/odoo /etc/odoo
EXPOSE 8069 8072
CMD ["python", "-m", "odoo", "-c", "/etc/odoo/odoo.conf"]
Odoo 18 Dockerfile
FROM python:3.11-slim-bookworm
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
libxml2-dev \
libxslt1-dev \
libjpeg-dev \
libfreetype6-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev \
libffi-dev \
npm \
git \
postgresql-client \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& dpkg -i wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& rm wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
RUN npm install -g rtlcss
WORKDIR /opt/odoo/source
COPY requirements.txt .
RUN pip install --upgrade pip \
&& pip install -r requirements.txt \
&& pip install cbor2
RUN mkdir -p /var/lib/odoo /var/log/odoo /etc/odoo
EXPOSE 8069 8072
CMD ["python", "-m", "odoo", "-c", "/etc/odoo/odoo.conf"]
Odoo 19 Dockerfile
FROM python:3.12-slim-bookworm
ENV DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
libxml2-dev \
libxslt1-dev \
libjpeg-dev \
libfreetype6-dev \
libsasl2-dev \
libldap2-dev \
libssl-dev \
libffi-dev \
libmagic1 \
npm \
git \
postgresql-client \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN wget -q https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& dpkg -i wkhtmltox_0.12.6.1-3.bookworm_amd64.deb \
&& rm wkhtmltox_0.12.6.1-3.bookworm_amd64.deb
RUN npm install -g rtlcss
WORKDIR /opt/odoo/source
COPY requirements.txt .
RUN pip install --upgrade pip \
&& pip install -r requirements.txt \
&& pip install cbor2 python-magic
RUN mkdir -p /var/lib/odoo /var/log/odoo /etc/odoo
EXPOSE 8069 8072
CMD ["python", "-m", "odoo", "-c", "/etc/odoo/odoo.conf"]
11. PyCharm Configuration
Local Python Run Configuration (XML)
Save to .idea/runConfigurations/Odoo_[PROJECT].xml:
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Odoo 17 [PROJECT]" type="PythonConfigurationType"
factoryName="Python">
<module name="[PROJECT_NAME]" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="$PROJECT_DIR$/.venv/Scripts/python.exe" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/odoo-bin" />
<option name="PARAMETERS" value="-c conf/[CONFIG].conf" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="true" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>
Docker Compose Run Configuration (XML)
Save to .idea/runConfigurations/Odoo_Docker.xml:
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Odoo [VERSION] Docker" type="docker-deploy"
factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="envFilePath" value="$PROJECT_DIR$/.env" />
<option name="composeFilePaths">
<list>
<option value="$PROJECT_DIR$/docker-compose.yml" />
</list>
</option>
<option name="sourceFilePath" value="docker-compose.yml" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>
PyCharm Settings (idea.properties / .idea/misc.xml)
<!-- .idea/misc.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.11 (.venv)" />
</component>
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="PythonProjectView">
<option name="showLibraryContents" value="false" />
</component>
</project>
12. VSCode Configuration
tasks.json (Local + Docker)
Save to .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Odoo: Start (dev mode)",
"type": "shell",
"command": "python -m odoo -c conf/${input:configFile} --dev=all",
"group": {"kind": "build", "isDefault": true},
"presentation": {
"reveal": "always",
"panel": "new",
"showReuseMessage": false
},
"problemMatcher": []
},
{
"label": "Odoo: Start (production mode)",
"type": "shell",
"command": "python -m odoo -c conf/${input:configFile} --workers=4",
"group": "build",
"presentation": {"reveal": "always", "panel": "new"}
},
{
"label": "Odoo: Stop (kill port 8069)",
"type": "shell",
"command": "FOR /F \"tokens=5\" %P IN ('netstat -ano ^| findstr :8069') DO taskkill /PID %P /F",
"windows": {
"command": "FOR /F \"tokens=5\" %P IN ('netstat -ano ^| findstr :8069') DO taskkill /PID %P /F"
},
"linux": {"command": "lsof -ti:8069 | xargs kill -9"},
"osx": {"command": "lsof -ti:8069 | xargs kill -9"},
"presentation": {"reveal": "always"}
},
{
"label": "Odoo: Update Module",
"type": "shell",
"command": "python -m odoo -c conf/${input:configFile} -d ${input:database} -u ${input:moduleName} --stop-after-init",
"presentation": {"reveal": "always", "panel": "shared"}
},
{
"label": "Odoo: Install Module",
"type": "shell",
"command": "python -m odoo -c conf/${input:configFile} -d ${input:database} -i ${input:moduleName} --stop-after-init",
"presentation": {"reveal": "always"}
},
{
"label": "Docker: Start",
"type": "shell",
"command": "docker-compose up -d",
"group": "build",
"presentation": {"reveal": "always"}
},
{
"label": "Docker: Stop",
"type": "shell",
"command": "docker-compose down",
"presentation": {"reveal": "always"}
},
{
"label": "Docker: Rebuild",
"type": "shell",
"command": "docker-compose up -d --build",
"presentation": {"reveal": "always", "panel": "new"}
},
{
"label": "Docker: Logs",
"type": "shell",
"command": "docker-compose logs -f odoo",
"presentation": {"reveal": "always", "panel": "shared"}
},
{
"label": "Docker: Shell",
"type": "shell",
"command": "docker-compose exec odoo bash",
"presentation": {"reveal": "always", "panel": "new"}
},
{
"label": "Docker: Update Module",
"type": "shell",
"command": "docker-compose exec odoo python -m odoo -c /etc/odoo/odoo.conf -d ${input:database} -u ${input:moduleName} --stop-after-init",
"presentation": {"reveal": "always"}
}
],
"inputs": [
{
"id": "configFile",
"type": "promptString",
"description": "Config file name (e.g. myproject.conf)",
"default": "odoo.conf"
},
{
"id": "database",
"type": "promptString",
"description": "Database name",
"default": "myproject17"
},
{
"id": "moduleName",
"type": "promptString",
"description": "Module name(s) to install/update",
"default": "my_module"
}
]
}
launch.json (Debugging)
Save to .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Odoo: Debug (Local)",
"type": "debugpy",
"request": "launch",
"module": "odoo",
"args": ["-c", "conf/${input:configFile}", "--dev=all"],
"cwd": "${workspaceFolder}",
"python": "${workspaceFolder}/.venv/Scripts/python.exe",
"justMyCode": false,
"console": "integratedTerminal",
"env": {
"PYTHONDONTWRITEBYTECODE": "1"
}
},
{
"name": "Odoo: Debug (Docker attach)",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/opt/odoo/source"
}
]
},
{
"name": "Odoo: Debug with DB override",
"type": "debugpy",
"request": "launch",
"module": "odoo",
"args": [
"-c", "conf/${input:configFile}",
"-d", "${input:database}",
"--dev=all"
],
"cwd": "${workspaceFolder}",
"python": "${workspaceFolder}/.venv/Scripts/python.exe",
"justMyCode": false,
"console": "integratedTerminal"
}
],
"inputs": [
{
"id": "configFile",
"type": "promptString",
"description": "Config file name",
"default": "odoo.conf"
},
{
"id": "database",
"type": "promptString",
"description": "Database name",
"default": "myproject17"
}
]
}
settings.json (Workspace)
Save to .vscode/settings.json:
{
"python.analysis.extraPaths": [
"./odoo",
"./odoo/addons",
"./projects"
],
"python.languageServer": "Pylance",
"python.defaultInterpreterPath": ".venv/Scripts/python.exe",
"python.analysis.typeCheckingMode": "basic",
"python.analysis.autoImportCompletions": true,
"files.exclude": {
"**/__pycache__": true,
"**/*.pyc": true,
"**/*.pyo": true,
"odoo.egg-info": true
},
"search.exclude": {
"odoo.egg-info": true,
"**/__pycache__": true,
".venv": true,
"**/*.pyc": true
},
"editor.rulers": [79, 120],
"editor.formatOnSave": false,
"files.associations": {
"*.xml": "xml",
"*.conf": "ini",
"*.po": "po"
},
"xml.validation.enabled": false,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"[python]": {
"editor.tabSize": 4
},
"[xml]": {
"editor.tabSize": 4
}
}
13. Multi-Project / Multi-Tenant Setup
Port Allocation Strategy
# Project A â Port 8069 (default)
http_port = 8069
gevent_port = 8072
dbfilter = projecta17.*
# Project B â Port 8070
http_port = 8070
gevent_port = 8073
dbfilter = projectb17.*
# Project C â Port 8071
http_port = 8071
gevent_port = 8074
dbfilter = projectc17.*
Nginx Reverse Proxy (Domain Routing)
# /etc/nginx/sites-available/projecta.conf
server {
listen 80;
server_name projecta.example.com;
location / {
proxy_pass http://127.0.0.1:8069;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /longpolling {
proxy_pass http://127.0.0.1:8072;
proxy_set_header Host $host;
}
}
# /etc/nginx/sites-available/projectb.conf
server {
listen 80;
server_name projectb.example.com;
location / {
proxy_pass http://127.0.0.1:8070;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /longpolling {
proxy_pass http://127.0.0.1:8073;
proxy_set_header Host $host;
}
}
Running Multiple Instances Simultaneously
# Terminal 1 â Project A
.\.venv\Scripts\activate
python -m odoo -c conf\projecta17.conf
# Terminal 2 â Project B
.\.venv\Scripts\activate
python -m odoo -c conf\projectb17.conf
# Background both (Windows PowerShell)
Start-Process python -ArgumentList "-m odoo -c conf\projecta17.conf" -WindowStyle Hidden
Start-Process python -ArgumentList "-m odoo -c conf\projectb17.conf" -WindowStyle Hidden
14. Production Checklist
Before going live, verify each item:
SECURITY
[ ] admin_passwd set to strong, unique password (not '123' or 'admin')
[ ] db_password set to strong password
[ ] PostgreSQL user has limited privileges (not superuser)
[ ] Firewall: only ports 80/443 exposed to internet
[ ] SSH key-based authentication (no password login)
[ ] SSL/TLS certificate installed (Let's Encrypt via certbot)
SERVER CONFIGURATION
[ ] proxy_mode = True (if behind nginx/Apache)
[ ] workers = 4 (or more based on CPU: 2*CPU+1)
[ ] max_cron_threads = 2 (or 1 for smaller servers)
[ ] limit_memory_soft / limit_memory_hard configured
[ ] limit_time_cpu / limit_time_real configured
[ ] logfile set and log rotation configured
[ ] data_dir set and backed up
DATABASE
[ ] dbfilter set to restrict accessible databases
[ ] Automated backup schedule configured
[ ] Backup tested (actually restore to verify)
[ ] PostgreSQL pg_hba.conf restricts remote access
INFRASTRUCTURE
[ ] Regular server snapshots configured
[ ] Monitoring configured (uptime, CPU, memory)
[ ] Alert on server down / high memory
[ ] wkhtmltopdf installed for PDF reports
[ ] rtlcss installed if using Arabic/RTL
ODOO SPECIFIC
[ ] website.base.url system parameter set correctly
[ ] Email (SMTP) configured and tested
[ ] CDN configured if using attachments
[ ] Session timeout configured appropriately
15. Troubleshooting Guide
Common Error Reference
| Problem | Likely Cause | Solution |
|---|---|---|
Address already in use: 8069 |
Previous Odoo still running | lsof -ti:8069 | xargs kill -9 or Windows: find/kill PID |
could not connect to server: Connection refused |
PostgreSQL not running | Start PostgreSQL: net start postgresql (Win) or systemctl start postgresql |
ImportError: No module named X |
Missing Python package | pip install X or pip install -r requirements.txt |
| Module not appearing in apps list | Module path not in addons_path | Add path to .conf, run --update-list |
Access Denied on module install |
Wrong admin_passwd | Check admin_passwd in .conf matches what you typed |
| Docker health check failing | PostgreSQL container not ready | Increase start_period in healthcheck config |
wkhtmltopdf not found (PDF fails) |
wkhtmltopdf not installed/PATH | Install via apt/choco, add to PATH |
| Longpolling not working | Port 8072 blocked or workers=0 |
Set workers > 0 for longpolling |
| Dev mode not auto-reloading | Only using --dev=reload |
Use --dev=all for full dev mode |
database "X" does not exist |
Database not created yet | createdb -U odoo X |
FATAL: role "odoo" does not exist |
PostgreSQL user not created | createuser -s odoo |
| Changes not reflecting after update | Browser cache | Hard refresh: Ctrl+Shift+R |
| XML view error (blank page) | Malformed XML | Check XML syntax, look at server logs |
KeyError: 'field_name' in view |
Field not in model | Check field exists in Python model |
| Slow startup | Too many modules | Check -i / -u flags, use --stop-after-init |
Diagnostic Commands
# Check PostgreSQL status
pg_isready -h localhost -p 5432
# Check Odoo port
netstat -ano | findstr :8069 # Windows
lsof -i :8069 # Linux/Mac
# Check Odoo logs (last 50 lines)
Get-Content logs\odoo.log -Tail 50 # PowerShell
tail -50 logs/odoo.log # Linux/Mac
# Check Python version
python --version
# Check installed packages
pip list | findstr odoo # Windows
pip list | grep odoo # Linux/Mac
# Test PostgreSQL connection
psql -U odoo -h localhost -c "SELECT 1"
# Docker diagnostics
docker-compose ps
docker-compose logs --tail=50 odoo
docker inspect odoo_web | grep -A 5 "Health"
16. Interactive Shell Usage
Starting the Shell
# Local
python odoo-bin shell -d mydatabase
# Docker
docker-compose exec odoo python -m odoo shell -d mydatabase -c /etc/odoo/odoo.conf
# With specific config
python odoo-bin shell -d mydatabase -c conf/myproject.conf
Common Shell Operations
# ---- PARTNERS ----
# List all partners
env['res.partner'].search([], limit=10)
# Search by name
env['res.partner'].search([('name', 'ilike', 'company')])
# Create partner
p = env['res.partner'].create({'name': 'Test Company', 'is_company': True})
env.cr.commit()
# ---- USERS ----
env.user.name # Current user name
env.user.id # Current user ID
env.user.groups_id # User's groups
# Find admin user
admin = env['res.users'].browse(2)
admin.login
# ---- MODULES ----
# List installed modules
env['ir.module.module'].search([('state', '=', 'installed')]).mapped('name')
# Find specific module
env['ir.module.module'].search([('name', '=', 'sale')])[0].state
# ---- SYSTEM PARAMS ----
env['ir.config_parameter'].sudo().get_param('web.base.url')
env['ir.config_parameter'].sudo().set_param('web.base.url', 'https://mysite.com')
env.cr.commit()
# ---- RAW SQL ----
env.cr.execute("SELECT id, name, state FROM ir_module_module WHERE state='installed' LIMIT 10")
rows = env.cr.fetchall()
for row in rows:
print(row)
# ---- COMMIT CHANGES ----
env.cr.commit() # Always commit after writes!
# ---- ROLLBACK ----
env.cr.rollback() # Undo uncommitted changes
17. Environment Variables (.env)
Docker .env File
# .env (for docker-compose)
# Copy from .env.example and customize
# PostgreSQL settings
POSTGRES_USER=odoo
POSTGRES_PASSWORD=change_me_in_production
POSTGRES_DB=postgres
# Odoo ports
ODOO_HTTP_PORT=8069
ODOO_LONGPOLLING_PORT=8072
# Development mode (set to 'all' for dev, empty for prod)
DEV_MODE=all
# Build settings
ODOO_VERSION=17
# Optional: custom config file
ODOO_CONFIG=/etc/odoo/odoo.conf
Local Development .env File
# .env.local (for local dev, load with dotenv or manually)
ODOO_CONFIG=conf/myproject17.conf
ODOO_DATABASE=myproject17
ODOO_PORT=8069
ODOO_LONGPOLLING_PORT=8072
PGUSER=odoo
PGPASSWORD=odoo
PGHOST=localhost
PGPORT=5432
Using .env in PowerShell
# Load .env file in PowerShell
Get-Content .env | ForEach-Object {
if ($_ -match '^([^#][^=]*)=(.*)$') {
[System.Environment]::SetEnvironmentVariable($matches[1].Trim(), $matches[2].Trim())
}
}
# Or use dotenv package
pip install python-dotenv
18. Available Commands Reference
Command Overview Table
| Command | Description | Environment |
|---|---|---|
/odoo-service |
Main help and status | Any |
/odoo-start |
Start Odoo server (auto-detects env) | Local / Docker |
/odoo-stop |
Stop Odoo server / containers | Local / Docker |
/odoo-init |
Initialize new Odoo environment | Local / Docker |
/odoo-db |
Database operations (backup, restore, create, drop) | Local / Docker |
/odoo-docker |
Docker management (build, up, down, logs, shell) | Docker |
/odoo-ide |
Generate PyCharm/VSCode configurations | Any |
Quick Start Examples
# --- LOCAL VENV WORKFLOW ---
# 1. Initialize new project
/odoo-init --version 17 --project myproject --port 8069
# 2. Start in dev mode
/odoo-start --config myproject17.conf --dev
# 3. Update a module
python -m odoo -c conf/myproject17.conf -d myproject17 -u my_module --stop-after-init
# 4. Stop server
/odoo-stop
# 5. Backup database
/odoo-db backup --db myproject17
# --- DOCKER WORKFLOW ---
# 1. Initialize Docker project
/odoo-init --docker --version 17 --project myproject
# 2. Build and start
/odoo-docker up
# 3. View logs
/odoo-docker logs
# 4. Open shell
/odoo-docker shell
# 5. Update module
/odoo-docker update --db mydb --module my_module
# 6. Backup database
/odoo-db backup --docker odoo_db --db mydb
# 7. Stop
/odoo-docker down
19. Odoo Version-Specific Notes
Odoo 14 Specifics
# Use longpolling_port (not gevent_port)
longpolling_port = 8072
# Python must be 3.7-3.10 (3.8 recommended)
# node.js + npm required for JS assets
npm install -g less less-plugin-clean-css
# Worker restart is via SIGHUP on Linux
kill -HUP $(cat logs/odoo.pid)
Odoo 17 Specifics
# gevent_port is the correct name (not longpolling_port)
gevent_port = 8072
# rtlcss required for Arabic/RTL language support
npm install -g rtlcss
# Assets are compiled differently (OWL 2.x)
# Use --dev=all for asset recompilation
# New: ORM caching improvements
# New: WhatsApp integration support
Odoo 18-19 Specifics
# cbor2 package required
pip install cbor2
# Odoo 19: libmagic1 required
apt-get install libmagic1
pip install python-magic
# New REST API framework in v17+
# New: spreadsheet integration
# PostgreSQL 15+ recommended for v18/19
20. Script Usage Reference
server_manager.py
# Start Odoo
python odoo-service/scripts/server_manager.py start --config conf/myproject.conf --dev
# Stop Odoo
python odoo-service/scripts/server_manager.py stop --port 8069
# Check status
python odoo-service/scripts/server_manager.py status
# Restart
python odoo-service/scripts/server_manager.py restart --config conf/myproject.conf
# Install module
python odoo-service/scripts/server_manager.py install --config conf/myproject.conf --db mydb --module my_module
# Update module
python odoo-service/scripts/server_manager.py update --config conf/myproject.conf --db mydb --module my_module
env_initializer.py
# Initialize complete environment
python odoo-service/scripts/env_initializer.py init --version 17 --project myproject --port 8069
# Just create venv
python odoo-service/scripts/env_initializer.py venv --python python3.11
# Check environment
python odoo-service/scripts/env_initializer.py check
# Generate config file only
python odoo-service/scripts/env_initializer.py conf --project myproject --version 17 --db mydb
db_manager.py
# Backup database
python odoo-service/scripts/db_manager.py backup --db myproject17 --output backups/
# Restore from dump
python odoo-service/scripts/db_manager.py restore --file backups/backup.dump --db restored_db
# Create database
python odoo-service/scripts/db_manager.py create --db newproject17
# Drop database
python odoo-service/scripts/db_manager.py drop --db oldproject
# List databases
python odoo-service/scripts/db_manager.py list
# Reset admin password
python odoo-service/scripts/db_manager.py reset-admin --db myproject17 --password newpass
docker_manager.py
# Generate Docker files
python odoo-service/scripts/docker_manager.py init --version 17 --project myproject
# Build image
python odoo-service/scripts/docker_manager.py build
# Start containers
python odoo-service/scripts/docker_manager.py up
# Stop containers
python odoo-service/scripts/docker_manager.py down
# Follow logs
python odoo-service/scripts/docker_manager.py logs
# Open shell
python odoo-service/scripts/docker_manager.py shell
# Check status
python odoo-service/scripts/docker_manager.py status
ide_configurator.py
# Generate VSCode config (local env)
python odoo-service/scripts/ide_configurator.py --ide vscode --env local --config myproject.conf
# Generate PyCharm config (Docker)
python odoo-service/scripts/ide_configurator.py --ide pycharm --env docker --project myproject
# Generate both IDE configs
python odoo-service/scripts/ide_configurator.py --ide both --env docker --project myproject
# Generate .gitignore
python odoo-service/scripts/ide_configurator.py --gitignore-only
This skill covers Odoo 14-19 server lifecycle management across all environments. For project-specific patterns, refer to version-specific CLAUDE.md files.