
How to Install Odoo with Docker on Ubuntu
Docker has revolutionized how we deploy applications, and Odoo – one of the most popular open-source ERP systems – is no exception. Installing Odoo with Docker on Ubuntu offers significant advantages over traditional bare-metal installations: isolated environments, easy scaling, simplified maintenance, and the ability to run multiple Odoo instances without conflicts. This guide will walk you through setting up a production-ready Odoo installation using Docker containers, covering everything from initial setup to troubleshooting common issues and performance optimization.
Why Docker for Odoo Installation
Traditional Odoo installations often involve dependency hell, version conflicts, and complex server configurations. Docker containers solve these problems by packaging Odoo with all its dependencies in isolated environments. Here’s why this approach makes sense:
- Environment consistency across development, staging, and production
- Easy rollback and version management
- Resource isolation and better security
- Simplified backup and migration processes
- Ability to run multiple Odoo versions simultaneously
Installation Method | Setup Time | Maintenance | Scaling | Isolation |
---|---|---|---|---|
Traditional Install | 2-4 hours | Complex | Difficult | None |
Docker Install | 30-60 minutes | Simple | Easy | Complete |
Prerequisites and System Requirements
Before diving into the installation, ensure your Ubuntu system meets these requirements:
- Ubuntu 18.04 LTS or newer (20.04 LTS recommended)
- Minimum 2GB RAM (4GB+ recommended for production)
- 20GB+ available disk space
- Root or sudo access
- Internet connection for downloading images
First, update your system and install Docker:
sudo apt update && sudo apt upgrade -y
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release -y
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose -y
# Add current user to docker group
sudo usermod -aG docker $USER
newgrp docker
Setting Up Odoo with Docker Compose
Docker Compose simplifies multi-container deployments. Create a project directory and configuration files:
mkdir ~/odoo-docker && cd ~/odoo-docker
mkdir -p addons config data
Create the docker-compose.yml
file:
version: '3.8'
services:
db:
image: postgres:13
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=odoo_password
- POSTGRES_USER=odoo
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- odoo-db-data:/var/lib/postgresql/data/pgdata
restart: unless-stopped
networks:
- odoo-network
odoo:
image: odoo:15.0
depends_on:
- db
ports:
- "8069:8069"
environment:
- HOST=db
- USER=odoo
- PASSWORD=odoo_password
volumes:
- odoo-web-data:/var/lib/odoo
- ./config:/etc/odoo
- ./addons:/mnt/extra-addons
restart: unless-stopped
networks:
- odoo-network
volumes:
odoo-web-data:
odoo-db-data:
networks:
odoo-network:
driver: bridge
Create an Odoo configuration file at config/odoo.conf
:
[options]
addons_path = /mnt/extra-addons
data_dir = /var/lib/odoo
db_host = db
db_port = 5432
db_user = odoo
db_password = odoo_password
db_maxconn = 64
list_db = True
log_level = info
max_cron_threads = 2
workers = 4
xmlrpc_port = 8069
proxy_mode = True
Launching Your Odoo Instance
Start the containers and monitor the startup process:
# Launch containers in detached mode
docker-compose up -d
# Monitor logs to ensure successful startup
docker-compose logs -f odoo
# Check running containers
docker-compose ps
The startup process typically takes 30-60 seconds. Look for these log messages indicating successful initialization:
odoo_1 | INFO ? odoo.modules.loading: loading 1 modules...
odoo_1 | INFO ? odoo.modules.loading: 1 modules loaded in 0.01s, 0 queries
odoo_1 | INFO ? odoo.service.server: HTTP service (werkzeug) running on 0.0.0.0:8069
Access your Odoo instance at http://your-server-ip:8069
. The initial setup wizard will guide you through database creation and basic configuration.
Production Configuration and Security
For production deployments, several modifications are essential for security and performance:
Environment Variables and Secrets
Create a .env
file for sensitive data:
# .env file
POSTGRES_PASSWORD=your_secure_password_here
ODOO_DB_PASSWORD=your_secure_password_here
POSTGRES_USER=odoo_user
Update docker-compose.yml
to use environment variables:
version: '3.8'
services:
db:
image: postgres:13
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- odoo-db-data:/var/lib/postgresql/data/pgdata
restart: unless-stopped
networks:
- odoo-network
odoo:
image: odoo:15.0
depends_on:
- db
ports:
- "127.0.0.1:8069:8069" # Bind to localhost only
environment:
- HOST=db
- USER=${POSTGRES_USER}
- PASSWORD=${POSTGRES_PASSWORD}
volumes:
- odoo-web-data:/var/lib/odoo
- ./config:/etc/odoo
- ./addons:/mnt/extra-addons
restart: unless-stopped
networks:
- odoo-network
Reverse Proxy with Nginx
Add Nginx as a reverse proxy for SSL termination and better performance:
# Add to docker-compose.yml
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/ssl:/etc/nginx/ssl
depends_on:
- odoo
restart: unless-stopped
networks:
- odoo-network
Create nginx/nginx.conf
:
events {
worker_connections 1024;
}
http {
upstream odoo {
server odoo:8069;
}
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
client_max_body_size 2G;
location / {
proxy_pass http://odoo;
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://odoo:8072;
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;
}
}
}
Performance Optimization
Optimizing your Dockerized Odoo installation involves several layers:
Database Optimization
Configure PostgreSQL for better performance by creating postgres/postgresql.conf
:
# PostgreSQL optimization for Odoo
shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
work_mem = 4MB
min_wal_size = 1GB
max_wal_size = 4GB
Odoo Worker Configuration
Calculate optimal worker count based on available resources:
# Formula: (CPU cores * 2) + 1
# For 4 CPU cores: (4 * 2) + 1 = 9 workers
# Update config/odoo.conf:
workers = 9
max_cron_threads = 4
worker_connections = 8192
limit_memory_hard = 2684354560 # 2.5GB
limit_memory_soft = 2147483648 # 2GB
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
Resource | Minimum | Recommended | High Performance |
---|---|---|---|
RAM | 2GB | 4GB | 8GB+ |
CPU Cores | 2 | 4 | 8+ |
Workers | 3 | 9 | 17+ |
DB Connections | 32 | 64 | 128+ |
Backup and Maintenance Strategies
Regular backups are crucial for production systems. Create automated backup scripts:
#!/bin/bash
# backup.sh - Automated Odoo backup script
BACKUP_DIR="/backups/odoo"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="your_database_name"
mkdir -p $BACKUP_DIR
# Database backup
docker-compose exec -T db pg_dump -U odoo $DB_NAME | gzip > $BACKUP_DIR/db_backup_$DATE.sql.gz
# Filestore backup
docker-compose exec -T odoo tar czf - /var/lib/odoo/filestore/$DB_NAME > $BACKUP_DIR/filestore_backup_$DATE.tar.gz
# Keep only last 7 days of backups
find $BACKUP_DIR -type f -mtime +7 -delete
echo "Backup completed: $DATE"
Set up automated backups with cron:
# Add to crontab (crontab -e)
0 2 * * * /path/to/backup.sh >> /var/log/odoo-backup.log 2>&1
Troubleshooting Common Issues
Container Won’t Start
Most startup issues relate to configuration or permission problems:
# Check container logs
docker-compose logs odoo
docker-compose logs db
# Verify file permissions
sudo chown -R 101:101 data/
sudo chmod -R 755 config/
# Test database connectivity
docker-compose exec odoo psql -h db -U odoo -d postgres
Performance Issues
Monitor resource usage and identify bottlenecks:
# Monitor container resource usage
docker stats
# Check database performance
docker-compose exec db psql -U odoo -d postgres -c "SELECT * FROM pg_stat_activity;"
# Analyze slow queries
docker-compose exec db psql -U odoo -d postgres -c "SELECT query, mean_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 5;"
SSL/TLS Certificate Issues
For Let’s Encrypt certificates, integrate Certbot:
# Add Certbot service to docker-compose.yml
certbot:
image: certbot/certbot
volumes:
- ./nginx/ssl:/etc/letsencrypt
- ./nginx/www:/var/www/certbot
command: certonly --webroot --webroot-path=/var/www/certbot --email your-email@domain.com --agree-tos --no-eff-email -d your-domain.com
Advanced Configuration and Custom Modules
For organizations requiring custom functionality, Docker simplifies module development and deployment:
# Custom module directory structure
addons/
├── custom_module_1/
│ ├── __init__.py
│ ├── __manifest__.py
│ └── models/
├── custom_module_2/
│ ├── __init__.py
│ ├── __manifest__.py
│ └── views/
Create a custom Dockerfile for additional dependencies:
# Dockerfile.custom
FROM odoo:15.0
USER root
# Install additional Python packages
RUN pip3 install pandas numpy requests beautifulsoup4
# Install system packages if needed
RUN apt-get update && apt-get install -y \
python3-dev \
libxml2-dev \
libxslt1-dev \
&& rm -rf /var/lib/apt/lists/*
USER odoo
Update docker-compose.yml to use the custom image:
odoo:
build:
context: .
dockerfile: Dockerfile.custom
# ... rest of configuration
Monitoring and Logging
Implement comprehensive monitoring for production environments:
# Add monitoring stack to docker-compose.yml
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
networks:
- odoo-network
grafana:
image: grafana/grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
networks:
- odoo-network
Configure log rotation to prevent disk space issues:
# /etc/logrotate.d/docker-containers
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
size=1M
missingok
delaycompress
copytruncate
}
Real-World Use Cases and Examples
This Docker-based Odoo setup excels in several scenarios:
- Multi-tenant SaaS platforms: Each client gets isolated containers with custom configurations
- Development environments: Developers can quickly spin up identical environments for testing
- Staging and production parity: Identical container configurations across all environments
- Microservices architecture: Odoo as part of larger containerized application stacks
A real-world example from a manufacturing company shows significant benefits:
Metric | Before Docker | After Docker | Improvement |
---|---|---|---|
Deployment Time | 4 hours | 15 minutes | 93% reduction |
Environment Issues | 2-3 per month | 0-1 per month | 67% reduction |
Backup/Restore Time | 2 hours | 30 minutes | 75% reduction |
System Downtime | 4 hours/month | 1 hour/month | 75% reduction |
Security Best Practices
Implement these security measures for production deployments:
- Run containers with non-root users
- Use Docker secrets for sensitive data
- Implement network segmentation
- Regular security updates for base images
- Enable Docker Content Trust
- Monitor container behavior with tools like Falco
# Security-hardened docker-compose.yml snippet
services:
odoo:
image: odoo:15.0
user: "101:101" # Use odoo user
read_only: true # Read-only root filesystem
tmpfs:
- /tmp
- /var/run
cap_drop:
- ALL
cap_add:
- SETGID
- SETUID
security_opt:
- no-new-privileges:true
This comprehensive Docker-based Odoo installation provides a robust foundation for both development and production environments. The containerized approach offers superior maintainability, scalability, and reliability compared to traditional installations. For additional resources and advanced configurations, consult the official Odoo documentation and Docker Compose documentation.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.