BLOG POSTS
How to Install Odoo with Docker on Ubuntu

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.

Leave a reply

Your email address will not be published. Required fields are marked