DEV Community

Luong Xuan Trung Dung
Luong Xuan Trung Dung

Posted on

Setup Odoo 19 and Postgres 15 with Docker

I'm writing this from the satisfaction of having a local Odoo instance with its isolated running environment in my Windows machine. Having looked up near and far, through searches, with multiple LLM models and 2 days of frustration, I finally did it.

I could have just installed Odoo's official Windows installer but there is a question of management. Besides, the installed Odoo from this method is packaged with Postgres 12, which is relatively old in my opinion.

I tried to set up Odoo from scratch by its Git repository since this is recommended to developers, but installing its required Python libraries always ended up in a variety of errors. In addition, my pre-installed Postgres 18 was conflicted with this Odoo due to CTYPE and COLLATION.

Thus, after removing everything from the previous attempts, I went for Docker and here is what I did.

Prerequisites

  • Docker Desktop version 4.18 or later.
  • Docker CLI, which is packaged with Docker Desktop. Make sure to add it to your machine's PATH environment variables.

Docker 101

It's useful to know some Docker terms before we continue:

  • Image: a read-only template that contains the application code, runtime, libraries and any other dependencies.
  • Container: a lightweight, isolated, and executable package running instance of an Image.
  • Volume: a persistent data stores for containers.
  • Bind mount: a way to link a specific file or directory on the host machine's filesystem directly into a Docker container.
  • Compose file: a simple YAML text file to manage the building of Docker Containers stack.

An example of a docker-compose.yaml:

services:
  web:
    build: .
    ports:
      - "8000:5000"
    develop:
      watch:
        - action: sync
          path: .
          target: /code
  redis:
    image: "redis:alpine"
Enter fullscreen mode Exit fullscreen mode

The Docker Compose YAML

Like the example above, I declared the building of 2 containers, one for Odoo (version 19) and one for Postgres (version 15). Afterward, the containers are meant to run in the default ports (8069 for Odoo and 5432 for Postgres).

services:
  web:
    image: odoo:19
    depends_on:
      - db
    ports:
      - "8069:8069"
  db:
    image: postgres:15
Enter fullscreen mode Exit fullscreen mode

The thing is when you delete a container, any data written to its writable layer is also deleted. Docker's volumes are meant for this, for storing data outside of the container's file system, on the host machine as a backup.

Now, with that in mind, I declared the volumes for the containers:

services:
  web:
    image: odoo:19
    depends_on:
      - db
    ports:
      - "8069:8069"
    volumes:
      - odoo: /var/lib/odoo
  db:
    image: postgres:15
    volumes:
      - postgres: /var/lib/postgresql/data

volumes:
  odoo:
  postgres:
Enter fullscreen mode Exit fullscreen mode

As you might notice, in order to use Odoo with Postgres, we also need to declare environment variables. These include a database, a Postgres superadmin's username and password for Odoo's content management.

services:
  ...
  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=postgres # Example DB name, don't use in production
      - POSTGRES_USER=odoo # Example username, don't use in production
      - POSTGRES_PASSWORD=oodo # Example password, don't use in production
    volumes:
      - postgres: /var/lib/postgresql/data
...
Enter fullscreen mode Exit fullscreen mode

This superadmin account and database is automatically created in the built Postgres container. For Odoo to actually use it, remember to confirm them once more in the browser.

How it should look in your browser when the containers are running properly. Image from Cybrosys
Final setup in browser, Odoo 17 in Ubuntu 20

The Odoo Development

Odoo development involves creating custom modules. Thus, the YAML above needs to be updated with bind mounts so that your modules can be copied (or mounted) into the containers.

services:
  web:
    image: odoo:19 # Choose your desired Odoo version
    depends_on:
      - db
    ports:
      - "8069:8069" # Maps host port 8069 to container port 8069
    volumes:
      - odoo: /var/lib/odoo
      - ./config: /etc/odoo # For Odoo configuration file
      - ./addons: /mnt/extra-addons # For custom modules
Enter fullscreen mode Exit fullscreen mode

This means, in the directory of the Docker Compose YAML file, there should be 2 folders, config (for custom Odoo config) and addons (for your custom modules).

Now, as you want to deploy your modules to the local Odoo application, the easiest method is to remove the Odoo container (just the container, not its volume data), then restart it to trigger the bind mount. This is irritating but I found no other way.

Here are the Docker commands that I used, which web is the declared Odoo container in the YAML file:

docker compose down web: remove the container
docker compose up -d --no-deps web: restart the container

or this combine command: docker compose up -d --no-deps --force-recreate web

Final thought

After the setup was done, I happily went on through the Odoo tutorial to learn about its server framework just to face another source of frustration since I could not set up the container's Python environment in my code editor and I could not quite understand that document. Anyways, maybe at some point, I'll be writing about this.

Nonetheless, I managed to finish that as well with the result is a functioning custom module that also serves as a demo for this article.

I hope you enjoy this tutorial. Let me know if you have any questions by: Github, LinkedIn or Email.

Thank you for your time.

Top comments (0)