Skip to main content
Reference Guide

Odoo Docker Hub — Official Image Tags, Versions & Usage

The official Odoo Docker image is the fastest way to get an Odoo instance running. Pull it, point it at a PostgreSQL database, and you have a working ERP in under a minute. This guide is a complete reference for the official odoo image on Docker Hub: every tag, every environment variable, every volume mount, and the decisions you need to make before deploying to production.

15 min read
Updated February 2026
Odoo 15–19

Odoo on Docker Hub — Overview

The official Odoo image lives at hub.docker.com/_/odoo. It is maintained by the Odoo S.A. team and published as a Docker Official Image, which means it goes through Docker's review process for security and best practices.

What the image includes:

  • Odoo Community Edition (server + web client)
  • Python 3.11+ runtime with all required Python dependencies
  • wkhtmltopdf for PDF report generation
  • Node.js and rtlcss for RTL language support
  • A minimal odoo.conf configuration
  • An entrypoint script that handles database initialization

What it does not include:

  • PostgreSQL — you provide this as a separate container or external service
  • Nginx or any reverse proxy
  • SSL certificates
  • Enterprise edition modules
  • Custom or third-party addons

The image is rebuilt and pushed whenever a new Odoo point release ships, so you get security patches without building anything yourself. For most versions, that means updates within days of an upstream release.

Image Tags & Versions

The odoo image on Docker Hub follows a consistent tagging scheme. Here is every tag you will encounter:

TagOdoo VersionBase OSStatus
odoo:18.018.0 (latest stable)Debian BookwormActive — recommended
odoo:1818.0 (alias)Debian BookwormActive
odoo:latest18.0 (alias)Debian BookwormActive — avoid in production
odoo:17.017.0Debian BookwormActive — LTS
odoo:1717.0 (alias)Debian BookwormActive
odoo:16.016.0Debian BullseyeMaintenance — security fixes only
odoo:1616.0 (alias)Debian BullseyeMaintenance
odoo:15.015.0Debian BullseyeEnd of life — do not use for new projects
odoo:1515.0 (alias)Debian BullseyeEnd of life

Tag naming rules:

  • X.0 (e.g., 18.0) — The specific major version. This is what you should use in production. It tracks the latest point release within that major version.
  • X (e.g., 18) — Alias for X.0. Functionally identical.
  • latest — Always points to the newest stable major version. Right now that is 18.0. Never use this in production because it will jump to 19.0 the moment that ships, and your database will not be compatible.

There are no separate -slim tags in the official Odoo repository. The image is already reasonably sized (roughly 700–900 MB compressed depending on version). If you need a smaller image, you will need to build your own — covered in the Building Custom Images section below.

Which tag should you pick?

  • New projects: odoo:18.0 — latest stable with all current features.
  • Existing production: Whatever major version you are already running. Do not jump major versions without a database migration.
  • Development/testing: Match your production version exactly.

Pulling & Running the Image

Start with the basics. Pull the image:

docker pull odoo:18.0

The simplest possible run — a throwaway instance for testing:

Terminalbash
# Start PostgreSQL
docker run -d \
  --name odoo-db \
  -e POSTGRES_USER=odoo \
  -e POSTGRES_PASSWORD=odoo \
  -e POSTGRES_DB=postgres \
  postgres:16

# Start Odoo, linked to the database
docker run -d \
  --name odoo \
  --link odoo-db:db \
  -p 8069:8069 \
  odoo:18.0

Open http://localhost:8069 and you will see the database manager. Create a database and you are running Odoo.

A better minimal example with Docker Compose:

docker-compose.ymlyaml
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: odoo
      POSTGRES_PASSWORD: odoo
      POSTGRES_DB: postgres
    volumes:
      - odoo-db-data:/var/lib/postgresql/data

  odoo:
    image: odoo:18.0
    depends_on:
      - db
    ports:
      - "8069:8069"
    environment:
      HOST: db
      USER: odoo
      PASSWORD: odoo
    volumes:
      - odoo-filestore:/var/lib/odoo

volumes:
  odoo-db-data:
  odoo-filestore:
docker compose up -d

This gives you persistent data across container restarts. For a full production-ready Compose file with Nginx, SSL, and backups, see our Odoo Docker Compose guide or generate one with the Docker Compose Generator.

Environment Variables

The Odoo Docker image accepts these environment variables to configure the database connection and server behavior:

VariableDefaultDescription
HOSTdbPostgreSQL hostname
PORT5432PostgreSQL port
USERodooPostgreSQL username
PASSWORDodooPostgreSQL password
DBNAME(none)Restrict Odoo to a single database name. If unset, Odoo can manage multiple databases.

These are the variables the entrypoint script handles. For any other Odoo configuration, you have two options:

Option 1: Mount a custom odoo.conf

volumes:
  - ./odoo.conf:/etc/odoo/odoo.conf

Your odoo.conf can include any Odoo server parameter:

odoo.confini
[options]
addons_path = /mnt/extra-addons
admin_passwd = your-strong-master-password
db_host = db
db_port = 5432
db_user = odoo
db_password = odoo
dbfilter = ^mydb$
list_db = False
proxy_mode = True
workers = 4
limit_memory_hard = 2684354560
limit_memory_soft = 2147483648
limit_time_cpu = 600
limit_time_real = 1200

Option 2: Pass Odoo CLI flags directly

docker-compose.ymlyaml
services:
  odoo:
    image: odoo:18.0
    command: -- --db-filter='^mydb$$' --without-demo=all --workers=4

Arguments after -- are passed directly to the Odoo server process. This is useful for overriding a few settings without managing a full config file.

Important: Always set admin_passwd (the database manager master password) in production. The default is empty, which means anyone can create or drop databases through the web interface.

Volume Mounts

Three paths inside the container hold data you care about:

Container PathPurposeMust Persist?
/var/lib/odooFilestore — uploaded files, attachments, session dataYes — losing this means losing every uploaded document
/mnt/extra-addonsCustom and third-party addon modulesMount your addons here
/etc/odooConfiguration file (odoo.conf)Mount your custom config here
volumes:
  - odoo-filestore:/var/lib/odoo
  - ./custom-addons:/mnt/extra-addons
  - ./odoo.conf:/etc/odoo/odoo.conf

The filestore is critical. If you run docker compose down -v (the -v flag removes volumes), you lose every file your users have uploaded. Treat the filestore volume the same way you treat your database — back it up regularly.

For custom addons, the /mnt/extra-addons path is already included in the default addons_path in the image's built-in config. Just drop your modules in and restart.

Image Variants Explained

The official Odoo image ships as a single variant per version — there is no -slim or -alpine tag.

What is inside the standard image:

  • Debian base (Bookworm for 17+, Bullseye for 15–16)
  • Full Python environment with all Odoo pip dependencies
  • wkhtmltopdf (required for PDF report generation — this is the main size contributor)
  • Node.js + npm + rtlcss (for right-to-left language rendering)
  • System libraries for image processing (Pillow), XML parsing (lxml), LDAP (if needed)

Typical compressed image sizes:

TagCompressed Size
odoo:18.0~750 MB
odoo:17.0~720 MB
odoo:16.0~680 MB

If image size is a concern, you can build a custom slimmed-down image. The tradeoff: removing wkhtmltopdf saves ~200 MB but breaks PDF reports. Removing Node.js saves ~80 MB but breaks RTL support. For most deployments, the standard image is the right choice.

Building Custom Odoo Docker Images

The official image covers the base case. When you need custom Python packages, system dependencies, or third-party addons baked into the image, build your own.

Adding pip packages (e.g., for OCA modules or integrations):

Dockerfiledockerfile
FROM odoo:18.0

USER root

RUN pip3 install --no-cache-dir \
    openupgradelib \
    python-stdnum \
    phonenumbers \
    boto3

USER odoo

Adding system dependencies:

Dockerfiledockerfile
FROM odoo:18.0

USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
    libcups2-dev \
    && rm -rf /var/lib/apt/lists/*

USER odoo

Baking custom addons into the image (for immutable deployments):

Dockerfiledockerfile
FROM odoo:18.0

USER root

COPY ./custom-addons /mnt/extra-addons
RUN chown -R odoo:odoo /mnt/extra-addons

USER odoo

Full production Dockerfile example:

Dockerfiledockerfile
FROM odoo:18.0

USER root

# System dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    libffi-dev \
    && rm -rf /var/lib/apt/lists/*

# Python dependencies
COPY requirements.txt /tmp/requirements.txt
RUN pip3 install --no-cache-dir -r /tmp/requirements.txt \
    && rm /tmp/requirements.txt

# Custom addons
COPY ./addons /mnt/extra-addons
RUN chown -R odoo:odoo /mnt/extra-addons

# Custom config
COPY ./odoo.conf /etc/odoo/odoo.conf
RUN chown odoo:odoo /etc/odoo/odoo.conf

USER odoo

EXPOSE 8069 8072

Build and tag it:

docker build -t my-odoo:18.0 .

Then reference my-odoo:18.0 in your docker-compose.yml instead of the official image.

Tip: Always switch back to USER odoo at the end of your Dockerfile. Running Odoo as root inside a container is a security risk you do not need to take.

Community vs Enterprise Images

Community Edition is what the official odoo image on Docker Hub contains. It is open source (LGPL-3.0), free to use, and includes the core ERP modules.

Enterprise Edition adds proprietary modules (accounting features, studio, marketing automation, etc.) that require an active Odoo subscription. There is no public Enterprise image on Docker Hub.

To run Enterprise with Docker, you have two options:

Option 1: Mount Enterprise addons as a volume

If you have an Odoo Enterprise subscription, you can download the enterprise addons and mount them:

docker-compose.ymlyaml
services:
  odoo:
    image: odoo:18.0
    volumes:
      - ./enterprise-addons:/mnt/enterprise
    command: -- --addons-path=/mnt/extra-addons,/mnt/enterprise

Option 2: Build a custom image with Enterprise addons

Dockerfiledockerfile
FROM odoo:18.0

USER root

# Copy Enterprise addons (not committed to public repos)
COPY ./enterprise /mnt/enterprise
RUN chown -R odoo:odoo /mnt/enterprise

USER odoo

CMD ["odoo", "--addons-path=/mnt/extra-addons,/mnt/enterprise"]

Important: Do not push Enterprise addons to public Docker registries or Git repositories. The Enterprise code is proprietary and covered by Odoo's license agreement. Use a private container registry (GitHub Container Registry, AWS ECR, etc.) for Enterprise images.

Multi-Architecture Support

The official Odoo Docker images are published for multiple architectures:

ArchitecturePlatformUse Case
linux/amd64Intel/AMD 64-bitProduction servers, most cloud VMs
linux/arm64ARM 64-bitApple Silicon Macs (M1/M2/M3/M4), ARM cloud instances (AWS Graviton, Ampere)

Docker automatically pulls the correct architecture for your platform. If you are developing on an M-series Mac, you get the arm64 image. When you deploy to an amd64 server, Docker pulls the amd64 variant. No configuration needed.

Building multi-arch custom images:

If you build a custom image on your M-series Mac and push it to a registry, it will only contain the arm64 variant by default. For production on amd64 servers, use Docker Buildx:

Terminalbash
docker buildx create --use
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t my-registry/my-odoo:18.0 \
  --push .

Performance note: Running amd64 images on ARM (or vice versa) through emulation works but is significantly slower — expect 3–5x performance degradation. Always use native architecture images in production.

Version Upgrade Path with Docker

Docker makes version upgrades more structured, but the database migration is still the hard part.

Step 1: Back up everything

Terminalbash
# Database
docker compose exec db pg_dump -U odoo mydb > backup-pre-upgrade.sql

# Filestore
docker compose exec odoo tar czf - /var/lib/odoo > filestore-backup.tar.gz

Step 2: Pull the new image

docker pull odoo:18.0  # or whatever version you're upgrading to

Step 3: Run the database upgrade

Odoo major version upgrades require the Odoo Upgrade service (upgrade.odoo.com) or manual migration scripts. You cannot simply point a new Odoo version at an old database.

For minor updates within the same major version (e.g., 18.0 January release to 18.0 March release):

Terminalbash
docker compose down
docker compose pull
docker compose up -d
# Odoo handles minor schema updates automatically on startup

Step 4: Rollback strategy

This is why you backed up in Step 1:

Terminalbash
# If something goes wrong, restore the database
docker compose down
docker compose exec db psql -U odoo postgres -c "DROP DATABASE mydb;"
docker compose exec db psql -U odoo postgres < backup-pre-upgrade.sql
# Revert to previous image tag in docker-compose.yml
docker compose up -d

Never upgrade production without a tested backup. Test the upgrade on a copy of your production database first.

Best Practices

These are the rules that will save you from the most common production Docker + Odoo failures:

1. Pin your image tag

Use odoo:18.0, not odoo:latest. The :latest tag will jump to the next major version when it releases, and your database will not be compatible.

2. Always persist the filestore volume

The /var/lib/odoo volume contains every file your users upload. Use a named volume, not a bind mount, and include it in your backup strategy.

3. Set the master password

Configure admin_passwd in your odoo.conf or the database manager is wide open.

4. Disable the database manager in production

Add list_db = False and dbfilter = ^yourdb$ to lock Odoo to a single database and hide the manager UI.

5. Add health checks

docker-compose.ymlyaml
services:
  odoo:
    image: odoo:18.0
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8069/web/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

6. Set resource limits

docker-compose.ymlyaml
services:
  odoo:
    image: odoo:18.0
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: "2.0"
        reservations:
          memory: 1G
          cpus: "1.0"

7. Use proxy_mode = True behind a reverse proxy

When running behind Nginx, Traefik, or any reverse proxy, enable proxy_mode = True. Without this, Odoo will not see the correct client IP addresses.

8. Run multi-worker in production

A single-worker Odoo process cannot handle concurrent users. Set workers = 4 (adjust based on your CPU count) and enable the longpolling port (8072) for live chat and real-time features.

9. Do not run as root

The official image already runs as the odoo user. If you build custom images, make sure you switch back to USER odoo after installing system packages.

10. Tag your custom images with Git commit hashes

Instead of my-odoo:latest, use my-odoo:18.0-abc123f. This makes rollbacks trivial and makes it obvious exactly what code is running.

Skip Docker config entirely

OEC.sh deploys Odoo on your choice of cloud provider (DigitalOcean, AWS, Hetzner, and more) with production configuration handled for you: reverse proxy, SSL, backups, monitoring, and scaling.

  • Full SSH access
  • No vendor lock-in
  • Your cloud, your data
Try OEC.sh Free

Frequently Asked Questions

What is the official Docker image for Odoo?

The official image is `odoo` on Docker Hub (hub.docker.com/_/odoo). It is maintained by Odoo S.A., published as a Docker Official Image, and includes Odoo Community Edition with all required dependencies. Use tags like `odoo:18.0` or `odoo:17.0` to select your version.

How large is the Odoo Docker image?

The compressed image size varies by version: roughly 750 MB for Odoo 18.0, 720 MB for 17.0. The bulk comes from wkhtmltopdf (PDF generation) and the Python dependency tree. The uncompressed image is approximately 1.8–2.2 GB.

Can I run Odoo Enterprise with the Docker Hub image?

The Docker Hub image contains Community Edition only. To run Enterprise, download the Enterprise addons with your Odoo subscription and either mount them as a volume or build a custom Docker image. Do not publish Enterprise addons to public registries — the code is proprietary.

Does the Odoo Docker image include PostgreSQL?

No. You must provide PostgreSQL separately, either as another Docker container, a managed database service (RDS, Cloud SQL), or a standalone server. The Odoo container connects to PostgreSQL via the HOST, PORT, USER, and PASSWORD environment variables.

Should I use odoo:latest in production?

No. The `latest` tag points to the newest major version and will change when a new Odoo version ships. Since major versions are not database-compatible, this would break your deployment. Always pin to a specific version tag like `odoo:18.0`.

How do I update the Odoo Docker image?

For minor updates within the same major version: `docker compose pull && docker compose up -d`. Odoo handles minor schema changes automatically on startup. For major version upgrades (e.g., 17.0 to 18.0), you need to run the Odoo database migration process first — pulling a new image alone is not sufficient.

Deploy Odoo Without the Docker Overhead

You keep full SSH access to your server. No vendor lock-in. If you want to move to self-managed Docker later, you can export everything and go.