Instructions
We use Nano to create and edit files. Use CTRL + S + Enter to save and CTRL + X + Enter to edit file editing. Sudo is added to each command, but can be omitted if you are logged in as root.
Guide
Switch versions to get the exact commands for Odoo 16, 17, or 18. Each preset updates users, paths, ports, and the required wkhtmltopdf build automatically.
Update these once and the commands below will respect your values.
We use Nano to create and edit files. Use CTRL + S + Enter to save and CTRL + X + Enter to edit file editing. Sudo is added to each command, but can be omitted if you are logged in as root.
Build the home tree for this release. Setting the base directory to 755 lets sudo-capable users inspect it without switching accounts.
sudo adduser --system --home /opt/odoo16 --group --shell /bin/bash odoo16sudo mkdir -p /opt/odoo16/{custom-addons,src}
sudo chown -R odoo16:odoo16 /opt/odoo16
sudo chmod 755 /opt/odoo16Install compile deps, then make a virtualenv scoped to this release.
Setuptools is pinned below 81 (80.1.0) so Odoo can keep using pkg_resources without the deprecation warning.
sudo apt update
sudo apt -y install python3 python3-venv python3-pip build-essential libpq-dev libldap2-dev libsasl2-dev libxml2-dev libxslt1-dev zlib1g-dev libjpeg-dev libtiff5-dev libopenjp2-7 libffi-devsudo -u odoo16 python3 -m venv /opt/odoo16/venv
sudo -u odoo16 /opt/odoo16/venv/bin/pip install --upgrade pip wheelsudo -u odoo16 /opt/odoo16/venv/bin/pip install "setuptools==80.1.0"Install Redis once per server so Odoo's longpolling bus, cron jobs, and queue workers have a fast in-memory backend.
Enable systemd supervision so Redis restarts automatically with the host.
sudo apt -y install redis-serversudo sed -i "s/^supervised .*/supervised systemd/" /etc/redis/redis.conf
sudo systemctl enable --now redis-server
sudo systemctl status redis-serverClone the correct version into src.
sudo -u odoo16 -H bash -c '
cd /opt/odoo16/src
git clone --depth 1 --branch 16.0 https://github.com/odoo/odoo.git'sudo -u odoo16 -H bash -c '
/opt/odoo16/venv/bin/pip install -r /opt/odoo16/src/odoo/requirements.txt'sudo apt -y install nodejs npm
sudo npm install -g rtlcssUbuntu 24.04 dropped libssl1.1, so install it before wkhtmltox 0.12.5. This is the stable build for Odoo 16.
cd /tmp
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.24_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.24_amd64.debwget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.bionic_amd64.deb
sudo dpkg -i wkhtmltox_0.12.5-1.bionic_amd64.deb
sudo apt-get -f installsudo ln -sf /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf
sudo ln -sf /usr/local/bin/wkhtmltoimage /usr/bin/wkhtmltoimage
wkhtmltopdf --versionThese commands assume the default `postgres` administrator user exists. If your distro renamed it or PostgreSQL isn't installed yet, install/configure PostgreSQL first or swap `postgres` for your admin role.
Update the password to something stronger than "odoo16_db_pass" and reuse it in the config file below.
sudo apt -y install postgresql postgresql-contribsudo -u postgres createuser -d -R -S odoo16
sudo -u postgres createdb -O odoo16 odoo16
sudo -u postgres psql -c "ALTER USER odoo16 WITH PASSWORD 'odoo16_db_pass';"Open the config as the Odoo Linux user, paste the snippet, then save and exit.
sudo mkdir -p /etc/odoo /var/log/odoo
sudo chown odoo16:odoo16 /etc/odoo /var/log/odoosudo -u odoo16 tee /etc/odoo/odoo16.conf > /dev/null <<'EOF'
[options]
admin_passwd = admin1234#
db_host = 127.0.0.1
db_port = 5432
db_user = odoo16
db_password = odoo16_db_pass
db_name = odoo16
http_port = 8069
gevent_port = 8072
addons_path = /opt/odoo16/src/odoo/addons,/opt/odoo16/custom-addons
logfile = /var/log/odoo/odoo16.log
proxy_mode = True
workers = 3
max_cron_threads = 1
limit_time_cpu = 600
limit_time_real = 1200
limit_memory_soft = 671088640
limit_memory_hard = 805306368
EOFsudo tee /etc/systemd/system/odoo16.service >/dev/null <<'EOF'
[Unit]
Description=Odoo 16.0 (Source Install)
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=odoo16
Group=odoo16
WorkingDirectory=/opt/odoo16/src/odoo
ExecStart=/opt/odoo16/venv/bin/python3 /opt/odoo16/src/odoo/odoo-bin -c /etc/odoo/odoo16.conf
Restart=on-failure
TimeoutStopSec=60
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOFsudo systemctl daemon-reload
sudo systemctl enable --now odoo16
sudo systemctl status odoo16Run these as root/sudo so nginx can read its PID and reload cleanly—running `nginx -t` without sudo triggers a permission denied error on /run/nginx.pid.
Copy in the config and swap the domain for your own hostname.
sudo apt -y install nginxsudo tee /etc/nginx/sites-available/odoo.conf >/dev/null <<'EOF'
upstream odoo {
server 127.0.0.1:8069;
}
upstream odoochat {
server 127.0.0.1:8072;
}
server {
listen 80;
server_name odoo.example.com;
location /websocket {
proxy_pass http://odoochat;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location / {
proxy_pass http://odoo;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOFsudo ln -s /etc/nginx/sites-available/odoo.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d odoo.example.comPlace our helper module in custom-addons before you initialize the database so it is ready to install once you log into Odoo.
Re-running this command refreshes the module contents from GitHub.
sudo -u odoo16 bash -c '
cd /opt/odoo16/custom-addons
git clone https://github.com/beltoftandersen/chimkins-helper-module.git chimkins-helper-module 2>/dev/null || (cd chimkins-helper-module && git pull --ff-only)'Stop the service, run a one-time initialization, set the actual admin login password, then bring it back online.
This command installs the base apps (base,sale_management,account,stock,chimkins-helper-module).
The master password for database operations still lives in /etc/odoo/${cfg.user}.conf (`admin_passwd` from Step 9); the shell snippet below updates the admin user's login password to ${cfg.adminPassword}.
sudo systemctl stop odoo16sudo -u odoo16 /opt/odoo16/venv/bin/python3 /opt/odoo16/src/odoo/odoo-bin -c /etc/odoo/odoo16.conf -d odoo16 -i base,sale_management,account,stock,chimkins-helper-module --without-demo=all --stop-after-initsudo -u odoo16 /opt/odoo16/venv/bin/python3 /opt/odoo16/src/odoo/odoo-bin shell -c /etc/odoo/odoo16.conf -d odoo16 <<'EOF'
user = env['res.users'].search([('login', '=', 'admin')], limit=1)
user.password = 'admin1234#'
env.cr.commit()
EOFsudo systemctl start odoo16
sudo systemctl status odoo16Open https://odoo.example.com, log in with the admin password you set (admin1234#), and verify everything loads. Repeat the same recipe for other releases: adjust usernames, branches, and ports.