Self-hosting Odoo gives you full control over data, and custom modules. This guide walks you through a safe, maintainable install of Odoo 19 on Ubuntu 24.04, covering both Community and Enterprise editions, an easy CLI installer (install-odoo), configuration, HTTPS, your instance runs reliably in production.
Key references used: Odoo official docs (install paths & packaging), the install-odoo CLI project, and practical server-deployment tutorials.
Quick overview — what you’ll do
- Prepare the Ubuntu 24.04 server (users, updates, firewall).
- Install PostgreSQL and system packages.
- Install Odoo 19 (two options: recommended manual/source method or quick CLI with install-odoo).
- Configure systemd and Nginx reverse proxy with HTTPS.
- Optionally add Enterprise addons (requires Odoo subscription and enterprise repo access). Odoo Source
Prerequisites (what you need before starting)
- An Ubuntu 24.04 server (fresh or dedicated VM).
- A non-root sudo user (recommended).
- Minimum recommended hardware for small production: 4 vCPU, 8–16 GB RAM, 100+ GB SSD. Increase for many users/modules. (real world deployments often use 4+ GB RAM as absolute minimum).
- Domain name pointing to the server (for HTTPS).
- Odoo Enterprise: valid subscription and access to the enterprise addons / repository if you plan to enable Enterprise features.
- (Optional but recommended) Node.js (for JS build assets) and wkhtmltopdf 0.12.6 for PDF headers/footers.
Recommended PostgreSQL version
Odoo requires PostgreSQL. Recent community guides and deployments recommend using modern PostgreSQL (15 or 16) for best compatibility and performance with Odoo 19; the packaged installers default to the distro PostgreSQL package. Use the distribution package unless you have a specific reason to compile/customize.
Option A
Quick install using the install-odoo CLI (fast & repeatable)
install-odoo is a CLI helper that automates many common tasks (user creation, PostgreSQL, dependencies, Odoo clone, systemd, nginx). It’s useful for a fast, consistent setup.
- Install Node.js & npm (if not installed)
sudo apt update
sudo apt install -y nodejs npm
# (Or install Node.js 18+ from nodesource for recommended node versions)- Run the installer (interactive)
npx install-odoonpx install-odoo will prompt for options: Odoo version (choose 19.0), install Community or Enterprise, PostgreSQL config, domain, SSL (LetsEncrypt) options, etc. The tool supports Ubuntu 22.04 and 24.04.
- After completion:
- The installer typically creates an odoo system user, clones the specified Odoo branch, sets up a Python venv, installs dependencies, configures systemd, and generates an Nginx config with HTTPS if you chose that option.
- Verify service:
sudo systemctl status odoo-server.service
# or check the service name printed by the installerNotes:
- The CLI speeds setup and is great for dev/test or small production — but review generated configs and secrets before going to production.
- If you choose Enterprise, the installer may ask for your Enterprise repository credentials or expect you to have them available.
Option B
Manual (recommended for full control / production)
If you need precise control or must integrate custom modules, follow these manual steps.
- System update and create user
sudo apt update && sudo apt upgrade -y
sudo adduser --system --home=/opt/odoo --group --shell=/bin/bash odoo- Install PostgreSQL and create DB user
sudo apt install -y postgresql postgresql-contrib postgresql-16-pgvector
sudo -u postgres createuser --createdb --username postgres --no-createrole --pwprompt odoo
# Follow prompts to set password for user 'odoo'- Install system packages & Python venv
sudo apt install -y git python3-venv python3-pip build-essential wget \
python3-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
libjpeg-dev zlib1g-dev libpq-dev nodejs npm node-less
sudo ln -s /usr/bin/nodejs /usr/bin/node
sudo npm install -g less less-plugin-clean-css- wkhtmltopdf (for PDF reports with headers/footers)
sudo wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bionic_amd64.deb
sudo dpkg -i wkhtmltox_0.12.6-1.bionic_amd64.deb
sudo apt install -f- Clone Odoo 19 source and set up virtualenv
sudo -u odoo -H bash -c '
cd /opt/odoo
git clone --depth 1 --branch 19.0 https://github.com/odoo/odoo.git odoo-server
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r /opt/odoo/odoo-server/requirements.txt
'FOR ENTERPRISE ONLY
if you wanted to deploy the odoo enterprise you can clone it too.
sudo -u odoo -H bash -c '
mkdir -p /opt/odoo/enterprise
cd /opt/odoo/enterprise
git clone --depth 1 --branch 19.0 https://github.com/odoo/enterprise.git addons'Note: To clone and install the Odoo Enterprise version, you must be an official Odoo partner and have authorized access to https://github.com/odoo/enterprise.
- Create odoo-server.conf (example) and log directory
sudo nano /etc/odoo-server.confPaste the following content, adjusting the admin_passwd and other settings as needed:
[options]
admin_passwd = your_secure_password
db_host = False
db_port = False
db_user = odoo
db_password = False
addons_path = /opt/odoo/odoo-server/addons,/opt/odoo/custom-addons
; uncomment below if you are using odoo enterprise
;addons_path = /opt/odoo/odoo-server/addons,/opt/odoo/enterprise/addons,/opt/odoo/custom-addons
logfile = /var/log/odoo/odoo-server.log
workers = 4 ; tune per CPU and RAM
max_cron_threads = 1
limit_memory_soft = 2147483648 ; 2GB, tune based on RAM
limit_time_cpu = 60
limit_time_real = 120
db_maxconn = 64Set workers to 0 for testing; for production set workers = (CPU * 2) + 1 as a baseline and tune.
Save and close the file. Then, set the appropriate permissions.
sudo mkdir -p /opt/odoo/custom-addons
sudo chown odoo:odoo /opt/odoo/custom-addons
sudo mkdir -p /var/log/odoo
sudo chown odoo:odoo /var/log/odoo
sudo chown odoo: /etc/odoo-server.conf
sudo chmod 640 /etc/odoo-server.conf- Create a Systemd Service File
sudo nano /etc/init.d/odoo-serverTo manage Odoo as a service, create a odoo service file that allows you to start, stop, and restart the application easily.
Add the following content to the file:
#!/bin/sh
### BEGIN INIT INFO
# Provides: odoo-server
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Enterprise Business Applications
# Description: ODOO Business Applications
### END INIT INFO
PATH=/opt/odoo/venv/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
DAEMON=/opt/odoo/odoo-server/odoo-bin
VENV=/odoo/venv/bin/python3
NAME=odoo-server
DESC=odoo-server
# Specify the user under which the Odoo service will run
USER=odoo
# Path to the Odoo configuration file
CONFIGFILE="/etc/odoo-server.conf"
# PID file location
PIDFILE=/var/run/${NAME}.pid
# Additional options that are passed to the Daemon
DAEMON_OPTS="-c $CONFIGFILE"
# Check if the DAEMON executable exists and CONFIGFILE is present
[ -x $DAEMON ] || { echo "DAEMON not found"; exit 1; }
[ -f $CONFIGFILE ] || { echo "CONFIGFILE not found"; exit 1; }
# Function to check if the PID file exists and if the process is running
checkpid() {
[ -f $PIDFILE ] || return 1
pid=$(cat $PIDFILE)
[ -d /proc/$pid ] && return 0
return 1
}
case "${1}" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER --background --make-pidfile --exec $VENV $DAEMON -- $DAEMON_OPTS
echo "${NAME} started."
;;
stop)
echo -n "Stopping ${DESC}: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo
echo "${NAME} stopped."
;;
restart|force-reload)
echo -n "Restarting ${DESC}: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo
sleep 5
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER --background --make-pidfile --exec $VENV $DAEMON -- $DAEMON_OPTS
echo "${NAME} restarted."
;;
status)
if checkpid; then
echo "${DESC} is running."
else
echo "${DESC} is not running."
fi
;;
*)
echo "Usage: $NAME {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0or you can copy the it from the Odoo source (/opt/odoo/odoo-server/debian/init). make sure to update the paths according to your environment.
sudo chmod 755 /etc/init.d/odoo-server
sudo chown root: /etc/init.d/odoo-server
sudo update-rc.d odoo-server defaults- Start Odoo Service
sudo su root -c "/etc/init.d/odoo-server start"at this point your odoo service will start and you will be able to access it from your IP address like http://your_server_ip:8069
Now we need to add the nginx reverse proxy to access Odoo from domain. make sure you have a domain/subdomain ready and DNS A record pointed to the server IP address.
- Nginx reverse proxy & HTTPS (Let’s Encrypt)
- Create an Nginx site that reverse proxies http://127.0.0.1:8069 and forwards WebSocket/longpoll requests for chat / live features (if you use longpolling or an external bus).
- Use Certbot to obtain certificates:
sudo apt install -y nginx
sudo apt-get install -y snapd
sudo snap install core; snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotcreate the nginx configuration file
sudo nano /etc/nginx/sites-available/odoo.confpaste the below content (make sure to change the domain name)
#odoo server
upstream odoo_server {
server 127.0.0.1:8069;
}
upstream odoo_server_chat {
server 127.0.0.1:8072;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name yourdmoain.com www.yourdmoain.com;
proxy_read_timeout 900s;
proxy_connect_timeout 900s;
proxy_send_timeout 900s;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header HTTP_X_FORWARDED_HOST $remote_addr;
# Add Headers for odoo proxy mode
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
underscores_in_headers on;
# increase proxy buffer size
proxy_buffers 16 64k;
proxy_buffer_size 128k;
# force timeouts if the backend dies
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503;
types {
text/less less;
text/scss scss;
}
# log
access_log /var/log/nginx/odoo_access.log;
error_log /var/log/nginx/odoo_error.log;
# Redirect longpoll requests to odoo longpolling port
location /longpolling {
proxy_pass http://odoo_server_chat;
}
# Redirect requests to odoo backend server
location / {
proxy_redirect off;
proxy_pass http://odoo_server;
}
location /websocket {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://odoo_server_chat;
}
# enable data compression
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript application/pdf image/jpeg image/png;
gzip_vary on;
client_header_buffer_size 4k;
large_client_header_buffers 4 64k;
client_max_body_size 0;
}save and exit the file. now we need to create the symbolic link to the odoo reverse proxy file. and check the configuration
ln -s /etc/nginx/sites-available/odoo.conf /etc/nginx/sites-enabled/odoo.conf
nginx -tnow we will acquire the ssl certificate using the certbot. (make sure to change the domain name)
sudo certbot --nginx -d yourdmoain.com www.yourdmoain.comat this point you should access the odoo from your configured domain. open your domain on the browser and you should see the odoo database selector initially.
Additional checklist
- Enable a firewall (UFW): Allow only essential ports — SSH (preferably on a custom port), HTTP (80), and HTTPS (443).
- Restrict database access: Disable remote PostgreSQL connections unless absolutely required. Bind PostgreSQL to localhost or limit access within your private network (VPC).
- Keep the system updated: Regularly apply OS and package updates to patch vulnerabilities and maintain stability.
- Rotate and manage logs: Set up log rotation for Odoo logs to prevent large file sizes from consuming disk space. Use logrotate or systemd journaling rules.
- Automate database backups: Schedule daily automated backups of both the PostgreSQL database and filestore. Test restores periodically to ensure data integrity.
- Optimize PostgreSQL for Odoo: Tune key parameters like shared_buffers, work_mem, and effective_cache_size based on available RAM. Monitor performance regularly and adjust as workload grows.
While this guide gives you a strong foundation for self-hosting Odoo, building a fully optimized business management system takes deeper expertise. For professional Odoo implementation, custom module development, smooth data migration, and reliable deployment, partner with a team that knows Odoo inside out.
Contact Heliconia Solutions to turn your Odoo instance into a powerful, tailored platform that truly fits your business.


