Why Odoo Crashes
Odoo can crash from OOM kills, uncaught exceptions, worker timeouts, or resource exhaustion. A production server must automatically recover from crashes without manual intervention. Multiple strategies ensure high availability.
Systemd Auto-Restart
# /etc/systemd/system/odoo.service
[Service]
Restart=on-failure
RestartSec=5
StartLimitBurst=5
StartLimitIntervalSec=300
# Restart policies:
# on-failure: restart on non-zero exit, signal, timeout
# always: restart regardless of exit status
# on-abnormal: restart on signal, timeout, watchdog
# on-abort: restart on signal only
# Recommended: on-failure
# Restarts on crash but not on clean 'systemctl stop'
# StartLimitBurst/Interval:
# Max 5 restarts in 300 seconds
# After that, service enters 'failed' state
# Manual intervention neededSystemd Watchdog
# Built-in systemd watchdog:
[Service]
Type=notify
WatchdogSec=30
# Odoo must send sd_notify("WATCHDOG=1") periodically
# If not received within 30s, systemd kills and restarts
# For Odoo (which doesn't natively support sd_notify),
# use a wrapper script:
# /opt/odoo/watchdog.sh
#!/bin/bash
/opt/odoo/venv/bin/python3 /opt/odoo/odoo-server/odoo-bin \
--config=/etc/odoo.conf &
ODOO_PID=$!
while kill -0 $ODOO_PID 2>/dev/null; do
if curl -sf http://localhost:8069/web/health > /dev/null; then
systemd-notify WATCHDOG=1
fi
sleep 10
doneMonit Process Monitor
# Install Monit
sudo apt install -y monit
# /etc/monit/conf.d/odoo
check process odoo with pidfile /var/run/odoo.pid
start program = "/usr/bin/systemctl start odoo"
stop program = "/usr/bin/systemctl stop odoo"
if failed host 127.0.0.1 port 8069
protocol http request "/web/health"
with timeout 15 seconds
for 3 cycles
then restart
if cpu > 90% for 5 cycles then restart
if memory > 80% for 3 cycles then restart
if 5 restarts within 5 cycles then alert
# Enable Monit
sudo systemctl enable --now monit
sudo monit reloadHealth Check Script
# /opt/odoo/healthcheck.sh
#!/bin/bash
MAX_FAILURES=3
FAILURES=0
while true; do
HTTP_CODE=$(curl -so /dev/null -w "%{http_code}" \
--max-time 10 http://localhost:8069/web/health 2>/dev/null)
if [ "$HTTP_CODE" != "200" ]; then
FAILURES=$((FAILURES + 1))
logger -t odoo-health "Health check failed ($FAILURES/$MAX_FAILURES)"
if [ $FAILURES -ge $MAX_FAILURES ]; then
logger -t odoo-health "Restarting Odoo after $MAX_FAILURES failures"
systemctl restart odoo
FAILURES=0
sleep 30 # Wait for startup
fi
else
FAILURES=0
fi
sleep 15
done
# Run as systemd service:
# /etc/systemd/system/odoo-health.serviceCrash Notifications
# Systemd email on failure:
# /etc/systemd/system/odoo.service.d/notify.conf
[Unit]
OnFailure=odoo-notify@%n.service
# /etc/systemd/system/[email protected]
[Unit]
Description=Crash notification for %i
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c '\
echo "Service %i crashed at $(date)" | \
mail -s "ALERT: %i crashed" [email protected]'
# Or use webhook:
ExecStart=/usr/bin/curl -X POST \
-d '{"text":"Odoo crashed and restarted"}' \
https://hooks.slack.com/services/XXXXOOM Kill Prevention
# Adjust OOM score for Odoo
# Lower score = less likely to be killed
echo -500 | sudo tee /proc/$(pgrep -f odoo-bin)/oom_score_adj
# Permanent via systemd:
[Service]
OOMScoreAdjust=-500
# Combined with swap and memory limits:
MemoryMax=4G
MemoryHigh=3GDeployMonkey
DeployMonkey monitors every Odoo instance with health checks and automatic restart. Crash notifications are sent via the control panel with no manual setup required.