Skip to content

Configurable DB_NAME #535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
singatias opened this issue Dec 30, 2024 · 4 comments
Open

Configurable DB_NAME #535

singatias opened this issue Dec 30, 2024 · 4 comments

Comments

@singatias
Copy link

singatias commented Dec 30, 2024

Hello,

Why is the database name hardcoded? Even if you change it in the odoo.conf, the Docker container won't be compatible with a PostgreSQL database that doesn't have a database named 'postgres'. Multiple people have reported this issue and created PRs to address it, but none of them have been taken seriously. I'm currently creating a Helm chart for Odoo and have to jump through hoops to get it set up.

#459 #426

Obviously these PRs were neglected for so long but it would be nice if the Odoo team merge a solution once and for all to this issue.

conn = psycopg2.connect(user=args.db_user, host=args.db_host, port=args.db_port, password=args.db_password, dbname='postgres')

# 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'}}}
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"

Best Regards,
Mathias Beaulieu-Duncan

@codebykyle
Copy link

codebykyle commented Feb 9, 2025

I do not think they were neglected as much as it is being intentionally left unmerged .

As per this comment:

I understand your reasoning, but in this pull request, the additional --db_name argument to wait-for-psql.py is never passed from entrypoint.sh. When I got that far in my own experimentation, I noticed that entrypoint.sh sends the same arguments to both wait-for-psql.py and odoo, which causes non-multi-tenant setups to run Odoo out of the postgres database by default... which is less than ideal.

I'm not too sure what the issue with passing the same arguments here is. There is already a step in check_config which handles our args. If we dont specify a database, we can drop it from the arguments passed into the exec and wait command, and then just rely on arg_parser's default to wait for the postgres database.

I created a folder in my project called docker, which has the following files:

entrypoint.sh

#!/bin/bash

set -e

if [ -v PASSWORD_FILE ]; then
    PASSWORD="$(< $PASSWORD_FILE)"
fi

# 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'}}}
: ${DATABASE:=${DB_ENV_POSTGRES_DATABASE:=${POSTGRES_DATABASE}}}

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;

    if [[ "$param" == "database" && -z "$value" ]]; then
        return
    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"
check_config "database" "$DATABASE"

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

wait-for-psql.py:

#!/usr/bin/env python3
import argparse
import psycopg2
import sys
import time


if __name__ == '__main__':
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('--db_host', required=True)
    arg_parser.add_argument('--db_port', required=True)
    arg_parser.add_argument('--db_user', required=True)
    arg_parser.add_argument('--db_password', required=True)
    arg_parser.add_argument('--timeout', type=int, default=5)
    arg_parser.add_argument('--database', default='postgres', required=False)

    args = arg_parser.parse_args()

    start_time = time.time()
    while (time.time() - start_time) < args.timeout:
        try:
            conn = psycopg2.connect(
                user=args.db_user,
                host=args.db_host,
                port=args.db_port,
                password=args.db_password,
                dbname=args.database
            )

            error = ''
            break
        except psycopg2.OperationalError as e:
            error = e
        else:
            conn.close()
        time.sleep(1)

    if error:
        print("Database connection failure: %s" % error, file=sys.stderr)
        sys.exit(1)

make the files executable:

chmod +x docker/entrypoint.sh && chmod +x docker/wait-for-psql.py

In my projects Dockerfile, I mount my version of these scripts:

FROM odoo:18.0


# Override the entrypoint and wait-for-psql.py file
COPY ./docker/entrypoint.sh /
COPY ./docker/wait-for-psql.py /usr/local/bin/wait-for-psql.py

Finally, I am able to control this in my docker-compose.yml file (or .env in my case) by setting

DATABASE=mydatabase

As far as I am able to tell this maintains the original functionality, just now with the ability to specify a database.

@singatias
Copy link
Author

Thanks for sharing your solution @codebykyle.

Have you tried it because I had similar solution changing these 2 files but I still couldn't get it to work, the Odoo executable threw an error on startup saying it doesn't recognize dbname parameter. I given up on Odoo since we found another suitable solution for our business needs.

@codebykyle
Copy link

codebykyle commented Feb 9, 2025

@singatias

Yes I've tried it, works fine.

Here are some examples:

Database is specified, but does not exist (wait-for-pysql.py fails) DATABASE=this_doesnt_exist
Image

Database test exists, but does not have Odoo installed DATABASE=test:
Image

Database param is specified but is empty (default behavior of Odoo) DATABASE=, or DATABASE is not in the env:
Image

The parameter Odoo expects is --database not --dbname

See here

Database exists and Odoo is setup DATABASE=mydatabasename correctly selects that database.

@codebykyle
Copy link

codebykyle commented Feb 10, 2025

I created a pull request with the changes. This hopefully addresses the concerns of the user being locked into postgres if the database is not specified that was brought up in that earlier comment.

It would be really nice to have this functionality in the official Odoo docker container for multi-tenant setups.

Edit:

If anyone ends up here in the future, do not use the code in the comment above.

Check the PR, which now supports multiple database names. Hopefully this is merged and we can support this feature natively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants