Skip to content

Fix Odoo Docker Volume Permissions: Filestore & Addon Errors

DeployMonkey Team · March 23, 2026 7 min read

Docker Permission Problems

Odoo Docker containers run as a specific UID (typically 101 for the odoo user). When Docker volumes are mounted from the host, file ownership mismatches cause permission denied errors for the filestore, custom addons, and configuration files.

Filestore Permission Denied

# Error: PermissionError: [Errno 13] Permission denied:
# '/var/lib/odoo/filestore/mydb'

# Cause: Host directory owned by root,
# container runs as uid 101 (odoo)

# Fix 1: Set correct ownership on host
sudo chown -R 101:101 /path/to/odoo-data

# Fix 2: Use named volumes (Docker manages permissions)
# docker-compose.yml:
volumes:
  odoo-data:
    driver: local

services:
  odoo:
    volumes:
      - odoo-data:/var/lib/odoo  # Named volume

# Fix 3: Run container with matching UID
docker run --user $(id -u):$(id -g) odoo:19

Custom Addons Permission

# Error: FileNotFoundError or PermissionError
# when loading custom modules from mounted volume

# Cause: Addon files not readable by container user

# Fix 1: Set permissions on host
sudo chown -R 101:101 /path/to/custom-addons
# Or make world-readable:
chmod -R 755 /path/to/custom-addons

# Fix 2: Copy instead of mount (Dockerfile)
FROM odoo:19
COPY ./custom-addons /mnt/extra-addons
RUN chown -R odoo:odoo /mnt/extra-addons

# Fix 3: Use :ro mount for addons (read-only)
volumes:
  - ./custom-addons:/mnt/extra-addons:ro

PostgreSQL Volume Errors

# Error: PostgreSQL data directory has wrong ownership
# FATAL: data directory "/var/lib/postgresql/data" has
# wrong ownership

# Cause: PostgreSQL container runs as uid 999 (postgres)
# Host directory has different owner

# Fix 1: Let Docker manage the volume
volumes:
  db-data:  # Named volume, Docker handles permissions

services:
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data

# Fix 2: Fix host ownership
sudo chown -R 999:999 /path/to/pg-data

# Fix 3: Initialize fresh
# Remove old data and let PostgreSQL reinitialize
docker volume rm my_pg_data
docker-compose up -d db

Log File Permissions

# Error: Cannot write to log file in container

# Fix: Create log directory with correct ownership
sudo mkdir -p /path/to/odoo-logs
sudo chown 101:101 /path/to/odoo-logs

# Docker compose:
volumes:
  - /path/to/odoo-logs:/var/log/odoo

# Alternative: Log to stdout (recommended for Docker)
# In odoo.conf:
logfile = False
# Logs go to container stdout → docker logs odoo

UID/GID Mapping

# Find the UID inside Odoo container:
docker exec odoo-container id
# uid=101(odoo) gid=101(odoo)

# Find the UID inside PostgreSQL container:
docker exec postgres-container id
# uid=999(postgres) gid=999(postgres)

# Match host user to container user:
# Create matching user on host
sudo useradd -u 101 -g 101 odoo-docker
sudo chown -R odoo-docker: /path/to/odoo-data

# Or use user namespacing:
# /etc/docker/daemon.json
{
  "userns-remap": "default"
}

Docker Compose Best Practices

# Production docker-compose.yml with correct volumes:
version: '3.8'
services:
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data  # Named volume
    environment:
      POSTGRES_USER: odoo
      POSTGRES_PASSWORD: ${DB_PASSWORD}

  odoo:
    image: odoo:19
    volumes:
      - odoo-filestore:/var/lib/odoo          # Named
      - ./custom-addons:/mnt/extra-addons:ro  # Read-only bind
      - ./odoo.conf:/etc/odoo/odoo.conf:ro    # Read-only bind
    depends_on:
      - db

volumes:
  db-data:
  odoo-filestore:

# Named volumes = Docker manages permissions
# Bind mounts = You manage permissions
# :ro = Prevent container from modifying host files

DeployMonkey

DeployMonkey handles Docker volume permissions automatically for every Odoo deployment. No manual chown or UID mapping needed.