Lewati ke isi

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