# Odoo: Self-Hosted Open Source ERP

> How to spin up an out-of-the-box enterprise application suite Odoo and use Pigsty to manage its backend PostgreSQL database.

---

LLMS index: [llms.txt](/llms.txt)

---

[Odoo](https://www.odoo.com/) is an open-source enterprise resource planning (ERP) software that provides a full suite of business applications, including CRM, sales, purchasing, inventory, production, accounting, and other management functions. Odoo is a typical web application that uses PostgreSQL as its underlying database.

> All your business on one platform — Simple, efficient, yet affordable

Public Demo (may not always be available): http://odoo.pigsty.io, username: `test@pigsty.io`, password: `pigsty`



--------

## Quick Start

On a fresh Linux x86/ARM server running a compatible operating system:

```bash
curl -fsSL https://repo.pigsty.io/get | bash; cd ~/pigsty
./bootstrap                # Install Ansible
./configure -c app/odoo    # Use Odoo configuration (change credentials in pigsty.yml)
./deploy.yml               # Install Pigsty
./docker.yml               # Install Docker Compose
./app.yml                  # Start Odoo stateless components with Docker
```

Odoo listens on port 8069 by default. Access `http://<ip>:8069` in your browser. The default username and password are both `admin`.

You can add a DNS resolution record `odoo.pigsty` pointing to your server in the browser host's `/etc/hosts` file, allowing you to access the Odoo web interface via `http://odoo.pigsty`.

If you want to access Odoo via SSL/HTTPS, you need to use a real SSL certificate or trust the self-signed CA certificate automatically generated by Pigsty. (In Chrome, you can also type `thisisunsafe` to bypass certificate verification)




--------

## Configuration Template

[`conf/app/odoo.yml`](https://github.com/pgsty/pigsty/blob/main/conf/app/odoo.yml) defines a template configuration file containing the resources required for a single Odoo instance.

```yaml
all:
  children:

    # Odoo application (default username and password: admin/admin)
    odoo:
      hosts: { 10.10.10.10: {} }
      vars:
        app: odoo   # Specify app name to install (in apps)
        apps:       # Define all applications
          odoo:     # App name, should have corresponding ~/pigsty/app/odoo folder
            file:   # Optional directories to create
              - { path: /data/odoo         ,state: directory, owner: 100, group: 101 }
              - { path: /data/odoo/webdata ,state: directory, owner: 100, group: 101 }
              - { path: /data/odoo/addons  ,state: directory, owner: 100, group: 101 }
            conf:   # Override /opt/<app>/.env config file
              PG_HOST: 10.10.10.10            # PostgreSQL host
              PG_PORT: 5432                   # PostgreSQL port
              PG_USERNAME: odoo               # PostgreSQL user
              PG_PASSWORD: DBUser.Odoo        # PostgreSQL password
              ODOO_PORT: 8069                 # Odoo app port
              ODOO_DATA: /data/odoo/webdata   # Odoo webdata
              ODOO_ADDONS: /data/odoo/addons  # Odoo plugins
              ODOO_DBNAME: odoo               # Odoo database name
              ODOO_VERSION: 19.0              # Odoo image version

    # Odoo database
    pg-odoo:
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars:
        pg_cluster: pg-odoo
        pg_users:
          - { name: odoo    ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_admin ] ,createdb: true ,comment: admin user for odoo service }
          - { name: odoo_ro ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_readonly ]  ,comment: read only user for odoo service  }
          - { name: odoo_rw ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_readwrite ] ,comment: read write user for odoo service }
        pg_databases:
          - { name: odoo ,owner: odoo ,revokeconn: true ,comment: odoo main database  }
        pg_hba_rules:
          - { user: all ,db: all ,addr: 172.17.0.0/16  ,auth: pwd ,title: 'allow access from local docker network' }
          - { user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes' }
        pg_crontab: [ '00 01 * * * /pg/bin/pg-backup full' ] # Full backup daily at 1am

    infra: { hosts: { 10.10.10.10: { infra_seq: 1 } } }
    etcd:  { hosts: { 10.10.10.10: { etcd_seq: 1 } }, vars: { etcd_cluster: etcd } }
    #minio: { hosts: { 10.10.10.10: { minio_seq: 1 } }, vars: { minio_cluster: minio } }

  vars:                               # Global variables
    admin_ip: 10.10.10.10             # Admin node IP address
    region: default                   # Upstream mirror region: default|china|europe
    node_tune: oltp                   # Node tuning specs: oltp,olap,tiny,crit
    pg_conf: oltp.yml                 # PGSQL tuning specs: {oltp,olap,tiny,crit}.yml

    docker_enabled: true              # Enable docker on app group
    #docker_registry_mirrors: ["https://docker.1panel.live","https://docker.1ms.run","https://docker.xuanyuan.me","https://registry-1.docker.io"]

    proxy_env:                        # Global proxy env for downloading packages & pulling docker images
      no_proxy: "localhost,127.0.0.1,10.0.0.0/8,192.168.0.0/16,*.pigsty,*.aliyun.com,mirrors.*,*.tsinghua.edu.cn"
      #http_proxy:  127.0.0.1:12345   # Add proxy env here for downloading packages or pulling images
      #https_proxy: 127.0.0.1:12345   # Usually format is http://user:pass@proxy.xxx.com
      #all_proxy:   127.0.0.1:12345

    infra_portal:                      # Domain names and upstream servers
      home  : { domain: i.pigsty }
      minio : { domain: m.pigsty ,endpoint: "${admin_ip}:9001" ,scheme: https ,websocket: true }
      odoo:                            # Nginx server config for odoo
        domain: odoo.pigsty            # REPLACE WITH YOUR OWN DOMAIN!
        endpoint: "10.10.10.10:8069"   # Odoo service endpoint: IP:PORT
        websocket: true                # Add websocket support
        certbot: odoo.pigsty           # Certbot cert name, apply with `make cert`

    repo_enabled: false
    node_repo_modules: node,infra,pgsql
    pg_version: 18

    #----------------------------------#
    # Credentials: MUST CHANGE THESE!
    #----------------------------------#
    grafana_admin_password: pigsty
    grafana_view_password: DBUser.Viewer
    pg_admin_password: DBUser.DBA
    pg_monitor_password: DBUser.Monitor
    pg_replication_password: DBUser.Replicator
    patroni_password: Patroni.API
    haproxy_admin_password: pigsty
    minio_secret_key: S3User.MinIO
    etcd_root_password: Etcd.Root
```

--------

## Basics

Check the configurable environment variables in the `.env` file:

```bash
# https://hub.docker.com/_/odoo#
PG_HOST=10.10.10.10
PG_PORT=5432
PG_USER=dbuser_odoo
PG_PASS=DBUser.Odoo
ODOO_PORT=8069
```

Then start Odoo with:

```bash
make up  # docker compose up
```

Access [http://odoo.pigsty](http://odoo.pigsty/) or http://10.10.10.10:8069

## Makefile

```bash
make up         # Start Odoo with docker compose in minimal mode
make run        # Start Odoo with docker, local data directory and external PostgreSQL
make view       # Print Odoo access endpoints
make log        # tail -f Odoo logs
make info       # Inspect Odoo with jq
make stop       # Stop Odoo container
make clean      # Remove Odoo container
make pull       # Pull latest Odoo image
make rmi        # Remove Odoo image
make save       # Save Odoo image to /tmp/docker/odoo.tgz
make load       # Load Odoo image from /tmp/docker/odoo.tgz
```

--------

## Using External PostgreSQL

You can use external PostgreSQL for Odoo. Odoo will create its own database during setup, so you don't need to do that.

```yaml
pg_users: [ { name: dbuser_odoo ,password: DBUser.Odoo ,pgbouncer: true ,roles: [ dbrole_admin ]    ,comment: admin user for odoo database } ]
pg_databases: [ { name: odoo ,owner: dbuser_odoo ,revokeconn: true ,comment: odoo primary database } ]
```

Create the business user and database with:

```bash
bin/pgsql-user  pg-meta  dbuser_odoo
#bin/pgsql-db    pg-meta  odoo     # Odoo will create the database during setup
```

Check connectivity:

```bash
psql postgres://dbuser_odoo:DBUser.Odoo@10.10.10.10:5432/odoo
```

------

## Expose Odoo Service

[Expose](/docs/infra/admin/portal/) the Odoo web service via Nginx portal:

```yaml
    infra_portal:                     # Domain names and upstream servers
      home         : { domain: i.pigsty }
      odoo         : { domain: odoo.pigsty, endpoint: "127.0.0.1:8069", websocket: true }  # <------ Add this line
```

```bash
./infra.yml -t nginx   # Setup nginx infra portal
```

------

## Odoo Addons

There are many Odoo modules available in the community. You can install them by downloading and placing them in the `addons` folder.

```yaml
volumes:
  - ./addons:/mnt/extra-addons
```

You can mount the `./addons` directory to `/mnt/extra-addons` in the container, then download and extract addons to the `addons` folder.

To enable addon modules, first enter [Developer mode](https://www.odoo.com/documentation/19.0/applications/general/developer_mode.html):

> Settings -> General Settings -> Developer Tools -> Activate the developer mode

Then go to Apps -> Update Apps List, and you'll find the extra addons available to install from the panel.

Frequently used [free](https://apps.odoo.com/apps/modules/browse?order=Downloads) addons: [Accounting Kit](https://apps.odoo.com/apps/modules/19.0/base_accounting_kit/)

------

## Demo

Check the public demo: [http://odoo.pigsty.io](http://odoo.pigsty.io/), username: `test@pigsty.io`, password: `pigsty`

If you want to access Odoo via SSL, you must trust `files/pki/ca/ca.crt` in your browser (or use the dirty hack `thisisunsafe` in Chrome).
