Skip to content

Docker vs DBFilter

When you create a subscription, you choose a deployment strategy: Docker or DBFilter. This is the most consequential decision in your SaaS setup — it determines how customer instances are isolated, how they scale, and how they are managed. The right choice depends on your isolation requirements, expected customer count, available server resources, and the technical profile of your customer base. You cannot change strategy after a subscription is created, so it is worth understanding the trade-offs before you start provisioning.


How Each Strategy Works

Docker

Each subscription runs as an isolated Docker stack managed through Portainer. The stack contains:

  • An Odoo container (the customer's Odoo instance)
  • A named Docker volume for filestore data
  • Optionally a bundled PostgreSQL container, or a connection to an external PostgreSQL server
  • Its own assigned HTTP port (and WebSocket port if workers > 1)

Nginx Proxy Manager receives a proxy host entry that routes the customer's domain to that port on the host machine.

Every subscription is completely independent — its own process, its own filesystem, its own database. One subscription crashing or consuming resources has no effect on others.

customer1.sadeem.cloud → NPM → host:8100 → Docker stack (Odoo + PG)
customer2.sadeem.cloud → NPM → host:8103 → Docker stack (Odoo + PG)
customer3.sadeem.cloud → NPM → host:8106 → Docker stack (Odoo + PG)

DBFilter

All subscriptions share a single running Odoo instance on a server. Each customer has their own database on that instance, and Odoo's --db-filter startup flag routes each incoming request to the correct database based on the domain name.

Nginx Proxy Manager routes all customer domains to the same Odoo port on the shared server.

customer1.sadeem.cloud → NPM → shared-odoo:8069 (db: customer1)
customer2.sadeem.cloud → NPM → shared-odoo:8069 (db: customer2)
customer3.sadeem.cloud → NPM → shared-odoo:8069 (db: customer3)

Side-by-Side Comparison

Docker DBFilter
Isolation Full — separate process, volume, ports per subscription Shared — one Odoo process serves all customers
Resource usage Higher — each subscription uses its own RAM and CPU Lower — customers share the Odoo worker pool
Resource cost per customer High — minimum ~256–512 MB RAM per idle container Low — incremental cost per additional database is near zero
Odoo version per customer Any — each stack uses its own Docker image Same for all — all customers run the same Odoo instance
Custom addons per customer Yes — mounted into each container independently Limited — addons are installed at the instance level
Startup time Slower — stack must be created and started Fast — database already accessible on the running instance
Provisioning speed 60–120 seconds (stack pull + container start) 10–30 seconds (database create or template restore)
Ideal customer count per server 10–50 (depends on RAM; each stack is a separate process) 50–500+ (CPU/memory shared; scales well for small tenants)
Stop/Start Stack is paused/resumed in Portainer Database access is revoked; Odoo keeps running
Failure blast radius One stack crashes → only that customer affected One error in shared Odoo process can affect all customers
Scaling Scale by adding more servers/environments Scale by adding more shared Odoo instances
Backup granularity Per-subscription — each stack has its own database and filestore volume, backed up independently Per-database — database dump per customer; filestore backup may be shared or per-database depending on setup
PostgreSQL Bundled in stack, or external server External — the shared Odoo server's database host
Portainer required Yes No
Root server Auto-assigned from Portainer environment Not used unless Git integration is enabled
Migration path between strategies No automated tool — requires exporting the database and filestore from the source subscription and importing under a new subscription with the target strategy Same — no automated migration; manual export and re-import required

When to Choose Docker

  • You want strong isolation between customers
  • Customers may need different Odoo versions or custom addons
  • You are comfortable managing Docker and Portainer
  • You have enough server resources to run multiple containers
  • You need per-subscription start/stop without affecting others
  • You need granular per-subscription backups with independent restore capability
  • You serve customers who may have compliance or data residency requirements that benefit from process-level isolation

When to Choose DBFilter

  • You are managing a large number of small customers on limited hardware
  • All customers run the same Odoo version and addon set
  • You want fast provisioning (database creation vs. stack launch)
  • You have an existing shared Odoo instance to reuse
  • You are running a trial or freemium tier where resource efficiency is critical
  • You expect high subscription churn and want provisioning to be fast and lightweight

Can You Mix Both?

Yes. You can have Docker subscriptions and DBFilter subscriptions on the same Odoo master instance. Install both sadeem_saas_docker and sadeem_saas_dbfilter and choose the type per subscription at creation time.

Once a subscription is created, its SAAS Type field is fixed and cannot be changed. There is no automated migration path between strategies. If you need to move a customer from Docker to DBFilter (or vice versa), you must export the customer's database and filestore from the existing subscription, create a new subscription with the target strategy, and import the data into it. Plan your strategy choice carefully before provisioning.

Warning

Attempting to change saas_subscription_type on an existing subscription after it has been confirmed is not supported. Always set the correct type before clicking Confirm.