Odoo, formerly known as OpenERP, is a suite of open-source business apps written in Python and released under the LGPL license. This suite of applications covers all business needs, from Website/Ecommerce down to manufacturing, inventory and accounting, all seamlessly integrated. It is the first time ever a software editor managed to reach such a functional coverage. Odoo is the most installed business software in the world. Odoo is used by 2.000.000 users worldwide ranging from very small companies (1 user) to very large ones (300 000 users).
wikipedia.org/wiki/Odoo
This image requires a running PostgreSQL server.
$ mkdir -p /var/appjail-volumes/odoo/db
$ appjail oci run -Pd \
-o overwrite=force \
-o virtualnet=":<random> default" \
-o nat \
-o template=template.conf \
-o container="args:--pull" \
-o fstab="/var/appjail-volumes/odoo/db /var/db/postgres" \
-e POSTGRES_USER=odoo \
-e POSTGRES_PASSWORD=odoo \
-e POSTGRES_DB=postgres \
ghcr.io/appjail-makejails/postgres odoo-dbtemplate.conf:
exec.start: "/bin/sh /etc/rc"
exec.stop: "/bin/sh /etc/rc.shutdown jail"
mount.devfs
persist
sysvmsg: new
sysvsem: new
sysvshm: new
$ mkdir -p /var/appjail-volumes/odoo/data
$ appjail oci run -Pd \
-o overwrite=force \
-o virtualnet=":<random> default" \
-o nat \
-o fstab="/var/appjail-volumes/odoo/data /data" \
-o expose=8069 \
-e HOST=odoo-db \
ghcr.io/appjail-makejails/odoo odoo
...
[00:00:39] [ info ] [odoo] Detached: pid:60415, log:jails/odoo/container/2026-07-23.log
$ appjail jail list -j odoo name network_ip4
NAME NETWORK_IP4
odoo 10.0.0.9Then you can hit http://10.0.0.9:8069 (or http://odoo:8069 if you've configured DNS in AppJail) or http://host-ip:8069 in your browser (and from an external host).
$ appjail stop odoo
$ appjail start odoo
$ # Or with just a single command:
$ appjail restart odoo
The default configuration file for the server (located at /usr/local/etc/odoo/odoo.conf) can be overriden at startup using volumes. Suppose you have a custom configuration at /path/to/config/odoo.conf, then
$ appjail oci run -Pd \
-o overwrite=force \
-o virtualnet=":<random> default" \
-o nat \
-o fstab="/var/appjail-volumes/odoo/data /data" \
-o fstab="/path/to/config/odoo.conf usr/local/etc/odoo/odoo.conf nullfs ro" \
-o expose=8069 \
-e HOST=odoo-db \
ghcr.io/appjail-makejails/odoo odooPlease use this configuration template to write your custom configuration as we already set some arguments for running Odoo inside a OCI container.
You can also directly specify Odoo arguments inline. Those arguments must be given after the keyword -- in the command-line, as follows
$ appjail oci run -Pd \
-o overwrite=force \
-o virtualnet=":<random> default" \
-o nat \
-o fstab="/var/appjail-volumes/odoo/data /data" \
-o expose=8069 \
-e HOST=odoo-db \
ghcr.io/appjail-makejails/odoo odoo \
-- --db-filter=odoo_db_.*You can mount your own Odoo addons within the Odoo container, at /mnt/extra-addons
$ appjail oci run -Pd \
-o overwrite=force \
-o virtualnet=":<random> default" \
-o nat \
-o fstab="/var/appjail-volumes/odoo/data /data" \
-o fstab="/path/to/addons /mnt/extra-addons" \
-o expose=8069 \
-e HOST=odoo-db \
ghcr.io/appjail-makejails/odoo odooNote: Altough there is no official Odoo Enterprise Docker image, the Enterprise modules can be mounted by using the above mentioned method.
The simplest appjail-director.yml file would be:
options:
- virtualnet: ':<random> default'
- nat:
- container: 'args:--pull'
services:
web:
name: odoo
makejail: gh+AppJail-makejails/odoo
volumes:
- data: /data
oci:
environment:
- HOST: odoo-db
options:
- expose: 8069
db:
name: odoo-db
priority: 98
makejail: gh+AppJail-makejails/postgres
volumes:
- db: /var/db/postgres
options:
- template: !ENV '${PWD}/template.conf'
scripts:
- type: local
text: service appjail-dns restart
oci:
environment:
- POSTGRES_DB: postgres
- POSTGRES_PASSWORD: odoo
- POSTGRES_USER: odoo
volumes:
data:
device: /var/appjail-volumes/odoo/data
db:
device: /var/appjail-volumes/odoo/db.env:
DIRECTOR_PROJECT=erpIf the default postgres credentials does not suit you, tweak the environment variables:
options:
- virtualnet: ':<random> default'
- nat:
- container: 'args:--pull'
services:
web:
name: odoo
makejail: gh+AppJail-makejails/odoo
volumes:
- data: /data
oci:
environment:
- HOST: odoo-db
- USER: odoo
- PASSWORD: myodoo
options:
- expose: 8069
db:
name: odoo-db
priority: 98
makejail: gh+AppJail-makejails/postgres
volumes:
- db: /var/db/postgres
options:
- template: !ENV '${PWD}/template.conf'
scripts:
- type: local
text: service appjail-dns restart
oci:
environment:
- POSTGRES_DB: postgres
- POSTGRES_PASSWORD: myodoo
- POSTGRES_USER: odoo
volumes:
data:
device: /var/appjail-volumes/odoo/data
db:
device: /var/appjail-volumes/odoo/dbHere's a last example showing you how to
- mount custom addons located in
./addons - use a custom configuration file located in
.config/odoo.conf - use volumes for the Odoo and postgres data dir
- use a file that contains the postgreql password shared by both services
options:
- virtualnet: ':<random> default'
- nat:
- container: 'args:--pull'
- volume: odoo-secrets
services:
web:
name: odoo
makejail: gh+AppJail-makejails/odoo
volumes:
- data: /data
- secrets: odoo-secrets
- config: /usr/local/etc/odoo
- addons: /mnt/extra-addons
oci:
environment:
- HOST: odoo-db
- PASSWORD_FILE: /volumes/odoo-secrets/postgresql_password
options:
- expose: 8069
db:
name: odoo-db
priority: 98
makejail: gh+AppJail-makejails/postgres
volumes:
- db: /var/db/postgres
- secrets: odoo-secrets
options:
- template: !ENV '${PWD}/template.conf'
scripts:
- type: local
text: service appjail-dns restart
oci:
environment:
- POSTGRES_DB: postgres
- POSTGRES_PASSWORD_FILE: /volumes/odoo-secrets/postgresql_password
- POSTGRES_USER: odoo
volumes:
data:
device: /var/appjail-volumes/odoo/data
db:
device: /var/appjail-volumes/odoo/db
config:
device: !ENV '${PWD}/config'
addons:
device: !ENV '${PWD}/addons'
secrets:
device: /var/appjail-volumes/odoo/secrets
type: '<volumefs>'
options: roTo start your Odoo instance, go in the directory of the appjail-director.yml file you created from the previous examples and type:
appjail-director upodoo_from(default:ghcr.io/appjail-makejails/odoo): Location of OCI image. See also OCI Configuration.odoo_tag(default:latest): OCI image tag. See also OCI Configuration.
HOST(default:db): The address of the postgres server. If you used a postgres container, set to the name of the container.PASSWORD(default:odoo): The password of the postgres role with which Odoo will connect. If you used a postgres container, set to the same value asPOSTGRES_PASSWORD.PORT(default:5432): The port the postgres server is listening to.USER(default:odoo): The postgres role with which Odoo will connect. If you used a postgres container, set to the same value asPOSTGRES_USER.PGID(default:1000): Equivalent toPUIDbut for the Process Group ID.PUID(default:1000): Process User ID for the container's main process, allowing you to match the owner of files written to mounted host volumes to your host system's user. Writable volumes are changed based on this environment variable.
| Name | Owner | Group | Perm | Type | Mountpoint |
|---|---|---|---|---|---|
| appjail-263aca83a3-data | ${PUID} |
${PGID} |
- | - | /data |
| appjail-9bfef7104e-mnt_extra-addons | ${PUID} |
${PGID} |
- | - | /mnt/extra-addons |
build:
variants:
- tag: 15.1
containerfile: Containerfile
aliases: ["latest"]
default: true
args:
FREEBSD_RELEASE: "15.1"
PYVER: "312"
NO_PKGCLEAN: "1"
cache_dirs: ["pkgcache0:/var/cache/pkg"]
- tag: 15.1-16
containerfile: Containerfile
args:
FREEBSD_RELEASE: "15.1"
ODOOVER: "16"
PYVER: "312"
NO_PKGCLEAN: "1"
cache_dirs: ["pkgcache0:/var/cache/pkg"]
- tag: 15.1-17
containerfile: Containerfile
args:
FREEBSD_RELEASE: "15.1"
ODOOVER: "17"
PYVER: "312"
NO_PKGCLEAN: "1"
cache_dirs: ["pkgcache0:/var/cache/pkg"]
- tag: 15.1-18
containerfile: Containerfile
args:
FREEBSD_RELEASE: "15.1"
ODOOVER: "18"
PYVER: "312"
NO_PKGCLEAN: "1"
cache_dirs: ["pkgcache0:/var/cache/pkg"]