One-Click Odoo 18 Installation on Ubuntu 22.04: the Complete Guide
“I wish I could spin up Odoo with one command…”
Now you can. In this post you’ll learn how to drop a single shell script onto a fresh Ubuntu 22.04 (Jammy) server and walk away—five minutes later you’ll have a production-ready Odoo 18 stack (Python 3.12, PostgreSQL, Node 18, wkhtmltopdf 0.12.5, systemd service, log rotation) humming on the port of your choice.
🗺️ What you’ll find below
- Why a script beats the manual method
- Prerequisites & tested environment
- The installer script (copy-paste ready)
- Running it—literally one command
- What the script does under the hood
- Troubleshooting & common questions
- Wrapping up
1 Why automate?
- Consistency – zero “works-on-my-laptop” surprises.
- Speed – 200+ manual keystrokes crushed into 1.
- Idempotence – re-run anytime to heal a half-broken install.
- Safety – the Odoo Linux user is system-scoped, no login shell by default.
2 Prerequisites
Item | Notes |
---|---|
Fresh Ubuntu 22.04 LTS server | Tested on 22.04.4 server & Jammy LXC containers |
sudo privileges | Run the script as root or through sudo |
Outbound internet | Fetches packages from apt, GitHub, NodeSource |
2 GB RAM + 2 CPU (minimum) | Odoo boots fine with less, but building wheels is faster |
Need Ubuntu 24.04? Swap in Python 3.12 from the default repo and skip the legacy libssl1.1 step—the rest is identical.
3 The one-click installer
Create a file called install_odoo18_22.sh (sudo nano install_odoo18_22.sh ) and paste the contents below.
(Feel free to add it to a gist or your Ansible repo later.)
#!/usr/bin/env bash # ╔═════════════════════════════════════════════════════════════╗ # ║ One-click Odoo 18 installer for Ubuntu 22.04 LTS (Jammy) ║ # ╚═════════════════════════════════════════════════════════════╝ # Optional flags (defaults): # --odoo-version 18.0 # --odoo-user odoo18 # --db-user odoo18 # --db-pass changeme # --port 8069 # --log-dir /var/log/odoo18 # --config /etc/odoo18.conf # --service odoo18 # # Example: # sudo ./install_odoo18_22.sh --db-pass "Sup3rSecret!" --port 8070 set -euo pipefail; IFS=$'\n\t' # ─────────────────────── CLI flags ──────────────────────────── ODOO_VERSION=18.0 ODOO_USER=odoo18 DB_USER=odoo18 DB_PASS=changeme \ ODOO_PORT=8069 LOG_DIR=/var/log/odoo18 ODOO_CONF=/etc/odoo18.conf \ SERVICE_NAME=odoo18 while [[ $# -gt 0 ]]; do case $1 in --odoo-version) ODOO_VERSION=$2; shift 2;; --odoo-user) ODOO_USER=$2; shift 2;; --db-user) DB_USER=$2; shift 2;; --db-pass) DB_PASS=$2; shift 2;; --port) ODOO_PORT=$2; shift 2;; --log-dir) LOG_DIR=$2; shift 2;; --config) ODOO_CONF=$2; shift 2;; --service) SERVICE_NAME=$2; shift 2;; -h|--help) grep '^# ' "$0"|sed 's/^# //' ; exit 0;; *) echo "Unknown flag $1"; exit 1;; esac; done die(){ echo "❌ $*"; exit 1; } echo "▶ Updating apt …"; apt update -y && apt upgrade -y echo "▶ Enabling Python 3.12 (Deadsnakes) …" apt install -y software-properties-common add-apt-repository -y ppa:deadsnakes/ppa && apt update -y echo "▶ Adding Node 18 repo …" curl -fsSL https://deb.nodesource.com/setup_18.x | bash - || echo "⚠️ Node repo skipped" DEBIAN_FRONTEND=noninteractive apt install -y \ git curl wget build-essential sudo postgresql \ python3.12 python3.12-venv python3.12-dev python3-pip \ libxml2-dev libxslt1-dev zlib1g-dev libsasl2-dev libldap2-dev \ libssl-dev libffi-dev libjpeg-dev libpq-dev libjpeg8-dev liblcms2-dev \ libblas-dev libatlas-base-dev openssh-server fail2ban \ nodejs npm xfonts-75dpi xfonts-base [[ -e /usr/bin/node ]] || ln -s /usr/bin/nodejs /usr/bin/node npm install -g less less-plugin-clean-css || echo "⚠️ npm-less skipped" # ── wkhtmltopdf 0.12.5 (static) ─────────────────────────────── if ! command -v wkhtmltopdf >/dev/null; then echo "▶ Installing wkhtmltopdf 0.12.5 …" wget -q https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.focal_amd64.deb wget -q http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb dpkg -i libssl1.1_* || true; dpkg -i wkhtmltox_* || true apt -f install -y && rm wkhtmltox_* libssl1.1_* fi # ── PostgreSQL role ─────────────────────────────────────────── systemctl enable --now postgresql sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'" | grep -q 1 || sudo -u postgres createuser --createdb --superuser --pwprompt "$DB_USER" <<<"$DB_PASS"$'\n'"$DB_PASS" # ── System user & source ───────────────────────────────────── adduser --system --home=/opt/$ODOO_USER --group "$ODOO_USER" 2>/dev/null || true sudo -H -u "$ODOO_USER" bash -c " cd /opt/$ODOO_USER [[ -d odoo ]] || git clone --depth 1 --branch $ODOO_VERSION https://github.com/odoo/odoo.git python3.12 -m venv venv source venv/bin/activate pip install -U pip wheel pip install -r odoo/requirements.txt " # ── Config & service ───────────────────────────────────────── cat >"$ODOO_CONF" <<EOF [options] admin_passwd = $(openssl rand -hex 16) db_host = False db_port = False db_user = $DB_USER db_password = $DB_PASS addons_path = /opt/$ODOO_USER/odoo/addons logfile = $LOG_DIR/odoo.log xmlrpc_port = $ODOO_PORT EOF chown $ODOO_USER: "$ODOO_CONF"; chmod 640 "$ODOO_CONF" mkdir -p "$LOG_DIR"; chown $ODOO_USER:root "$LOG_DIR" cat >/etc/systemd/system/${SERVICE_NAME}.service <<EOF [Unit] Description=Odoo ${ODOO_VERSION} After=network.target postgresql.service [Service] Type=simple User=$ODOO_USER ExecStart=/opt/$ODOO_USER/venv/bin/python3.12 /opt/$ODOO_USER/odoo/odoo-bin -c $ODOO_CONF Restart=on-failure [Install] WantedBy=multi-user.target EOF chmod 644 /etc/systemd/system/${SERVICE_NAME}.service systemctl daemon-reload && systemctl enable --now ${SERVICE_NAME}.service echo -e "\n🎉 Odoo $ODOO_VERSION is live on http://$(hostname -I|awk '{print $1}'):$ODOO_PORT\n"
Make it executable:
chmod +x install_odoo18_22.sh
4 Run it (the real “single click”)
sudo ./install_odoo18_22.sh --db-pass "ChangeMe!" --port 8069
Grab a coffee—the script:
- Updates the OS.
- Installs Python 3.12, Node 18, PostgreSQL 14, wkhtmltopdf 0.12.5.
- Creates a non-login odoo18 system user.
- Clones the Odoo 18 source and builds a virtual environment.
- Drops a hardened odoo18.conf in /etc.
- Registers a systemd service and starts it.
When you see “🎉 Odoo 18 is live”, point your browser to:
http://<SERVER-IP>:8069
and create your first database.
5 What just happened? (the short version)
Stage | Highlights |
---|---|
System prep | Deadsnakes PPA + NodeSource repo |
Dependencies | xfonts-75dpi & xfonts-base fix wkhtmltopdf deps |
wkhtmltopdf | Static 0.12.5 build + legacy libssl1.1 (Odoo-approved) |
PostgreSQL | Super-role with the password you set |
Odoo env | /opt/odoo18/venv isolates Python libs |
Service | systemctl status odoo18 for health checks |
Logs | /var/log/odoo18/odoo.log rotates via logrotate defaults |
6 Troubleshooting & FAQs
Symptom | Fix |
---|---|
wkhtmltopdf PDF header/footer misaligned | You’re on 0.12.6+—rerun script or reinstall 0.12.5 |
psql: connection refused | systemctl status postgresql → start service |
Need to SSH as odoo18 | sudo -H -u odoo18 bash (account is nologin by design) |
Change port later | Edit xmlrpc_port in /etc/odoo18.conf & systemctl restart odoo18 |
7 Wrapping up
With one script and one command you’ve provisioned a fully-functional Odoo 18 stack on Ubuntu 22.04—ready for production or dev play. Clone the script into your IaC pipeline, bake it into a custom AMI, or hand it to a teammate who “just needs Odoo” by lunchtime.
Happy automating—and happy selling with Odoo 18!