In this post, I will guide you through the 6 steps to install Odoo 12 running with Python 3.7 and 3.8 on Ubuntu 22.04 Server with PostgreSQL 10 and PostgreSQL 12.
Please note that if you are seeking for installing other Odoo versions, you could read other posts of mine for that:
- How to Install Odoo 8 on Ubuntu 22.04
- How to install Odoo 9 on Ubuntu 22.04
- How to install Odoo 10 on Ubuntu 22.04
- How to install Odoo 11 on Ubuntu 22.04
- How to install Odoo 13 on Ubuntu 22.04
- How to install Odoo 14 on Ubuntu 22.04
- How to install Odoo 15 on Ubuntu 22.04
- How to Install Odoo 16 on Ubuntu 22.04
Of, if you are an Odoo developer, you may interest in How to setup Odoo development environment on Ubuntu 22.04.
Executive Summary
In this post, I will guide you through 6 steps to install Odoo 12 on Ubuntu 22.04 server to achieve the following:
- Odoo 12 running with Python 3.7:
- Running Unix User: odoo12_37
- PostgreSQL version: 10
- HTTP port: 8089, so that users can access it with a web browser with an address like http://your_ip:8089
- Odoo 12 running with Python 3.8
- Running Unix User: odoo12_38
- PostgreSQL version: 12
- HTTP port: 8099, so that users can access it with a web browser with an address like http://your_ip:8099
- Each of the 2 above (aka each instance) will run as a service with autostart.
- The instances will also be isolated in a dedicated environment
- They will also be set with a secured master password to protect their database. Users having master password will be able to create/delete/backup/restore databases
Step1 – Create Odoo Running Users and Group
For security, we should run Odoo instances under separate Linux user accounts that have the following specifications:
- For Odoo 12 running Python 3.7:
- Account Name: odoo12_37
- Home Directory:
/home/odoo12_37
- For Odoo 12 running Python 3.8:
- Account Name: odoo12_38
- Home Directory:
/home/odoo12_38
- The user accounts will not be able to login for security purpose. They should also be system accounts under which daemons and other processes could run;
- The user accounts will belong to a group that has access to Odoo 12 source code (i.e. odoo);
Create Unix group
Run the following command to create the group odoo:
sudo addgroup odoo
Create User odoo12_37
Run the following command to create the user account odoo12_37 and add it to the group odoo:
sudo adduser odoo12_37 --system \ --home=/home/odoo12_37 --disabled-login \ --disabled-password --ingroup odoo
Create User odoo12_38
Run the following command to create the user account odoo12_38 and add it to the group odoo:
sudo adduser odoo12_38 --system \ --home=/home/odoo12_38 --disabled-login \ --disabled-password --ingroup odoo
Step 2 – Install PostgreSQL for Odoo 12
I have not fully tested Odoo 12 with the latest version of PostgreSQL which is PostgreSQL 14 that comes fresh with Ubuntu 22.04 but I believe it should work. However, as discussed in the section Executive Summary, we are going to install PostgreSQL 10 and 12. If you want other versions of PostgreSQL, you can follow another post of mine to install multiple PostgreSQL versions on Ubuntu 22.04 in case you want another version of PostgreSQL.
Adding official PostgreSQL PPA
As Ubuntu 22.04 has no idea about the PostgreSQL versions other than 14, we need to add the official PPA from PostgreSQL author
# Create the file repository configuration: sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' # Import the repository signing key: wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg # Update the package lists: sudo apt-get update
As usual, we should update the system before installing anything:
sudo apt dist-upgrade
Install PostgreSQL 10 and 12
sudo apt install postgresql-10 sudo apt install postgresql-12
After the installation is completed, and I assume that you did not have any postgreSQL installed before, the listening port of the newly installed PostgreSQL clusters will be:
- PostgreSQL 10: 5432
- PostgreSQL 12: 5433
In case you have other versions of PostgreSQL running and you want to re-arrange the ports assignment, please follow the tutorial on changing PostgreSQL ports.
Create Database Roles
In this section, we will create database SQL roles having the same name as the unix user accounts’ so that Odoo will be able to authenticate PosgreSQL using ident method (without using password):
- Odoo 12 running Python 3.7 will connect PostgreSQL 10 on port 5432 using the role odoo12_37,
- Odoo 12 running Python 3.8 will connect PostgreSQL 12 on port 5433 using the role odoo12_38
Create Role odoo12_37
The command below will create a role named odoo12_37 in PostgreSQL 10 listening on port 5432:
sudo -u postgres createuser odoo12_37 --interactive -p 5432
When asked during the interative session, please input as follow:

Create Role odoo12_38
The command below will create a role named odoo12_38 in PostgreSQL 12 listening on port 5433:
sudo -u postgres createuser odoo12_38 --interactive -p 5433
When being asked during the interactive session, please input as follow:

Step 3 – Download Odoo 12 source code from GitHub
In this section, we will download the Odoo 12 source code from GitHub and implement security policy for read access for the users in the group odoo.
To download the source code of Odoo 12 from GitHub, just run the command below to clone it using git over HTTP:
git clone -b 12.0 https://github.com/odoo/odoo.git /opt/odoo/odoo12
Or, you may clone the repository from GitHub over SSH for better performance and security using the following command:
git clone -b 12.0 git@github.com:odoo/odoo.git /opt/odoo/odoo12
Depending on your internet connection speed, the process may take a few minutes or more. Please be patient or open another session to work for the next steps of installing Python in parallel.
After the process is completed, you will find the Odoo 12 source code in the directory /opt/odoo/odoo12/
.
Now, secure your source code to allow only the users of the group odoo to read it by changing group permission to odoo.
sudo chown -hR root:odoo /opt/odoo/odoo12
Step 4 – Install Python 3.7 and 3.8
As discussed, Odoo 12 supports Python 3.7 and 3.8 officially. However, the Python version comes fresh with Ubuntu 22.04 is 3.10 so we need to install Python 3.7 and 3.8 ourselves. You can follow the instructions on how to install multiple versions of Python to complete this step. In summary, you could:
Add Deadsnakes PPA
sudo add-apt-repository ppa:deadsnakes/ppa
Install Python 3.7 and its Virtual Environment tool
As we need to create an isolated Python environment for Odoo 12 to run to avoid to break existing things, we need to install Python Virtual Environment Tool also. Here is the command to install both Python 3.7 and its virtual environment tool:
sudo apt install python3.7 python3.7-venv
Now, run the command below to verify if Python 3.7 is properly installed:
python3.7 -V
You should see output as below:

Install Python 3.8 and its Virtual Environment tool
sudo apt install python3.8 python3.8-venv
Now, issue the command below to verify if Python 3.8 is properly installed:
python3.8 -V
You should see output as below

Step 5 – Install Odoo 12
Prerequisites
Install Ubuntu software and packages that are required to run Odoo 12 later:
sudo apt install python3.7-dev python3.8-dev \ build-essential libsass-dev libjpeg-dev \ libjpeg8-dev libldap-dev libldap2-dev \ libpq-dev libsasl2-dev libxslt1-dev zlib1g-dev
Install wkhtmltopdf
Odoo generates PDF from HTML, that’s why we need the wkhtmltopdf.
Download wkhtmltopdf:
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb
Install wkhtmltopdf:
sudo dpkg -i wkhtmltox_0.12.6.1-2.jammy_amd64.deb # force install dependencies sudo apt -f install -y
Install Odoo 12 with Python 3.7 and PostgreSQL 10
Create Odoo 12 Python 3.7 Virtual Environment
Create parent folders for Odoo 12 with Python 3.7 virtual environment:
sudo mkdir -p /python-venv/3.7/odoo12
Secure the virtual environment:
sudo chown -hR odoo12_37:odoo /python-venv/3.7/odoo12
Switch the current user account to odoo12_37’s bash:
sudo su - odoo12_37 -s /bin/bash
Create virtual environment:
python3.7 -m venv /python-venv/3.7/odoo12
Install required Python libraries for Odoo 12
Activate the virtual environment we’ve created in the above:
source /python-venv/3.7/odoo12/bin/activate
As usual, we need to upgrade pip to its latest version for the activated environment first:
pip install --upgrade pip
Now, start installing libraries required by Odoo 12 for the virtual environment. Please make sure you have finished cloning Odoo 12 source code.
pip install -r /opt/odoo/odoo12/requirements.txt
Start Odoo 12
Now, we can start Odoo 12 in the virtual environment by running the following command that connects PostgreSQL on port 5432 and offers HTTP port 8089 for the client to access:
/opt/odoo/odoo12/odoo-bin --db_port=5432 --http-port=8089
You should see the output as below in the terminal:

Now, you can open your browser and input the address like http://your_id:8089 to see the Odoo 12 Database Creator User Interface as below:

Now, you can input database name, email, etc then hit the button Create database to initilize your first Odoo 12 database.
Stop Odoo 12 and Exit
To stop the Odoo 12, just get back to the terminal and hit Ctrl+C twice.
Now, let’s get ready for the next steps to install Odoo 12 with Python 3.8 by running commands below.
Deactivate Virtual Environment
deactivate
Get back to the previous unix user account:
exit
Install Odoo 12 with Python 3.8 and PostgreSQL 12
Installing Odoo 12 with Python 3.8 is similar to the Install Odoo 12 with Python 3.7.
Create parent folder for Python 3.8 virtual environment for Odoo12
sudo mkdir -p /python-venv/3.8/odoo12 sudo chown -hR odoo12_38:odoo /python-venv/3.8/odoo12
Switch to the user odoo12_38:
sudo su - odoo12_38 -s /bin/bash
Create Python 3.8 virtual environment for Odoo 12:
python3.8 -m venv /python-venv/3.8/odoo12
Activate the virtual environment:
source /python-venv/3.8/odoo12/bin/activate
Upgrade pip
pip install --upgrade pip
Install Odoo 12’s required libraries:
pip install -r /opt/odoo/odoo12/requirements.txt
Start Odoo 12 that connects PostgreSQL 12:
/opt/odoo/odoo12/odoo-bin --db_port=5433 --http-port=8099
After verifying that the Odoo 12 worked properly, exit:
deactivate
exit
Step 6 – Run Odoo 12 as service / daemon
In this section, I will guide you on how to create startup services for your newly installed Odoo 12 instances so that they will be running as service and started every time the server is started.
Odoo 12 Python 3.7 Daemon
Create Odoo 12 Configuration File
Configuration file is the file that stores configuration directives that let Odoo know how to run (e.g. addons path, database port, etc).
In this section, I will create a configuration file named odoo12_37.conf and store it in /home/odoo12_37. I will use nano editor to create the file:
sudo nano /home/odoo12_37/odoo12_37.conf
Now, copy and pasted the following in your nano editor UI:
[options] addons_path = /opt/odoo/odoo12/odoo/addons,/opt/odoo/odoo12/addons admin_passwd = admin # please change this master password csv_internal_sep = , data_dir = /home/odoo12_37/.local/share/Odoo db_host = False db_maxconn = 64 db_name = False db_password = False db_port = 5432 db_sslmode = prefer db_template = template0 db_user = False dbfilter = demo = {} email_from = False geoip_database = /usr/share/GeoIP/GeoLite2-City.mmdb http_enable = True http_interface = http_port = 8089 import_partial = limit_memory_hard = 2684354560 limit_memory_soft = 2147483648 limit_request = 8192 limit_time_cpu = 60 limit_time_real = 120 limit_time_real_cron = -1 list_db = True log_db = False log_db_level = warning log_handler = :INFO log_level = info logfile = None logrotate = False longpolling_port = 8090 max_cron_threads = 2 osv_memory_age_limit = 1.0 osv_memory_count_limit = False pg_path = None pidfile = None proxy_mode = False reportgz = False server_wide_modules = base,web smtp_password = False smtp_port = 25 smtp_server = localhost smtp_ssl = False smtp_user = False syslog = False test_enable = False test_file = False test_tags = None translate_modules = ['all'] unaccent = False without_demo = False workers = 0
Now, save the file and exit by hitting Ctrl+X then input y and hit Enter button.
To allow odoo12_37 to access the configration file:
sudo chown odoo12_37:root /home/odoo12_37/odoo12_37.conf
Create Unit Service file
sudo nano /lib/systemd/system/odoo12_37.service
Now, copy and pasted the following in your nano editor UI
[Unit] Description=Odoo12_37 After=network.target postgresql.service [Service] Type=simple PermissionsStartOnly=true User=odoo12_37 Group=odoo SyslogIdentifier=odoo12_37 PIDFile=/run/odoo12_37/odoo12_37.pid ExecStartPre=/usr/bin/install -d -m755 -o odoo12_37 -g odoo /run/odoo12_37 ExecStart=/python-venv/3.7/odoo12/bin/python /opt/odoo/odoo12/odoo-bin -c /home/odoo12_37/odoo12_37.conf --pid=/run/odoo12_37/odoo12_37.pid ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID [Install] Alias=odoo12_37.service WantedBy=multi-user.target
Now, save the file and exit by hitting Ctrl+X then input y and hit Enter button.
Run the following command to notify systemd that a new unit file exists:
sudo systemctl daemon-reload
Now, enable the service and ask it to run on boot:
sudo systemctl enable --now odoo12_37
Now, start your Odoo 12 using systemd:
sudo systemctl start odoo12_37
Now, let’s open your web browser and input the address https://your_ip:8089 to see the Odoo 12 Database Creation User Interface.
To stop it, just run:
sudo systemctl stop odoo12_37
Odoo 12 Python 3.8 Daemon
Create Odoo 12 Configuration File
Configuration file is the file that stores configuration directives that let Odoo know how to run (e.g. addons path, database port, etc).
In this section, I will create a configuration file named odoo12_38.conf and store it in /home/odoo12_38. I will use nano editor to create the file:
sudo nano /home/odoo12_38/odoo12_38.conf
Now, copy and pasted the following in your nano editor UI:
[options] addons_path = /opt/odoo/odoo12/odoo/addons,/opt/odoo/odoo12/addons admin_passwd = admin # please change this master password csv_internal_sep = , data_dir = /home/odoo12_38/.local/share/Odoo db_host = False db_maxconn = 64 db_name = False db_password = False db_port = 5433 db_sslmode = prefer db_template = template0 db_user = False dbfilter = demo = {} email_from = False geoip_database = /usr/share/GeoIP/GeoLite2-City.mmdb http_enable = True http_interface = http_port = 8099 import_partial = limit_memory_hard = 2684354560 limit_memory_soft = 2147483648 limit_request = 8192 limit_time_cpu = 60 limit_time_real = 120 limit_time_real_cron = -1 list_db = True log_db = False log_db_level = warning log_handler = :INFO log_level = info logfile = None logrotate = False longpolling_port = 8100 max_cron_threads = 2 osv_memory_age_limit = 1.0 osv_memory_count_limit = False pg_path = None pidfile = None proxy_mode = False reportgz = False server_wide_modules = base,web smtp_password = False smtp_port = 25 smtp_server = localhost smtp_ssl = False smtp_user = False syslog = False test_enable = False test_file = False test_tags = None translate_modules = ['all'] unaccent = False without_demo = False workers = 0
Now, save the file and exit by hitting Ctrl+X then input y and hit Enter button.
To allow odoo12_38 to access the configration file:
sudo chown odoo12_38:root /home/odoo12_38/odoo12_38.conf
Create Unit Service file
sudo nano /lib/systemd/system/odoo12_38.service
Now, copy and pasted the following in your nano editor UI
[Unit] Description=Odoo12_38 After=network.target postgresql.service [Service] Type=simple PermissionsStartOnly=true User=odoo12_38 Group=odoo SyslogIdentifier=odoo12_38 PIDFile=/run/odoo12_38/odoo12_38.pid ExecStartPre=/usr/bin/install -d -m755 -o odoo12_38 -g odoo /run/odoo12_38 ExecStart=/python-venv/3.8/odoo12/bin/python /opt/odoo/odoo12/odoo-bin -c /home/odoo12_38/odoo12_38.conf --pid=/run/odoo12_38/odoo12_38.pid ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s QUIT $MAINPID [Install] Alias=odoo12_38.service WantedBy=multi-user.target
Now, save the file and exit by hitting Ctrl+X then input y and hit Enter button.
Run the following command to notify systemd that a new unit file exists:
sudo systemctl daemon-reload
Now, enable the service and ask it to run on boot:
sudo systemctl enable --now odoo12_38
Now, start your Odoo 12 using systemd:
sudo systemctl start odoo12_38
Now, let’s open your web browser and input the address https://your_ip:8099 to see the Odoo 12 Database Creation User Interface.
To stop it, just run:
sudo systemctl stop odoo12_38