Odoo: Self-Hosted Open Source ERP
Odoo 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: [email protected], password: pigsty
Quick Start
On a fresh Linux x86/ARM server running a compatible operating system:
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 defines a template configuration file containing the resources required for a single Odoo instance.
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' }
node_crontab: [ '00 01 * * * postgres /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
version: v4.0.0 # Pigsty version string
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:[email protected]
#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:
# 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:
make up # docker compose up
Access http://odoo.pigsty or http://10.10.10.10:8069
Makefile
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.
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:
bin/pgsql-user pg-meta dbuser_odoo
#bin/pgsql-db pg-meta odoo # Odoo will create the database during setup
Check connectivity:
psql postgres://dbuser_odoo:[email protected]:5432/odoo
Expose Odoo Service
Expose the Odoo web service via Nginx portal:
infra_portal: # Domain names and upstream servers
home : { domain: h.pigsty }
grafana : { domain: g.pigsty ,endpoint: "${admin_ip}:3000" , websocket: true }
prometheus : { domain: p.pigsty ,endpoint: "${admin_ip}:9058" }
alertmanager : { domain: a.pigsty ,endpoint: "${admin_ip}:9059" }
blackbox : { endpoint: "${admin_ip}:9115" }
loki : { endpoint: "${admin_ip}:3100" }
odoo : { domain: odoo.pigsty, endpoint: "127.0.0.1:8069", websocket: true } # <------ Add this line
./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.
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:
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 addons: Accounting Kit
Demo
Check the public demo: http://odoo.pigsty.io, username: [email protected], 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).
Feedback
Was this page helpful?
Thanks for the feedback! Please let us know how we can improve.
Sorry to hear that. Please let us know how we can improve.