Friday, May 31, 2024

How to install Odoo 17 on Ubuntu 22.04, step-by-step

How to Install Odoo 17: 

Step 1. Update the System

sudo apt-get update -y && sudo apt-get upgrade -y
Add Swap Memory
df -h
htop

dd if=/dev/zero of=/swapfile bs=1M count=8192 (4GB)
mkswap /swapfile
chmod 0600 /swapfile
swapon /swapfile
echo "/swapfile swap swap defaults 0 0" >> /etc/fstab

Step 2. Install Python and Required Libraries

sudo apt-get install -y python3-pip python3-dev python3-venv libxml2-dev libxslt1-dev libsasl2-dev libldap2-dev build-essential libssl-dev libffi-dev libjpeg-dev libpq-dev libjpeg8-dev liblcms2-dev libblas-dev unzip -y

sudo apt update
sudo apt install libmysqlclient-dev
sudo apt update
sudo apt install zlib1g-dev 
sudo apt update
sudo apt install libatlas-base-dev -y

Step 3. Install NPM and CSS plugins

sudo apt-get install -y npm
sudo ln -s /usr/bin/nodejs /usr/bin/node
sudo npm install -g less less-plugin-clean-css
sudo apt-get install -y node-less

Step 4. Install Wkhtmltopdf

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
or apt install wkhtmltopdf -y
sudo ln -s /usr/local/bin/wkhtmltopdf /usr/bin/
sudo ln -s /usr/local/bin/wkhtmltoimage /usr/bin/
wkhtmltopdf https://google.com google.pdf  - test wkhtmltopdf 
sudo apt-get install w3m w3m-img -y
sudo apt-get install links2 -y
sudo apt-get install lynx-common lynx -y
xdg-open google.pdf
(optional sudo apt install python3-full)
https://stackoverflow.com/questions/39241643/no-module-named-pypdf2-error

Step 5. Install PostgreSQL

sudo apt-get install postgresql -y
sudo systemctl start postgresql && sudo systemctl enable postgresql
sudo systemctl status postgresql

Step 6. Create Odoo and PostgreSQL users

useradd -m -U -r -d /opt/odoo17 -s /bin/bash odoo17
passwd odoo17
New password: YourStrongPasswordHere
Retype new password: YourStrongPasswordHere
passwd: password updated successfully
usermod -aG sudo odoo17
sudo su - postgres -c "createuser -s odoo17"

Step 7. Install and Configure Odoo 17

sudo adduser --system --home=/opt/odoo17 --group odoo17
su - odoo17
git clone https://www.github.com/odoo/odoo --depth 1 --branch 17.0 /opt/odoo17/odoo17
cd /opt/odoo17/odoo17
mv /opt/odoo17/odoo17/* /opt/odoo17/
mv .git/ .github/ .gitignore .weblate.json /opt/odoo17/
python3 -m venv odoo17-venv
source odoo17-venv/bin/activate
pip install --upgrade pip
pip3 install wheel
pip3 install lxml
pip3 install -r /opt/odoo17/requirements.txt
pip install --upgrade pip setuptools wheel pip install gevent==24.2.1
pip install --only-binary :all: gevent==21.12.0 deactivate
mkdir /opt/odoo17/odoo17-custom-addons
chown -R odoo17:odoo17 /opt/odoo17/odoo17-custom-addons
sudo mkdir -p /var/log/odoo17
sudo touch /var/log/odoo17/odoo17.log
sudo chown -R odoo17:odoo17 /var/log/odoo17/ /opt/odoo17/

Step 8. Create Odoo 17 configuration file

sudo nano /etc/odoo17.conf
[options]
admin_passwd = YourStrongPasswordHere
db_host = False
db_port = False
db_user = odoo17
db_password = False
xmlrpc_port = 8069
logfile = /var/log/odoo17/odoo17.log
addons_path = /opt/odoo17/addons,/opt/odoo17/odoo17-custom-addons

Step 9. Create an Odoo systemd unit file

sudo nano /etc/systemd/system/odoo17.service
[Unit]
Description=odoo17
After=network.target postgresql@14-main.service

[Service]
Type=simple
SyslogIdentifier=odoo17
PermissionsStartOnly=true
User=odoo17
Group=odoo17
ExecStart=/opt/odoo17/odoo17-venv/bin/python3 /opt/odoo17/odoo-bin -c /etc/odoo17.conf
StandardOutput=journal+console

[Install]
WantedBy=multi-user.target
-----------------------------------
/opt/odoo17/odoo17-venv/bin/python3 -V
Python 3.10.12

ModuleNotFoundError: No module named 'psycopg2'
sudo apt update
sudo apt install -y python3-dev libpq-dev
pip3 install psycopg2-binary
source odoo17-venv/bin/activate
pip install psycopg2-binary
python3 -c "import psycopg2; print(psycopg2.__version__)"
ModuleNotFoundError: No module named 'urllib3'
source odoo17-venv/bin/activate
pip install urllib3
python -c "import urllib3; print(urllib3.__version__)"
ModuleNotFoundError: No module named 'urllib3'
source odoo17-venv/bin/activate
pip install urllib3
python -c "import urllib3; print(urllib3.__version__)"
sudo systemctl restart odoo17
ModuleNotFoundError: No module named 'werkzeug'
pip install "werkzeug<3"
python -c "import werkzeug; print(werkzeug.__version__)"
ModuleNotFoundError: No module named 'pytz'
pip install pytz
python -c "import pytz; print(pytz.__version__)"
ModuleNotFoundError: No module named 'passlib'
pip install passlib
python -c "import passlib; print(passlib.__version__)"
ModuleNotFoundError: No module named 'PIL'
pip install pillow
python -c "from PIL import Image; print(Image.__version__)"
ModuleNotFoundError: No module named 'reportlab'
pip install reportlab
python -c "import reportlab; print(reportlab.__version__)"
ModuleNotFoundError: No module named 'babel'
pip install babel
python -c "import babel; print(babel.__version__)"
ModuleNotFoundError: No module named 'decorator'
pip install decorator
python -c "import decorator; print(decorator.__version__)"
ImportError: pypdf implementation not found
pip install pypdf
python -c "import pypdf; print(pypdf.__version__)"
ModuleNotFoundError: No module named 'dateutil'
pip install python-dateutil
python -c "import dateutil; print(dateutil.__version__)"
ModuleNotFoundError: No module named 'polib'
pip install polib
python -c "import polib; print(polib.__version__)"
ModuleNotFoundError: No module named 'idna'
pip install idna
python -c "import idna; print(idna.__version__)"
ImportError: lxml.html.clean module is now a separate project lxml_html_clean
pip install lxml_html_clean
ModuleNotFoundError: No module named 'requests'
pip install requests
python -c "import requests; print(requests.__version__)"
ModuleNotFoundError: No module named 'psutil'
pip install psutil
python -c "import psutil; print(psutil.__version__)"
ModuleNotFoundError: No module named 'jinja2'
pip install Jinja2
python -c "import jinja2; print(jinja2.__version__)"
ModuleNotFoundError: No module named 'rjsmin'
pip install rjsmin
python -c "import rjsmin; print(rjsmin.__version__)"
num2words is not available
pip install num2words
ModuleNotFoundError: No module named 'OpenSSL'
pip install pyOpenSSL
python -W "ignore::pkg_resources.PkgResourcesDeprecationWarning"
ModuleNotFoundError: No module named 'docutils'
pip install docutils
pip install vobject
pip install qrcode
pip install chardet
sudo apt update
sudo apt install sassc -y
pip3 install libsass
which sassc



sudo chown -R odoo17:odoo17 /var/log/odoo17/ /opt/odoo17/ /etc/odoo17.conf
sudo chmod 777 /var/log/odoo17/odoo17.log
-------------------------------------------------------------------------
add end of the file
nano /root/.bashrc
alias python3='/usr/bin/python3.10'
sudo systemctl restart odoo17

sudo systemctl daemon-reload

sudo systemctl start odoo17 && sudo systemctl enable odoo17

sudo systemctl status odoo17
sudo systemctl stop odoo17
sudo systemctl start odoo17
sudo systemctl restart odoo17

http://YourServerIPAddress:8069
tail -f /var/log/odoo17/odoo17.log

Proxy Pass odoo 8069 to 80 with enhancements

There are couple of things that you should be familiar before going through the steps
  1. Odoo
  2. Linux
  3. Nginx

So i assume the application was now accessible through your port 8069, eg. 188.xx.xx.xx:8069 or yourdomain.com:8069 and your requirement would be
  1. your application should be run on port 80, or your domain eg: yourdomain.com
  2. your application should be run under secure connection
  3. your application should not be accessible through port 8069 anymore     

sudo apt-get install nginx
nano /etc/nginx/sites-available/odoo

upstream odoo {
    server 127.0.0.1:8069;
}

server {
    listen 80;
    server_name yourdomain.com;
    root        /usr/share/nginx/html;
    index       index.html index.htm;
    access_log  /var/log/nginx/yourdomaincom.access.log;
    error_log   /var/log/nginx/yourdomaincom.error.log;

    location / {
        proxy_pass  http://odoo;
        # force timeouts if the backend dies
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;

        # set headers
        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 https;
    }

    # cache some static data in memory for 60mins
    location ~* /web/static/ {
        proxy_cache_valid 200 60m;
        proxy_buffering on;
        expires 864000;
        proxy_pass http://odoo;
    }
}
Save and exit

cd /etc/nginx/sites-enabled/
ln -s ../sites-available/odoo odoo
rm -rf default
cd cd /etc/nginx/sites-available/
rm -rf default
nginx -t
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8069 -j REDIRECT --to-port 80
/etc/init.d/nginx restart

Open URL http://localhost or http://ip

How To Secure Apache with Let's Encrypt on Ubuntu 22.04

Step 1 — Installing Certbot

sudo apt update
sudo apt install certbot python3-certbot-apache 

sudo apt-get install python3-certbot-nginx

Step 2 — Checking your Apache Virtual Host Configuration

sudo nano /etc/apache2/sites-available/your_domain.conf
...
ServerName your_domain
ServerAlias www.your_domain
...

sudo apache2ctl configtest
sudo systemctl reload apache2

Step 3 — Allowing HTTPS Through the Firewall

sudo ufw status
sudo ufw allow 'Apache Full'
# sudo ufw delete allow 'Apache'
sudo ufw status

Step 4 — Obtaining an SSL Certificate

sudo certbot --apache

sudo certbot --nginx -d my_subdomain.website.com -d my_subdomain2.website.com

Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): you@your_domain
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N


Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: your_domain
2: www.your_domain
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 

Output
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on 2024-05-31.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

Deploying certificate
Successfully deployed certificate for your_domain to /etc/apache2/sites-available/your_domain-le-ssl.conf
Successfully deployed certificate for www.your_domain.com to /etc/apache2/sites-available/your_domain-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https:/your_domain and https://www.your_domain.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Step 5 — Verifying Certbot Auto-Renewal

sudo systemctl status certbot.timer

Output
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset:>
     Active: active (waiting) since Mon 2024-05-31 20:52:46 UTC; 4min 3s ago
    Trigger: Tue 2022-04-12 00:56:55 UTC; 4h 0min left
   Triggers: ● certbot.service
May 31 20:52:46 jammy-encrypt systemd[1]: Started Run certbot twice daily.

sudo certbot renew --dry-run

Output
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/your_domain.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for your_domain and www.your_domain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/your_domain/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Changes on Odoo home page:
1. nano /opt/odoo17/odoo17/addons/web/static/src/webclient/webclient.js 
line no 35 change Odoo to <Project name>
nano /opt/odoo17/odoo17/addons/web/static/tests/webclient/actions/misc_tests.js
line no 210 change Odoo to <Project name>

2. replace below files for change favicon icon
/opt/odoo17/odoo17/addons/point_of_sale/static/src/img/favicon.ico
/opt/odoo17/odoo17/addons/web/static/img/favicon.ico