Search code examples
postgresqldockerdocker-composeodoodefault

How to customise docker-compose containing the odoo app and postgresql with non default database name, user name and password?


I have an application (odoo, but my question may be for any app, I don't know) and a database with database default name, user and password. All is launched with docker-compose. With these default values, it works great (I have copy/pasted only what is relevant):

  db:
    image: postgres:14
    user: root
    environment:
      - POSTGRES_PASSWORD=odoo
      - POSTGRES_USER=odoo
      - POSTGRES_DB=postgres
  volumes:
      - ./postgresql:/var/lib/postgresql/data
  web:
    image: odoo:15
    user: root
    depends_on:
      - db
    environment:
      - HOST=db
      - USER=odoo
      - PASSWORD=odoo
  volumes:
      - ./etc:/etc/odoo
      - ./odoo-data:/var/lib/odoo

There is also a config file etc/odoo.conf which needs to be updated and I did (here the default values):

db_name = postgres
db_user = odoo
db_password = odoo

If for example I set the password to 123, the user name to my and the database name to mydb, remove the containers and suppress ./postgresql to restart clean, I get the following error from the database host:

odoo-db-1   | 2022-09-18 15:08:17.420 UTC [908] FATAL:  password authentication failed for user "my"
odoo-db-1   | 2022-09-18 15:08:17.420 UTC [908] DETAIL:  Role "my" does not exist.

Of course, I have updated both the docker-compose and odoo.conf files with my values.

What could I miss? My investigations at this point have failed.

Here is my docker-compose file:

version: '2'
services:
  db:
    image: postgres:14
    user: root
    environment:
      - POSTGRES_DB_FILE=/run/secrets/postgresql_db
      - POSTGRES_USER_FILE=/run/secrets/postgresql_user
      - POSTGRES_PASSWORD_FILE=/run/secrets/postgresql_password
    restart: always             # run as a service
    volumes:
        - ./postgresql:/var/lib/postgresql/data
    secrets:
      - postgresql_user
      - postgresql_password
      - postgresql_db

  web:
    image: odoo:15
    user: root
    depends_on:
      - db
    ports:
      - "10013:8069"
      - "20013:8072" # live chat
    tty: true
    command: --
    environment:
      - HOST=db
      - USER_FILE=/run/secrets/postgresql_user
      - PASSWORD_FILE=/run/secrets/postgresql_password
    volumes:
      - /etc/timezone:/etc/timezone:fr
      - /etc/localtime:/etc/localtime:fr
      - ./addons:/mnt/extra-addons
      - ./etc:/etc/odoo
      - ./odoo-data:/var/lib/odoo
    secrets:
      - postgresql_user
      - postgresql_password
    restart: always             # run as a service

secrets:
  postgresql_db:
    file: odoo_pg_db
  postgresql_user:
    file: odoo_pg_user
  postgresql_password:
    file: odoo_pg_pass

Here is my etc/odoo.conf:

[options]
addons_path = /mnt/extra-addons
data_dir = /etc/odoo
admin_passwd = "my_own_admin_password"
logfile = /etc/odoo/odoo-server.log
db_name = my_db
db_user = myself
db_password = "my_db_user_password"
dev_mode = reload

The entrypoint.sh:

#!/bin/bash

set -e

# set the postgres database host, port, user and password according to the environment
# and pass them as arguments to the odoo process if not present in the config file
: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}}
: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}}
: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}}
: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}}

# install python packages
pip3 install pip --upgrade
pip3 install -r /etc/odoo/requirements.txt

# sed -i 's|raise werkzeug.exceptions.BadRequest(msg)|self.jsonrequest = {}|g' /usr/lib/python3/dist-packages/odoo/http.py

DB_ARGS=()
function check_config() {
    param="$1"
    value="$2"
    if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then       
        value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g')
    fi;
    DB_ARGS+=("--${param}")
    DB_ARGS+=("${value}")
}
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"

case "$1" in
    -- | odoo)
        shift
        if [[ "$1" == "scaffold" ]] ; then
            exec odoo "$@"
        else
            wait-for-psql.py ${DB_ARGS[@]} --timeout=30
            exec odoo "$@" "${DB_ARGS[@]}"
        fi
        ;;
    -*)
        wait-for-psql.py ${DB_ARGS[@]} --timeout=30
        exec odoo "$@" "${DB_ARGS[@]}"
        ;;
    *)
        exec "$@"
esac

exit 1

And:

cat odoo_pg_db
my_db
cat odoo_pg_user
myself
cat odoo_pg_pass
my_db_user_password

And my project folder tree:

.
├── addons
│   └── readme.md
├── docker-compose.yml
├── entrypoint.sh
├── etc
│   ├── addons
│   │   └── 15.0
│   ├── odoo.conf
│   ├── odoo.conf.meld
│   ├── odoo-server.log
│   ├── requirements.txt
│   └── sessions
├── odoo-data
├── odoo_pg_db
├── odoo_pg_pass
├── odoo_pg_user
├── postgresql [error opening dir]
├── README.md
├── run.sh
└── screenshots
    ├── odoo-13-apps-screenshot.png
    ├── odoo-13-sales-form.png
    ├── odoo-13-sales-screen.png
    └── odoo-13-welcome-screenshot.png

The odoo:15 dockerfile does not include hard written database name nor user regarding the database, only an app user set to odoo, but this is for the web app. It makes use of a config file with the default database name user and password like depicted above, but I provide the modified one with my values. The docker files makes use of ENV to refer to it: ENV ODOO_RC /etc/odoo/odoo.conf. Then it runs an entrypoint containing:

DB_ARGS=()
function check_config() {
    param="$1"
    value="$2"
    if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then       
        value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g')
    fi;
    DB_ARGS+=("--${param}")
    DB_ARGS+=("${value}")
}
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"

With these check_config, it gets my values from the config file.

The postgres:14 dockerfile contains only the superuser name postgres set with a useradd.

Note: of course, there is more to be done after this like replace root user, use Docker secrets, but that's another topic.


Solution

  • The postgresql folder contents were not suppressed with sudo rm -fr postgresql/* while the containers were deleted, since created with the odoo user. I have to do sudo chmod -R 777 postgresql before.

    Now I can see in the docker console that the environment variables are correctly set. Other problems now, but this one is solved.