# odoo init helper This folder contains helper scripts used to initialize the Odoo container on first boot. The `odoo-init` one-shot runs a small wrapper (`init-wrapper.sh`) that fixes filesystem ownerships for the Odoo named volumes and then runs the actual initialization script (`init-odoo.sh`). Why the wrapper runs as root --------------------------- - The wrapper must run as `root` so it can chown the Docker named volumes after they are created. Named volumes are created with root ownership by Docker on many hosts, which causes Odoo (a non-root process inside the container) to fail when writing the filestore. - The wrapper drops to the `odoo` user before executing the init script so the actual Odoo commands run with the correct, unprivileged uid/gid. What it does ----------- - Creates any missing directories the image expects (filestore, web, addons, logs, config) and sets their ownership to the numeric `odoo` UID:GID. - Writes a marker file `/var/lib/odoo/.odoo-init-done` to indicate the one-shot ran successfully. - Checks `/init-odoo.sh` is present and readable. If the script is missing or unreadable the wrapper exits with status `2` and logs an error. Troubleshooting --------------- - If you see PermissionError writing `/var/lib/odoo/filestore/*`: - Ensure the named volumes are not mounted on the host with root-only permissions. The wrapper attempts to chown them on container start; if that fails check the host mount permissions. - You can run the wrapper manually in a container to inspect output: ```sh docker compose run --rm --entrypoint /bin/sh odoo-init -c /init-wrapper.sh ``` - If the wrapper logs `ERROR: /init-odoo.sh missing or not readable`: - Verify `./scripts/odoo/init-odoo.sh` exists in the repo and that it is mounted into the container in `odoo-init.yml` at `/init-odoo.sh`. Notes ----- - `odoo-init.yml` intentionally runs the `odoo-init` service as `root` so the wrapper can perform chown. The wrapper drops privileges before running the init logic. - The marker file is a simple heuristic other tooling (or manual checks) can use to detect that initialization already ran. Removing the named volumes and re-creating them will require re-running the wrapper (it runs on every start of the `odoo-init` one-shot service).