Self-Host Odoo Behind Nginx on Port 80 Safely
This guide walks you through installing Odoo on your own server and putting it behind an Nginx reverse proxy so it serves on standard HTTP port 80. You’ll get a stable, production-ready setup that can later be upgraded to HTTPS with Let’s Encrypt. You’ll need a Linux server (Ubuntu 22.04 or 24.04 recommended) with root access, a domain name pointing to your server’s IP, and basic comfort with the command line.
What You’ll Need
- A Linux server (Ubuntu 22.04/24.04) with at least 2 GB RAM and 20 GB free disk.
- Root or sudo access to the server.
- A domain name (e.g.,
odoo.example.com) with an A record pointing to your server’s public IP. - Port 80 and 443 open in your firewall (we’ll use 80 now, 443 later for HTTPS).
- Basic familiarity with the terminal and editing files (we’ll use
nano).
Step-by-Step
- Update your system
Log in via SSH and run:sudo apt update && sudo apt upgrade -y
This ensures all packages are current. - Install PostgreSQL and other dependencies
Odoo uses PostgreSQL as its database. Install it along with required libraries:sudo apt install -y postgresql git python3-pip build-essential wget node-less libldap2-dev libsasl2-dev libjpeg-dev zlib1g-dev libpq-dev - Create a system user for Odoo
Running Odoo as a dedicated user improves security. Create one:sudo useradd -m -d /opt/odoo -U -r -s /bin/bash odoo - Install Odoo from source
Clone the Odoo repository (use the version you need, e.g., 17.0):sudo git clone --depth 1 --branch 17.0 https://github.com/odoo/odoo.git /opt/odoo/odoo
Then install Python dependencies:sudo pip3 install -r /opt/odoo/odoo/requirements.txt - Create the PostgreSQL database user
Odoo needs its own database user. Switch to the postgres system user and create one:sudo su - postgres -c "createuser --createdb --username postgres --no-createrole --no-superuser odoo" - Configure Odoo
Create a config file at/etc/odoo.confwith the following content (adjust paths and passwords):[options] addons_path = /opt/odoo/odoo/addons admin_passwd = change_this_admin_password db_host = False db_port = False db_user = odoo db_password = False logfile = /var/log/odoo/odoo.log
Create the log directory and set permissions:
sudo mkdir -p /var/log/odoo && sudo chown odoo:odoo /var/log/odoo - Create a systemd service
Create/etc/systemd/system/odoo.servicewith:[Unit] Description=Odoo After=network.target [Service] Type=simple User=odoo Group=odoo ExecStart=/usr/bin/python3 /opt/odoo/odoo/odoo-bin -c /etc/odoo.conf Restart=always [Install] WantedBy=multi-user.target
Then reload systemd and start Odoo:
sudo systemctl daemon-reload && sudo systemctl enable --now odoo - Verify Odoo is running
Check the service status:sudo systemctl status odoo
You should see “active (running)�. Test locally with:curl http://localhost:8069– you should get an HTML response. - Install and configure Nginx
Install Nginx:sudo apt install -y nginx
Create a new server block at/etc/nginx/sites-available/odoowith:server { listen 80; server_name odoo.example.com; location / { proxy_pass http://127.0.0.1:8069; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }Replace
odoo.example.comwith your actual domain. Enable the site and remove the default:sudo ln -s /etc/nginx/sites-available/odoo /etc/nginx/sites-enabled/odoosudo rm /etc/nginx/sites-enabled/default - Test and reload Nginx
Check for syntax errors:sudo nginx -t
If OK, reload:sudo systemctl reload nginx - Allow port 80 through the firewall
If using UFW:sudo ufw allow 80/tcp
Also allow SSH and 443 for future:sudo ufw allow 22/tcp && sudo ufw allow 443/tcp
Enable UFW if not already:sudo ufw enable - Access Odoo via your domain
Open a browser and go tohttp://odoo.example.com. You should see the Odoo database creation screen. Fill in a master password and create your first database.
Common Mistakes
- Forgetting to set the correct domain in Nginx – if you use the default server block, you may get the wrong site.
- Running Odoo as root – this is a security risk; always use the dedicated
odoouser. - Using the default admin password – change
admin_passwdin the config to a strong random string. - Not setting proxy headers – without
X-Forwarded-*, Odoo may generate incorrect URLs and think it’s on port 8069. - Leaving port 8069 open to the public – block it in your firewall; only Nginx should reach Odoo.
Tips
- Use a dedicated domain or subdomain for Odoo, not the root domain, to keep other services separate.
- Set up HTTPS (SSL) after this works – use Certbot’s Nginx plugin to get a free Let’s Encrypt certificate.
- Schedule regular backups of your PostgreSQL database and the
/opt/odoodirectory. - Monitor logs:
tail -f /var/log/odoo/odoo.logand Nginx logs in/var/log/nginx/. - Increase Nginx client_max_body_size if you upload large files (e.g.,
client_max_body_size 100M;inside the server block).
Troubleshooting
- 502 Bad Gateway – Nginx can’t reach Odoo. Check Odoo is running (
systemctl status odoo) and that it listens on 127.0.0.1:8069 (ss -tlnp | grep 8069). - Connection refused on port 80 – Check Nginx is running (
systemctl status nginx) and that your firewall allows port 80. Test withcurl http://localhoston the server. - Odoo shows “Database selection� but you can’t create a database – Ensure the PostgreSQL user
odoohas createdb rights. You can grant them withsudo su - postgres -c "ALTER USER odoo CREATEDB;". - Odoo generates URLs with port 8069 – You missed the proxy headers in Nginx. Add the
proxy_set_headerlines exactly as shown. - After a reboot, Odoo doesn’t start – Check the service is enabled (
systemctl is-enabled odoo). If not, runsystemctl enable odoo. - Nginx configuration test fails – Look at the error message; often it’s a missing semicolon or a typo in the server_name. Use
sudo nginx -tto see the exact line.
Frequently Asked Questions
Is it safe to run Odoo on port 80 without HTTPS?
Port 80 sends data in plain text. For a production environment, you should enable HTTPS (port 443) as soon as possible. This guide sets up port 80 as a starting point; you can add SSL with Certbot in minutes.
Can I use a different port than 80?
Yes, you can change the listen directive to any port (e.g., 8080), but then users must include that port in the URL. Port 80 is the default for HTTP and requires no suffix.
How do I update Odoo later?
Stop the service, pull the latest code from the repository (cd /opt/odoo/odoo && sudo git pull), re-install any new Python dependencies, and restart the service. Always back up your database first.
What should I set for the admin password in Odoo?
Use a long, random string. This password is used to create and manage databases from the web interface. Store it securely.
Can I run Odoo on the same server as other websites?
Yes, Nginx can host multiple server blocks. Just give each site its own server_name and ensure they listen on different ports or use different domains.
Why do I see a “403 Forbidden� error?
This often means Nginx can’t access the proxy target. Check that Odoo is listening on 127.0.0.1:8069 and that the proxy_pass URL is exactly correct. Also check file permissions on the log directory.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.