Instalasi Odoo pada sistem operasi Linux¶
sudo
Semua proses instalasi menggunakan root atau tambahkan sudo pada awal perintah eksekusi
Persiapan¶
Persyaratan¶
aplikasi & pustaka
dnf install -y \
bzip2-devel freetype-dev gcc git libjpeg-devel libxslt-devel openldap-devel \
python3 python3-devel redhat-rpm-config
Membuat pengguna¶
PENGGUNA_ODOO="odoo13"
DIREKTORI_ODOO="/opt/$PENGGUNA_ODOO"
useradd -m -U -r -d $DIREKTORI_ODOO -s /bin/bash $PENGGUNA_ODOO
Koneksi ke PD¶
Wkhtmltopdf¶
VERSI_WKHTMLTOPDF="0.12.6-1"
REPO_WKHTMLTOPDF="https://github.com/wkhtmltopdf/packaging/releases/download"
DISTRO_ARSITEKTUR="centos8.x86_64.rpm"
dnf install -y $REPO_WKHTMLTOPDF/$VERSI_WKHTMLTOPDF/wkhtmltox-$VERSI_WKHTMLTOPDF.$DISTRO_ARSITEKTUR
Proses¶
Odoo - instalasi¶
PENGGUNA_ODOO="odoo13"
DIREKTORI_ODOO="/opt/$PENGGUNA_ODOO"
VERSI_ODOO="13.0"
sudo -u $PENGGUNA_ODOO git clone https://www.github.com/odoo/odoo --depth 1 --branch $VERSI_ODOO $DIREKTORI_ODOO/odoo
sudo -u $PENGGUNA_ODOO /bin/bash
cd $HOME
python3 -m venv venv
source venv/bin/activate
pip3 install -U pip
pip3 install wheel setuptools
pip3 install -r odoo/requirements.txt
deactivate && exit
sudo -u $PENGGUNA_ODOO mkdir -pv $DIREKTORI_ODOO/custom-addons
Odoo - OCA (Odoo Community Association)¶
OCA
sudo -u $PENGGUNA_ODOO /bin/bash
cd $HOME
source venv/bin/activate
pip3 install -e .
pip3 install odoo-autodiscover
python3 -c "import odoo.api"
export PIP_FIND_LINKS="https://wheelhouse.odoo-community.org/oca-simple"
pip3 search odoo13 | sort $1 | grep odoo13-addon
pip3 install odoo13-addon-web-responsive
deactivate && exit
Odoo - Cybrosys Open HRMS¶
Cybrosys Open HRMS
PENGGUNA_ODOO="odoo13"
DIREKTORI_ODOO="/opt/$PENGGUNA_ODOO"
VERSI_ODOO="13.0"
sudo -u $PENGGUNA_ODOO git clone https://github.com/CybroOdoo/OpenHRMS.git --depth 1 \
--branch $VERSI_ODOO --single-branch $DIREKTORI_ODOO/openhrms
sudo -u $PENGGUNA_ODOO git clone https://github.com/CybroOdoo/CybroAddons.git --depth 1 \
--branch $VERSI_ODOO --single-branch $DIREKTORI_ODOO/CybroAddons
sudo -u $PENGGUNA_ODOO /bin/bash
cd $HOME
source venv/bin/activate
pip3 install pandas
deactivate && exit
systemctl restart $PENGGUNA_ODOO
Odoo - konfigurasi¶
/etc/$PENGGUNA_ODOO.conf
PENGGUNA_ODOO="odoo13"
DIREKTORI_ODOO="/opt/odoo13"
SANDI_ADMIN_PD_ODOO="sandi_admin_pd_odoo"
PD_HOS="10.20.30.1"
PD_PENGGUNA="pd_pengguna"
PD_SANDI="pd_sandi"
BERKAS_LOG="/var/log/odoo/odoo-server.log"
DIREKTORI_DATA="/tmp"
mkdir -pv /var/log/odoo && touch $BERKAS_LOG && chown -Rv $PENGGUNA_ODOO: /var/log/odoo
sudo -u $PENGGUNA_ODOO mkdir -pv $DIREKTORI_ODOO/data
cat << EOF > /etc/$PENGGUNA_ODOO.conf
[options]
# Addons and data locations
addons_path = $DIREKTORI_ODOO/odoo/addons, $DIREKTORI_ODOO/custom-addons, $DIREKTORI_ODOO/venv/lib/python3.6/site-packages/odoo/addons
;csv_internal_sep = ,
data_dir = $DIREKTORI_ODOO/data
;geoip_database = /usr/share/GeoIP/GeoLiteCity.dat
# DB parameters
admin_passwd = $SANDI_ADMIN_PD_ODOO
db_host = $PD_HOS
db_maxconn = 64
db_name = False
db_password = $PD_SANDI
db_port = False
db_template = template1
db_user = $PD_PENGGUNA
;dbfilter = ^%d$
;dbfilter = wow
list_db = True
;pg_path = None
;demo = {}
;import_partial =
# Performance parameters
limit_memory_hard = 4684354560
limit_memory_soft = 4147483648
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
limit_time_real_cron = -1
max_cron_threads = 2
osv_memory_age_limit = 1.0
osv_memory_count_limit = False
workers = 4
# Logs parameters
syslog = False
log_db = True
logrotate = True
log_level = info
log_db_level = warning
log_handler = :INFO
logfile = $BERKAS_LOG
;pidfile = None
reportgz = True
server_wide_modules = web
# Email parameters
;email_from = False
;test_commit = False
;test_enable = False
;test_file = False
;test_report_directory = False
;translate_modules = ['all']
;unaccent = False
;without_demo = False
# Proxy and connectivity
;proxy_mode = True
xmlrpc = True
xmlrpc_interface = 127.0.0.1
xmlrpc_port = 8069
netrpc_interface = 127.0.0.1
longpolling_port = 8072
EOF
Odoo - berkas systemd
¶
/etc/systemd/system/$PENGGUNA_ODOO.service
PENGGUNA_ODOO="odoo13"
DIREKTORI_ODOO="/opt/odoo13"
cat << EOF > /etc/systemd/system/$PENGGUNA_ODOO.service
[Unit]
Description=$PENGGUNA_ODOO
[Service]
Type=simple
SyslogIdentifier=$PENGGUNA_ODOO
PermissionsStartOnly=true
User=$PENGGUNA_ODOO
Group=$PENGGUNA_ODOO
ExecStart=$DIREKTORI_ODOO/venv/bin/python3 $DIREKTORI_ODOO/odoo/odoo-bin -c /etc/$PENGGUNA_ODOO.conf
StandardOutput=journal+console
[Install]
WantedBy=multi-user.target
EOF
#
systemctl daemon-reload
systemctl enable --now $PENGGUNA_ODOO
systemctl status $PENGGUNA_ODOO
journalctl -u $PENGGUNA_ODOO
Penyelesaian¶
Nginx -instalasi¶
Repositori & instalasi
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install yum-utils
tee /etc/yum.repos.d/nginx.repo <<EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
dnf install -y nginx
systemctl enable --now nginx
nginx --version
SELinux - setsebool
setsebool -P httpd_unified 1
# worker_rlimit_nofile and SELinux
setsebool -P httpd_setrlimit 1
setsebool -P httpd_read_user_content 1
setsebool -P httpd_can_network_connect 1
setsebool -P httpd_can_network_connect_db 1
# NGINX listen sockets
semanage fcontext -a -t httpd_var_run_t "/var/run/nginx(/.*)?"
restorecon -v /var/run/nginx.pid
Optimasi Nginx - Soft & Hard limit
cat << EOF >> /etc/security/limits.conf
nginx soft nofile 65535
nginx hard nofile 65535
EOF
SELinux - policy package
DIREKTORI_PENGGUNA="/home/deploy"
POLICY_PACKAGE="nginx-python-odoo"
cd $DIREKTORI_PENGGUNA
cat << EOF > $POLICY_PACKAGE.te
module $POLICY_PACKAGE 1.0;
require {
type httpd_t;
type httpd_config_t;
type httpd_log_t;
type httpd_sys_rw_content_t;
type httpd_sys_script_exec_t;
type httpd_sys_script_t;
type var_t;
type var_run_t;
class dir { add_name remove_name write };
class file { open create read write unlink execute setattr };
}
allow httpd_sys_script_t httpd_sys_rw_content_t:file execute;
allow httpd_t var_t:file read;
allow httpd_t var_run_t:file { open read write unlink };
allow httpd_t httpd_config_t:dir add_name;
allow httpd_t httpd_config_t:file { create write setattr};
allow httpd_t httpd_log_t:dir remove_name;
allow httpd_t httpd_log_t:file { unlink write };
allow httpd_t httpd_sys_script_exec_t:dir { write };
allow httpd_t httpd_sys_script_exec_t:file { setattr write };
EOF
#
semodule -r $POLICY_PACKAGE
rm -f $POLICY_PACKAGE.mod $POLICY_PACKAGE.pp
checkmodule -M -m -o $POLICY_PACKAGE.mod $POLICY_PACKAGE.te
semodule_package -o $POLICY_PACKAGE.pp -m $POLICY_PACKAGE.mod
semodule -i $POLICY_PACKAGE.pp
Nginx - konfigurasi¶
Persiapan Certbot SSL
openssl dhparam -out /etc/nginx/dhparam.pem 2048
mkdir -pv /var/www/_letsencrypt
chown -Rv nginx /var/www/_letsencrypt
semanage fcontext -a -t httpd_sys_content_t "/var/www(/.*)?"
restorecon -rv /var/www
systemctl restart nginx
/etc/nginx/*
cp -v /etc/nginx/nginx.conf{,.`date +%Y%m%d%H%M`}
cat << EOF > /etc/nginx/nginx.conf
user nginx;
pid /run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
multi_accept on;
worker_connections 65536;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
keepalive_timeout 65;
types_hash_max_size 2048;
# MIME
include mime.types;
default_type application/octet-stream;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# Limits
limit_req_log_level warn;
limit_req_zone \$binary_remote_addr zone=login:10m rate=10r/m;
# SSL
# ssl on;
ssl_session_timeout 1d;
# ssl_session_timeout 30m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Diffie-Hellman parameter for DHE ciphersuites
ssl_dhparam /etc/nginx/dhparam.pem;
# Mozilla Intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
# ssl_prefer_server_ciphers on;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
resolver_timeout 2s;
# Load configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
EOF
FQDN_INSTALASI="wow13.proxsis.com"
UPSTREAM="app07-wow13"
cat << EOF > /etc/nginx/conf.d/$FQDN_INSTALASI.conf
# app07-wow13 server
upstream $UPSTREAM {
server 127.0.0.1:8069;
}
upstream $UPSTREAM-chat {
server 127.0.0.1:8072;
}
server {
listen 443 ssl http2;
server_name $FQDN_INSTALASI;
# SSL
ssl_certificate /etc/letsencrypt/live/$FQDN_INSTALASI/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$FQDN_INSTALASI/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/$FQDN_INSTALASI/chain.pem;
# BEGIN SECURITY
#include conf.d/security.conf;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline' 'unsafe-eval' 'unsafe-hashes'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# . files
location ~ /\.(?!well-known) {
deny all;
}
## END SECURITY
# logging
access_log /var/log/nginx/$FQDN_INSTALASI.access.log;
error_log /var/log/nginx/$FQDN_INSTALASI.error.log warn;
## BEGIN PROXY
#include conf.d/proxy.conf
proxy_http_version 1.1;
proxy_cache_bypass \$http_upgrade;
# Add Headers for odoo proxy mode
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_set_header X-Forwarded-Host \$host;
proxy_set_header X-Forwarded-Port \$server_port;
# Proxy timeouts
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
proxy_read_timeout 720s;
# additional proxy parameters
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# increase proxy buffer to handle some OpenERP web requests
proxy_buffers 16 64k;
proxy_buffer_size 128k;
# by default, do not forward anything
proxy_redirect off;
proxy_buffering on;
proxy_max_temp_file_size 0;
# cache some static data in memory for 60mins.
# under heavy load this should relieve stress on the OpenERP web interface a bit.
location ~* /web/static/ {
proxy_pass http://$UPSTREAM;
proxy_buffering on;
proxy_cache_valid 200 60m;
expires 864000;
}
# Specifies the maximum accepted body size of a client request,
# as indicated by the request header Content-Length.
client_max_body_size 512m;
# IP Whitelist
location /web/database/ {
allow 159.89.200.13;
deny all;
proxy_pass http://$UPSTREAM;
}
# location /.well-known/acme-challenge/ {
# proxy_pass http://$UPSTREAM;
# allow all;
# }
# Redirect requests to odoo backend server
location / {
proxy_redirect off;
proxy_pass http://$UPSTREAM;
}
# Redirect longpoll requests to odoo longpolling port
location /longpolling {
proxy_pass http://$UPSTREAM-chat;
}
## END PROXY
## BEGIN GENERAL
# favicon.ico
location = /favicon.ico {
log_not_found off;
access_log off;
}
# robots.txt
location = /robots.txt {
log_not_found off;
access_log off;
}
# common gzip
gzip on;
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
## END GENERAL
}
# subdomains redirect
server {
listen 443 ssl http2;
server_name *.$FQDN_INSTALASI;
# SSL
ssl_certificate /etc/letsencrypt/live/$FQDN_INSTALASI/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$FQDN_INSTALASI/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/$FQDN_INSTALASI/chain.pem;
return 301 https://\$host\$request_uri;
}
# HTTP redirect
server {
listen 80;
server_name .$FQDN_INSTALASI;
# rewrite ^(.*) https://\$host\$1 permanent;
#include conf.d/letsencrypt.conf;
# ACME-challenge
location ^~ /.well-known/acme-challenge/ {
root /var/www/_letsencrypt;
}
location / {
return 301 https://\$host\$request_uri;
}
}
EOF
Sementara menonaktifkan SSL pada konfigurasi $FQDN_INSTALASI
SUREL_LE="[email protected]"
dnf install -y certbot python3-certbot-nginx
sed -i -r 's/(listen .*443)/\1;#/g; s/(ssl_(certificate|certificate_key|trusted_certificate) )/#;#\1/g' /etc/nginx/conf.d/$FQDN_INSTALASI.conf
nginx -t && systemctl reload nginx
Mendapatkan SSL & mengaktifkan kembali konfigurasi SSL
Lakukan perubahan alamat IP sebelum menjalankan perintah untuk mendapatkan sertifikat SSL
certbot certonly --webroot -d $FQDN_INSTALASI --email $SUREL_LE -w /var/www/_letsencrypt \
-n --agree-tos --force-renewal
sed -i -r 's/#?;#//g' /etc/nginx/conf.d/$FQDN_INSTALASI.conf
nginx -t && systemctl reload nginx
Mengatur Certbot agar memuat ulang Nginx saat setelah sukses pembaruan SSL
echo -e '#!/bin/bash\nnginx -t && systemctl reload nginx' | \
tee /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
chmod a+x /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
nginx -t && systemctl reload nginx