This post reveals the series of steps I did to have relationalgames running Odoo on a production https server.
On Hetzner, you can just buy a 2 CPU server with 40Gb as a starting point.
As soon you have setup your hetzner server with your local ssh key, you can ssh root@[YOUR-IP] to enter the server.
Docker and docker-compose
Following steps at: How to install Docker and docker compose on Ubuntu
When running sudo apt-get update, got an error. To solve it needed to delete file docker.list at /etc/apt/sources.list.d (thanks to How to fix apt-get update error on Ubuntu or Debian)
Next, following steps at:
As this is ubuntu 22.04 and not 20.04 in step:
sudo add-apt-repository “deb [arch=amd64] Index of linux/ubuntu/ focal stable”
Replace “focal” with “jammy”
In the end the steps were a blend from the two links above
Docker and docker compose prerequisites
sudo apt-get install curl
sudo apt-get install gnupg
sudo apt-get install ca-certificates
sudo apt-get install lsb-release
Download the docker gpg file to Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository “deb [arch=amd64] Index of linux/ubuntu/ jammy stable”
apt-cache policy docker-ce
sudo apt-get update
Install docker and docker compose on Ubuntu
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Verify the Docker and docker compose install on Ubuntu
sudo docker run hello-world
sudo systemctl status docker
Odoo
Following steps at Docker for Odoo 16 - get Odoo within 1 minute
$ git clone GitHub - minhng92/odoo-16-docker-compose: Fast set-up Odoo 16 for dev/production with Docker Compose
$ cd odoo-16-docker-compose
$ sudo chmod -R 777 addons && sudo chmod -R 777 etc && mkdir -p postgresql && sudo chmod -R 777 postgresql
$ if grep -qF “fs.inotify.max_user_watches” /etc/sysctl.conf; then echo $(grep -F “fs.inotify.max_user_watches” /etc/sysctl.conf); else echo “fs.inotify.max_user_watches = 524288” | sudo tee -a /etc/sysctl.conf; fi
$ sudo sysctl -p # apply new config immediately
Then I copied my custom addons to the addons folder
Ex: git clone GitHub - diogocsc/carddecks: Playable cards and decks
Then changed admin password in etc/odoo.conf to my own pwd
And then continued
docker-compose up -d
Oops…docker-compose wasn’t installed after all.
So, installed it: sudo apt install docker-compose
And again:
docker-compose up -d
with this, your server should be up on http://[YOUR-IP]:8069
Do note that the port may be one of your choice, as setup in odoo.conf file in etc folder
Adding https with let’s encrypt
First, ensure your server has its A records setup, pointing to your server’s IP Address.
Following this instructions by letter didn’t work at first, because we were missing the upstream.
Also the https server redirect revealed not necessary.
See annex for both http and https final configurations.
Do note that for https to work, we first need to run certbot as indicated in the link, so the certificates are loaded to our local machine.
Annex
nginx/conf/default.conf file for http requests:
upstream odoo {
server 65.21.245.173:8069;
}
upstream odoochat {
server 65.21.245.173:8072;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
# listen [::]:80;
listen 80;
server_name relationalgames.com;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
# Add Headers for odoo proxy mode
proxy_set_header 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;
# log
access_log /var/log/nginx/odoo.access.log;
error_log /var/log/nginx/odoo.error.log;
# Redirect websocket requests to odoo gevent port
location /websocket {
proxy_pass http://odoochat;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
# Redirect requests to odoo backend server
location / {
proxy_redirect off;
proxy_pass http://odoo;
}
location ~* /web/static/ {
proxy_pass http://odoo;
}
# common gzip
gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript;
gzip on;
}
nginx.conf/default.conf file for https requests:
upstream odoo {
server 65.21.245.173:8069;
}
upstream odoochat {
server 65.21.245.173:8072;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# line below is needed so website edits work properly.
add_header 'Content-Security-Policy' 'upgrade-insecure-requests';
server {
listen [::]:80;
listen 80;
server_name relationalgames.com;
return 301 https://www.relationalgames.com$request_uri;
}
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name relationalgames.com;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
ssl_certificate /etc/nginx/ssl/live/relationalgames.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/relationalgames.com/privkey.pem;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/html;
}
# Add Headers for odoo proxy mode
proxy_set_header 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;
# log
access_log /var/log/nginx/odoo.access.log;
error_log /var/log/nginx/odoo.error.log;
# Redirect websocket requests to odoo gevent port
location /websocket {
proxy_pass http://odoochat;
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;
}
# Redirect requests to odoo backend server
location / {
proxy_pass http://odoo;
}
# common gzip
gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript;
gzip on;
location ~* /web/static/ {
proxy_pass http://odoo;
}
}