skip to content
Sean Thawe
Table of Contents

Setting up a full-featured ERP system like Odoo can be a complex task, but Docker simplifies the process immensely. I needed a quick way to spin up a new Odoo 18 instance for testing, and I wanted to make sure my data would be saved even after the containers were stopped.

This guide provides the exact commands I used to get a persistent Odoo environment running in just a few minutes.

This guide was tested on a machine running Ubuntu 24.04.3 LTS. Since Docker is a cross-platform tool, these commands should work on any operating system that supports Docker.

What You’ll Achieve in This Guide

  • How to run a PostgreSQL database in a Docker container with a persistent volume.
  • How to link an Odoo container to the database container.
  • How to ensure your Odoo data is also persistent.
  • How to access your new Odoo instance from your browser.

Part 1: The Core Commands

The setup is a two-step process: first, we start the database container, and then we start the Odoo application container, linking them together.

1.1. Start the PostgreSQL Database

Odoo requires a PostgreSQL database to store its data. This command creates a new Docker container named odoo-db for the database.

Command:

Terminal window
docker run -d --name odoo-db \
-e POSTGRES_USER=odoo \
-e POSTGRES_PASSWORD=odoo \
-e POSTGRES_DB=postgres \
-v pg-data:/var/lib/postgresql/data \
postgres:16

Explanation:

  • docker run -d --name odoo-db: Runs a container in detached mode (-d) and names it odoo-db.
  • -e POSTGRES_...: Sets the environment variables for the PostgreSQL user, password, and database name. It’s important that the Odoo container uses these same credentials.
  • -v pg-data:/var/lib/postgresql/data: This is the key to persistence. It creates a Docker volume named pg-data and mounts it to the directory where PostgreSQL stores its data inside the container. Your database files will be safe here.
  • postgres:16: Specifies the official PostgreSQL image, version 16.

1.2. Start the Odoo Application

With the database running, we can now start the Odoo container.

Command:

Terminal window
docker run -d --name odoo \
-p 8069:8069 \
--link odoo-db:db \
-v odoo-data:/var/lib/odoo \
odoo:18.0

Explanation:

  • docker run -d --name odoo: Runs a container in detached mode and names it odoo.
  • -p 8069:8069: Maps port 8069 on your host machine to port 8069 in the container. This is how you’ll access the Odoo web interface.
  • --link odoo-db:db: This connects the Odoo container to the odoo-db container. Inside the Odoo container, the database will be accessible at the hostname db.
  • -v odoo-data:/var/lib/odoo: Creates another Docker volume, odoo-data, to store Odoo’s application data, such as custom modules and session files.
  • odoo:18.0: Specifies the official Odoo image, version 18.0.

Part 2: Accessing Your Odoo Instance

Once both containers are running, you can access your new Odoo instance by opening a web browser and navigating to:

http://localhost:8069

You should be greeted by the Odoo setup screen, ready for you to create your first database and start exploring.

Part 3: Managing Your Containers

Here are a few useful commands to manage your new Odoo environment:

Terminal window
# View the logs of your Odoo container
docker logs -f odoo
# View the logs of your database container
docker logs -f odoo-db
# Stop both containers
docker stop odoo odoo-db
# Restart them later
docker start odoo odoo-db

Because we used Docker volumes, all your data will be right where you left it when you restart the containers. This setup provides a reliable and isolated environment for any Odoo project.


Part 4: An Advanced Method with docker-compose

For those who need a more flexible and production-like setup, I’ve created a separate GitHub repository that uses docker-compose to manage the Odoo environment. This method is ideal for development, as it simplifies the management of multi-container applications and makes it easy to handle custom addons.

You can find the repository here: seanthw/odoo-19-dockerized

What This docker-compose Setup Offers

  • Simplified Management: Start and stop all required services (Odoo and PostgreSQL) with a single command.
  • Easy Configuration: All settings are managed in a .env file.
  • Custom Addons: Includes a test-addons directory to easily mount your own custom modules.
  • Scalability: docker-compose files are easy to extend for more complex setups (e.g., adding a reverse proxy).

4.1. Getting Started

First, clone the repository to your local machine:

Terminal window
git clone https://github.com/seanthw/odoo-19-dockerized.git
cd odoo-19-dockerized

4.2. Configuration

The repository comes with an example environment file, .env.example. Create a copy of this file and name it .env:

Terminal window
cp .env.example .env

You can edit the .env file to change the Odoo or PostgreSQL versions, set different ports, or update credentials. The default values are suitable for a local development environment.

4.3. Running the Environment

With docker-compose, starting the entire stack is as simple as running one command from the root of the project directory:

Terminal window
docker compose up -d

This command will pull the required images, create the persistent volumes, and start the Odoo and PostgreSQL containers in the background.

4.4. Accessing and Managing the Environment

Once the containers are running, you can access your Odoo instance at http://localhost:8069 (or whichever port you configured in the .env file).

Here are the essential commands for managing your docker-compose environment:

Terminal window
# View the logs for both services
docker compose logs -f
# Stop the services
docker compose stop
# Restart the services
docker compose start
# Bring down the entire stack and remove the containers
docker compose down

This docker-compose approach provides a more robust and maintainable way to run Odoo, especially when you start developing custom modules or need to replicate a production environment.


Further Reading

If you found this guide helpful, you might be interested in these other posts: