How To Install Odoo on Ubuntu 20.04 with Docker

Published on March 11, 2022
How To Install Odoo on Ubuntu 20.04 with Docker


Odoo is an open-source enterprise resource planning (ERP) tool written in Python. It supports a number of plugins for different kinds of business needs like accounting, payroll, inventory management, and more.

In this tutorial you will install Odoo and a PostgreSQL database using Docker Compose, then install Nginx to act as a reverse proxy for your Odoo site. Finally, you will enable secure HTTPS connections by using Certbot to download and configure a TLS certificate from the Let’s Encrypt Certificate Authority.


To complete this tutorial, you will need:

Note: You can skip these prerequisites if you are using DigitalOcean’s One-Click Docker Image. This image is pre-configured with Docker, Docker Compose, and UFW.

Launch a new Docker image in the region of your choice, then log in as the root user and proceed with the tutorial.

Finally, to enable TLS you’ll need a domain name pointed at your server’s public IP address. This should be something like example.com or odoo.example.com. If you are using DigitalOcean, please see our DNS Quickstart for information on creating domain resources in your control panel.

Once you have all the prerequisites in place, proceed to Step 1, where you’ll install the docker-compose package.

Step 1 — Installing Docker Compose

To install the docker-compose command line tool, refresh your package list, then install the package using apt:

  1. sudo apt update
  2. sudo apt install docker-compose

Note: You can also install a more recent Docker Compose package than the one that is included with Ubuntu 20.04. To do so, follow Step 1 of How To Install and Use Docker Compose on Ubuntu 20.04.

If you opt to use this version of Docker Compose, you will need to substitute docker compose as the command in place of docker-compose.

You can confirm that the package is installed by running the following command:

  1. docker-compose –version

You should receive output like the following:

docker-compose version 1.25.0, build unknown docker-py version: 4.1.0 CPython version: 3.8.10

Once you have confirmed that Docker Compose is installed on your server, you will configure and launch Odoo and PostgreSQL using Docker Compose in the next step of this tutorial.

Step 2 — Running Odoo and PostgreSQL with Docker Compose

To get started creating your Odoo and PostgreSQL containers, create a directory called odoo in your home directory to store the files that you will create in this tutorial. You’ll use this directory to store all the files that you need to run Odoo.

Run the following commands to create the directory and then cd into it:

  1. mkdir ~/odoo
  2. cd ~/odoo

Now open a new blank YAML file called docker-compose.yml using nano or your preferred editor:

  1. nano docker-compose.yml

You will use this file with the docker-compose command to start your Odoo and PostgreSQL containers and link them together. Add the following lines to the file:

version: '3'
    image: odoo:15.0
    env_file: .env
      - postgres
      - ""
      - data:/var/lib/odoo
    image: postgres:13
    env_file: .env
      - db:/var/lib/postgresql/data/pgdata


The file defines two services. The first is called odoo, which runs the Odoo application. The second is called postgres, which is the PostgreSQL database container. Both services reference named volumes that they use to store data outside of the running container instances. Finally, the odoo service exposes port 8069 on your server to the Odoo container that is running on the same port 8069.

Save and exit the file when you are done editing it. If you are using nano, press CTRL+O then RETURN to save, then CTRL+X to exit.

The Odoo and PostgreSQL containers use environment variables to configure themselves. The docker-compose.yml file specifies the env_file directive for both services. That directive then includes the referenced file that contains the variables that each service needs to run.

This approach is generally recommended instead of adding environment variables to the docker-compose.yml file directly, sinceit is a good practice to keep passwords out of your docker-compose.yml file. This approach is especially applicable if you’ll be committing your files to a Git repository or another source control system.

Open a new .env file with nano:

  1. nano .env

Add the following lines into the file, substituting in a POSTGRES_USER and POSTGRES_PASSWORD of your choice in place of the highlighted values:

# postgresql environment variables

# odoo environment variables

To generate a password for Odoo and PostgreSQL, use the openssl command, which should be available on most Linux systems. Run the following command on your server to generate a random set of bytes and print a base64 encoded version that you can use as a password:

  1. openssl rand -base64 30

Paste the resulting string into your .env file in place of the a_strong_password_for_user placeholder passwords.

When you’re done editing your .env file, save and exit your text editor.

You’re now ready to start the odoo and postgres containers with the docker-compose command:

  1. docker-compose up -d

The up sub-command tells docker-compose to start the containers and the associated volumes and networks that are defined in the docker-compose.yml file. The -d flag (which stands for “daemonize”) tells docker-compose to run the containers in the background so the command doesn’t take over your terminal. docker-compose will print some brief output as it downloads the required Docker images and then starts the containers:

Creating network "odoo_default" with the default driver Creating volume "odoo_odoo_data" with default driver Creating volume "odoo_postgres_data" with default driver Pulling odoo (odoo:14.0)... 15.0: Pulling from library/odoo . . .

If you would like to stop your Odoo and PostgreSQL containers at any time, run the following command in your ~/odoo directory:

  1. docker-compose stop

The containers will be stopped. The configuration and data in their volumes will be preserved so that you can start the containers again with the docker-compose up -d command.

When that’s done, Odoo should be running. You can test that a webserver is running at by fetching the homepage using the curl command:

  1. curl --head http://localhost:8069

This will print out only the HTTP headers from the response:

HTTP/1.0 303 SEE OTHER Content-Type: text/html; charset=utf-8 Content-Length: 215 Location: http://localhost:8069/web Set-Cookie: session_id=142fa5c02742d0f5f16c73bc14ec8144b8230f8a; Expires=Mon, 06-Jun-2022 20:45:34 GMT; Max-Age=7776000; HttpOnly; Path=/ Server: Werkzeug/0.14.1 Python/3.7.3 Date: Tue, 08 Mar 2022 20:45:34 GMT

The 303 SEE OTHER response means the Odoo server is up and running, but that you should visit another page to complete the installation. The highlighted http://localhost:8069/web Location header indicates where to visit the Odoo installer page in your browser.

Next we’ll set up Nginx to proxy public traffic to the Odoo container.

Step 3 — Installing and Configuring Nginx

Putting a web server such as Nginx in front of your Odoo server can improve performance by offloading caching, compression, and static file serving to a more efficient process. We’re going to install Nginx and configure it to reverse proxy requests to Odoo, meaning it will take care of handing requests from your users to Odoo and back again. Using a non-containerized Nginx process will also make it easier to add Let’s Encrypt TLS certificates in the next step.

First, refresh your package list, then install Nginx using apt:

  1. sudo apt update
  2. sudo apt install nginx

Allow public traffic to ports 80 and 443 (HTTP and HTTPS) using the Nginx Full UFW application profile:

  1. sudo ufw allow "Nginx Full"
Rule added Rule added (v6)

Next, open up a new Nginx configuration file in the /etc/nginx/sites-available directory. We’ll call ours odoo.conf but you could use a different name:

  1. sudo nano /etc/nginx/sites-available/odoo.conf

Paste the following into the new configuration file, being sure to replace your_domain_here with the domain that you’ve configured to point to your Odoo server. This should be something like odoo.example.com, for instance:

server {
    listen       80;
    listen       [::]:80;
    server_name  your_domain_here;

    access_log  /var/log/nginx/odoo.access.log;
    error_log   /var/log/nginx/odoo.error.log;

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Proto https;
      proxy_pass http://localhost:8069;

This configuration is HTTP-only for now, as we’ll let Certbot take care of configuring TLS in the next step. The rest of the configuration file sets up logging locations and then passes all traffic, as well as some important proxy headers, along to http://localhost:8069, the Odoo container that we started up in the previous step.

Save and close the file, then enable the configuration by linking it into /etc/nginx/sites-enabled/:

  1. sudo ln -s /etc/nginx/sites-available/odoo.conf /etc/nginx/sites-enabled/

Use nginx -t to verify that the configuration file syntax is correct:

  1. sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

And finally, reload the nginx service with the new configuration:

  1. sudo systemctl reload nginx.service

Your Odoo site should now be available on plain HTTP. Load http://your_domain_here (you may have to click through a security warning) and it will look like this:

Screenshot of Odoo's "Database Setup" page, with a form for inputting database connection details and a random password for the PostgreSQL database

Now that you have your site up and running over HTTP, it’s time to secure the connection with Certbot and Let’s Encrypt certificates. You should do this before going through Odoo’s web-based setup procedure.

Step 4 — Installing Certbot and Setting Up TLS Certificates

Thanks to Certbot and the Let’s Encrypt free certificate authority, adding TLS encryption to your Odoo app will take only two commands.

First, install Certbot and its Nginx plugin:

  1. sudo apt install certbot python3-certbot-nginx

Next, run certbot in --nginx mode, and specify the same domain that you used in the Nginx server_name configuration directive:

  1. sudo certbot --nginx -d your_domain_here

You’ll be prompted to agree to the Let’s Encrypt terms of service, and to enter an email address.

Afterwards, you’ll be asked if you want to redirect all HTTP traffic to HTTPS. It’s up to you, but this is generally recommended and safe to do.

After that, Let’s Encrypt will confirm your request and Certbot will download your certificate:

Congratulations! You have successfully enabled https://odoo.example.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=odoo.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/odoo.example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/odoo.example.com/privkey.pem Your cert will expire on 2022-05-09. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

Certbot will automatically reload Nginx with the new configuration and certificates. Reload your site in your browser and it should switch you over to HTTPS automatically if you chose the redirect option.

Your site is now secure and it’s safe to continue with the web-based setup steps.

Step 5 — Setting Up Odoo

Back in your web browser, reload the page. You should now have Odoo’s database configuration page open via a secure https:// connection. Now you can enter usernames and passwords safely to complete the installation process.

The information that you fill in on this page will tell the Odoo application how to create its PostgreSQL database and details about the default administrative user.

Fill out the following fields:

  • Database Name: odoo
  • Email: your email address
  • Password: a strong and unique password for your administrator login
  • Demo data: ensure that this option is checked if this is the first time that you are installing odoo

The defaults are fine for the remaining fields. Be sure to record the email and password values that you choose since you will use them to login to Odoo in the future.

Now click the Create database button at the bottom left of the page. It may take a minute or two for Odoo to create its database tables. When the process is complete you will be redirected to the Odoo Apps administrative page.

Screenshot of Odoo's Apps dashboard with a list of available modules that can be enabled

From here you can choose which Odoo modules you would like to install and use for your ERP needs. If you would like to test an app, click the Install button on the Sales tile. Odoo will install the module and then redirect you to your personal Discuss app page.

Click the segmented square icon at the top left of your screen and then select the Sales link in the list of dropdown options.

Screenshot of Odoo's Sales app dashboard with customization options

You will be on a page that will guide you through customizing data, quotes, orders, and a list of example sales that you can experiment with.


In this tutorial, you launched the Odoo ERP app and a PostgreSQL database using Docker Compose, then set up an Nginx reverse proxy and secured it using Let’s Encrypt TLS certificates.

You’re now ready to start building your ERP website using the supplied modules. For more information about using Odoo please see the official Odoo documentation.

If you would like to write your own custom Odoo modules or customize existing modules, the Developer documentation is a good place to start.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

After many attempts to get Odoo installed using various tutorails this is the first one that actually worked. I have Odoo up and running. There is one issue I find that needs to be addressed.

Odoo itself still runs thinking the website is localhost:8069. When it creates a sitemap it does not use the correct domain name. I believe these lines in the odoo.conf for nginx are supposed to handle this but they don’t:

proxy_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Proto https;

In my research on this problem I have learned there is a flag that needs to be set in Odoo to let it know it is behind a proxy that needs to be in the Odoo Config. It is:

proxy_mode = 1 (I have also seen some people say this should be proxy_mode = TRUE)

Problem is I am not sure how to pass that variable to the docker image.

I have tried to put it in the .env file but in that file it does not allow whitespace so I shorten it to proxy_mode=1 but that doesnt work either. I went inside the docker image - there is an odoo.conf file in the /etc directory, I tried adding it there as well. No effect.

This problem also rears its head if you go to enable the Paypal payments module in your website. At the end of a paypal transaction, paypal returns the buyer to lcoalhost:8069 address.

Hoping someone has experienced this and found a solution ?? Help!

Todo bien pero al momento de instalar cerbot y recargar la pagina me sale el error 502, asi me quedo el archivo de nginx al instalar el certificado

server {

    server_name  domain.com;

    access_log  /var/log/nginx/odoo.access.log;

    error_log   /var/log/nginx/odoo.error.log;

    location / {

      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_set_header X-Real-IP $remote_addr;

      proxy_set_header X-Forwarded-Host $host;

      proxy_set_header X-Forwarded-Proto https;

      proxy_pass http://localhost:8069;


    listen [::]:443 ssl ipv6only=on; # managed by Certbot

    listen 443 ssl; # managed by Certbot

    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # managed by Certbot

    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; # managed by Certbot

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


server {

    if ($host = domain.com) {

        return 301 https://$host$request_uri;

    } # managed by Certbot

    listen       80;

    listen       [::]:80;

    server_name  domain.com;

    return 404; # managed by Certbot


si pudieran ayudarme de favor

To add a custom in odoo 16 use:

Identify the container name or ID:

docker ps

Copy custom to container:

docker cp custom_name docker_ContainerName_or_Id:/usr/lib/python3/dist-packages/odoo/addons

If you want to add custom or third party modules you must add the nex instructions to the above procedure:

  1. Create two extra folders under ./odoo
$ mkdir ./odoo/addons
$ mkdir ./odoo/config
  1. Add two extra lines to the docker-compose.yml so the volumes section under odoo is like:
- data:/var/lib/odoo
- ./config:/etc/odoo
- ./addons:/mnt/extra-addons
  1. Add a file named odoo.conf under the ./odoo/config folder that have the next lines
addons_path = /mnt/extra-addons
data_dir = /var/lib/odoo
  1. Add your custom and third party modules under the ./odoo/addons.

That’s all. But you must consider that only with that, the modules under ./odoo/addons can’t have requeriments of extra python libraries (for that you must alter the image creation).

Can you please modify the demo to enclude how to add custom addons folder and where is the conf file of the odoo docker?

hello, does it work for version 14? If I wanted to add third party modules, what would be the path to upload the files?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel