Jump to
↵select↑↓navigateescclose

Production

The container image

The all-in-one OCI image odoo-nix builds from a project, its entrypoint's environment variables, and its volume and secret contract.

Updated
Tags
  • containers
  • oci
  • docker
On this page

Set odoo-nix.containers.enable = true and the project gets packages.<SYSTEM>.container-odoo, an all-in-one image built with dockerTools.buildLayeredImage from the project's packages.default. It runs Odoo with its HTTP workers, the websocket process and cron.

nix build .#container-odoo
docker load < result

The image is named <name>-odoo:latest, or <REGISTRY>/<name>-odoo:latest with containers.registry set ("ghcr.io/avunu" gives ghcr.io/avunu/acme-odoo; a trailing slash is dropped). With containers.roleImageNames it is <name>/odoo instead; see The image name. It exposes 8069 and 8072, and its odoo is the full command, so docker exec <CONTAINER> odoo db backup acme works as it does on a server.

Configuration

The entrypoint writes /etc/odoo/odoo.conf at start from environment variables, each with a default:

Variableodoo.conf keyDefault
ODOO_NIX_DB_HOSTdb_hostdb
ODOO_NIX_DB_PORTdb_port5432
ODOO_NIX_DB_USERdb_userodoo
ODOO_NIX_DB_NAMEdb_name, and dbfilter = ^<NAME>$unset
ODOO_NIX_HTTP_PORThttp_port8069
ODOO_NIX_GEVENT_PORTgevent_port8072
ODOO_NIX_WORKERSworkers2
ODOO_NIX_MAX_CRON_THREADSmax_cron_threads2
ODOO_NIX_PROXY_MODEproxy_modeTrue
ODOO_NIX_LIST_DBlist_dbFalse
ODOO_NIX_WITHOUT_DEMOwithout_demoFalse
ODOO_NIX_LOG_LEVELlog_levelinfo
ODOO_NIX_LOG_HANDLERlog_handlerunset
ODOO_NIX_LOG_DBlog_dbunset
ODOO_NIX_LOG_DB_LEVELlog_db_levelwarning

addons_path is the image's own, data_dir is /var/lib/odoo/data and http_interface is 0.0.0.0. The variables were ODOO_<NAME> before; the old names are still read, with a warning, through 1.x.

Volumes and secrets

  • /var/lib/odoo/data: the persistent filestore. Mount a volume.

  • /secrets/db_password and /secrets/admin_passwd: appended to the configuration as db_password and admin_passwd when present.

  • /secrets/*.conf: appended verbatim, so a mounted file can add or override any key (the last value wins).

  • PostgreSQL is external.

The finished configuration is mode 0600.

Healthcheck

The image has a HEALTHCHECK: GET /web/health on the HTTP port (ODOO_NIX_HTTP_PORT, default 8069) must answer 200. Odoo serves that route without a database. The probe uses Bash's /dev/tcp, since the image has no curl. Docker and Podman run it every 30 seconds after a 120-second start period, and three failures in a row mark the container unhealthy.

Labels

The image carries the org.opencontainers.image.* labels: title (the image name), source (https://github.com/Avunu/odoo-nix), version (the odoo-nix version that built it), licenses (MIT), and revision, odoo-nix's commit, when your flake has odoo-nix as the odoo-nix input. They describe odoo-nix. containers.labels goes over them, so you can describe your project instead:

odoo-nix.containers.labels = {
  "org.opencontainers.image.source" = "https://github.com/acme/odoo";
  "org.opencontainers.image.revision" = self.rev or "dirty";
};

The image name

python-devops-nix names images <REGISTRY>/<name>/<role>. odoo-nix 1.0 named this one <name>-odoo, and that stays the default through 1.x. A host that pulls or runs the image by name has to change with it; otherwise it keeps running the last image it had under the old name. Opt in when you update the host:

odoo-nix.containers.roleImageNames = true; # <name>/odoo, or <REGISTRY>/<name>/odoo

Until you do, building container-odoo prints a warning that suggests the option. The new name is the default in 2.0.0.

Running as non-root

The image runs as root by default in 1.x, as it always has. Set containers.nonRoot = true and it runs as odoo, uid 1000 and gid 1000, with home /var/lib/odoo. That becomes the default in 2.0.0.

With it on, the image owns /etc/odoo, where the entrypoint writes odoo.conf, and /var/lib/odoo, so a new named volume at /var/lib/odoo/data takes that ownership. A bind mount must be writable by uid 1000 (chown -R 1000:1000 <DIR> on the host), and the files in /secrets must be readable by it.

A filestore volume that a root image wrote is owned by root, and a non-root image cannot write to it. Before you turn nonRoot on for an existing deployment, change its owner once:

docker run --rm --user 0 --entrypoint chown \
  -v <VOLUME>:/var/lib/odoo/data <IMAGE> -R 1000:1000 /var/lib/odoo/data