From 75533b7e3f504f771383b30e5625d2f352affc39 Mon Sep 17 00:00:00 2001 From: Nj Subedi Date: Fri, 11 Mar 2022 13:00:53 +0545 Subject: [PATCH] init mvp --- .dockerignore | 3 + .gitignore | 6 ++ CloudronManifest.json | 31 +++++++ Dockerfile | 36 ++++++++ LICENSE | 21 +++++ README.md | 26 ++++++ dev-scripts/README.md | 1 + dev-scripts/build-push-install.sh | 11 +++ dev-scripts/docker-run-openldap.sh | 11 +++ dev-scripts/docker-run-postgres.sh | 25 ++++++ dev-scripts/docker-run.sh | 11 +++ dev-scripts/simulate-cloudron.sh | 30 +++++++ manifest/CHANGELOG.md | 2 + manifest/DESCRIPTION.md | 12 +++ manifest/POSTINSTALL.md | 6 ++ manifest/logo.png | Bin 0 -> 7943 bytes nginx.conf | 87 ++++++++++++++++++ odoo.conf.sample | 3 + start.sh | 138 +++++++++++++++++++++++++++++ 19 files changed, 460 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 CloudronManifest.json create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 dev-scripts/README.md create mode 100755 dev-scripts/build-push-install.sh create mode 100755 dev-scripts/docker-run-openldap.sh create mode 100755 dev-scripts/docker-run-postgres.sh create mode 100755 dev-scripts/docker-run.sh create mode 100644 dev-scripts/simulate-cloudron.sh create mode 100644 manifest/CHANGELOG.md create mode 100644 manifest/DESCRIPTION.md create mode 100644 manifest/POSTINSTALL.md create mode 100644 manifest/logo.png create mode 100644 nginx.conf create mode 100644 odoo.conf.sample create mode 100755 start.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..15f5357 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.dockerignore +.docker +dev-scripts/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8383a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.tar.gz +.DS_Store +.env +.docker/ +.idea/ +*.iml \ No newline at end of file diff --git a/CloudronManifest.json b/CloudronManifest.json new file mode 100644 index 0000000..d6b6b36 --- /dev/null +++ b/CloudronManifest.json @@ -0,0 +1,31 @@ +{ + "manifestVersion": 2, + "id": "com.odoo.cloudronapp", + "website": "https://www.odoo.com", + "contactEmail": "support@odoo.com", + "title": "Odoo", + "author": "Odoo authors", + "tagline": "Open Source ERP and CRM", + "version": "15.0", + "icon": "manifest/logo.png", + "description": "file://manifest/DESCRIPTION.md", + "changelog": "file://manifest/CHANGELOG.md", + "postInstallMessage": "file://manifest/POSTINSTALL.md", + "healthCheckPath": "/", + "httpPort": 80, + "memoryLimit": 2684354560, + "addons": { + "localstorage": {}, + "postgresql": {}, + "sendmail": {}, + "ldap": {} + }, + "tags": [ + "auth" + ], + "optionalSso": true, + "mediaLinks": [], + "forumUrl": "https://forum.cloudron.io/", + "documentationUrl": "https://docs.cloudron.io/" +} + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3bc64f4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +FROM cloudron/base:3.2.0@sha256:ba1d566164a67c266782545ea9809dc611c4152e27686fd14060332dd88263ea +# Reference: https://github.com/odoo/docker/blob/master/15.0/Dockerfile + +RUN mkdir -p /app/code /app/pkg /app/data +WORKDIR /app/code + +RUN apt-get update && \ + apt-get install -y \ + python3-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \ + libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev libfreetype6-dev \ + liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev libxcb1-dev libpq-dev + +RUN curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.focal_amd64.deb && \ + echo 'ae4e85641f004a2097621787bf4381e962fb91e1 wkhtmltox.deb' | sha1sum -c - && \ + apt-get install -y --no-install-recommends ./wkhtmltox.deb && \ + rm -f ./wkhtmltox.deb && \ + rm -rf /var/lib/apt/lists/* /var/cache/apt + +RUN npm install -g rtlcss + +# Install Odoo +ENV ODOO_VERSION 15.0 + +RUN curl -L https://github.com/odoo/odoo/archive/refs/heads/$ODOO_VERSION.tar.gz | tar zx --strip-components 1 -C /app/code && \ + pip3 install wheel && \ + pip3 install -r requirements.txt + +RUN rm -rf /var/log/nginx && mkdir /run/nginx && ln -s /run/nginx /var/log/nginx + +# Copy entrypoint script and Odoo configuration file +ADD start.sh odoo.conf.sample nginx.conf /app/pkg/ + +RUN mkdir -p /app/data/odoo/filestore /app/data/odoo/addons && \ + chown -R cloudron:cloudron /app/data + +CMD [ "/app/pkg/start.sh" ] \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4422327 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Nj Subedi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a8b26a --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +## What + +Run [Odoo](https://www.odoo.com/) on [Cloudron](https://cloudron.io). For more information see DESCRIPTION.md + +## Why + +Because Odoo works almost out of the box in any system that has Postgres and some disk space for data storage. + +## Build and Install + +- Install Cloudron CLI on your machine: `npm install -g cloudron-cli`. +- Install Docker, and make sure you can push to docker hub, or install the docker registry app in your own Cloudron. +- Log in to your Cloudron using cloudron cli: `cloudron login `. +- Build and publish the docker image: `cloudron build`. +- If you're using your own docker registry, name the image properly, + like `docker.example-cloudron.tld/john_doe/cloudron-odoo`. +- Log in to Docker Hub and mark the image as public, if necessary. +- Install the app `cloudron install -l ` +- Look at the logs to see if everything is going as planned. + +Refer to the [Cloudron Docs](https://docs.cloudron.io/packaging/cli) for more information. + +## Third-party Intellectual Properties + +All third-party product names, company names, and their logos belong to their respective owners, and may be their +trademarks or registered trademarks. \ No newline at end of file diff --git a/dev-scripts/README.md b/dev-scripts/README.md new file mode 100644 index 0000000..431bd6b --- /dev/null +++ b/dev-scripts/README.md @@ -0,0 +1 @@ +Scripts inside this folder are only used as reference during development, and have no use or effect in the docker image or containers. \ No newline at end of file diff --git a/dev-scripts/build-push-install.sh b/dev-scripts/build-push-install.sh new file mode 100755 index 0000000..e3768b1 --- /dev/null +++ b/dev-scripts/build-push-install.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +VERSION=15.0 +DOMAIN='' +AUTHOR='' + +docker build -t $AUTHOR/cloudron-odoo:$VERSION ./ && docker push $AUTHOR/cloudron-odoo:$VERSION + +cloudron install --image $AUTHOR/cloudron-odoo:$VERSION -l $DOMAIN + +cloudron logs -f --app $DOMAIN diff --git a/dev-scripts/docker-run-openldap.sh b/dev-scripts/docker-run-openldap.sh new file mode 100755 index 0000000..fde6632 --- /dev/null +++ b/dev-scripts/docker-run-openldap.sh @@ -0,0 +1,11 @@ +#!/bin/bash -e + +# Run OpenLDAP & phpLDAPadmin on the network named localnet +# Create a network, if not exists: `docker network create localnet` + +docker run --name ldap-service --hostname ldap-service --network localnet --detach osixia/openldap:1.1.8 +docker run -p 8091:443 --name phpldapadmin-service --hostname phpldapadmin-service --network localnet --env PHPLDAPADMIN_LDAP_HOSTS=ldap-service --detach osixia/phpldapadmin:0.9.0 + +echo "Go to: https://localhost:8091" +echo "Login DN: cn=admin,dc=example,dc=org" +echo "Password: admin" \ No newline at end of file diff --git a/dev-scripts/docker-run-postgres.sh b/dev-scripts/docker-run-postgres.sh new file mode 100755 index 0000000..169997d --- /dev/null +++ b/dev-scripts/docker-run-postgres.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# Run `postgres` container named `postgres` in docker network `localnet` +# Create a network, if not exists: `docker network create localnet` + +docker run --name postgres -d -p 5432:5432 --network localnet \ + -e POSTGRES_USER=odoo_user \ + -e POSTGRES_PASSWORD=odoo_password \ + -e POSTGRES_DB=odoo \ + postgres:latest + +# Login to pg cli +PGPASSWORD=postgres psql -h 127.0.0.1 -U postgres -p 5432 + +# Create user called 'odoo_user' +CREATE ROLE odoo_user with LOGIN +\password odoo_user +# Enter a password, such as: odoo_password, which is an extremely bad password btw. + +# Recreate database quickly. +drop database odoo; +create database odoo with encoding 'utf-8' owner odoo_user; + +# Try logging in as odoo_user +PGPASSWORD=odoo_password psql -h 172.17.0.1 -p 5432 -U odoo_user -d odoo diff --git a/dev-scripts/docker-run.sh b/dev-scripts/docker-run.sh new file mode 100755 index 0000000..c320a25 --- /dev/null +++ b/dev-scripts/docker-run.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +docker rm -f odoo_container && rm -rf ./.docker/* && mkdir -p ./.docker/run/nginx ./.docker/run/odoo ./.docker/app/data ./.docker/tmp && \ +BUILDKIT_PROGRESS=plain docker build -t odoo_custom . && docker run --read-only \ + -v "$(pwd)"/.docker/app/data:/app/data:rw \ + -v "$(pwd)"/.docker/tmp:/tmp:rw \ + -v "$(pwd)"/.docker/run:/run:rw \ + -p 8000:8000 \ + --network localnet \ + --name odoo_container \ + odoo_custom diff --git a/dev-scripts/simulate-cloudron.sh b/dev-scripts/simulate-cloudron.sh new file mode 100644 index 0000000..e364ea8 --- /dev/null +++ b/dev-scripts/simulate-cloudron.sh @@ -0,0 +1,30 @@ +if [[ -z "${CLOUDRON+x}" ]]; then + echo "Not Cloudron. Setting testing vars..." + export CLOUDRON_POSTGRESQL_PORT=5432 + export CLOUDRON_POSTGRESQL_HOST=172.17.0.1 + export CLOUDRON_POSTGRESQL_DATABASE=odoo + export CLOUDRON_POSTGRESQL_USERNAME=odoo_user + export CLOUDRON_POSTGRESQL_PASSWORD=odoo_password + + export CLOUDRON_APP_DOMAIN=odoo.localhost + export CLOUDRON_APP_ORIGIN=https://odoo.localhost + + export CLOUDRON_MAIL_SMTP_SERVER='localhost' + export CLOUDRON_MAIL_SMTP_PORT='25' + export CLOUDRON_MAIL_SMTP_USERNAME='username' + export CLOUDRON_MAIL_SMTP_PASSWORD='password' + export CLOUDRON_MAIL_FROM='from@localhost' + + export CLOUDRON_MAIL_IMAP_SERVER='localhost' + export CLOUDRON_MAIL_IMAP_PORT='25' + export CLOUDRON_MAIL_IMAP_USERNAME='username' + export CLOUDRON_MAIL_IMAP_PASSWORD='password' + + export CLOUDRON_LDAP_SERVER='172.18.0.1' + export CLOUDRON_LDAP_PORT='3002' + export CLOUDRON_LDAP_URL='ldap://172.18.0.1:3002' + export CLOUDRON_LDAP_USERS_BASE_DN='ou=users,dc=cloudron' + export CLOUDRON_LDAP_GROUPS_BASE_DN='ou=groups,dc=cloudron' + export CLOUDRON_LDAP_BIND_DN='cn=app_id,ou=apps,dc=cloudron' + export CLOUDRON_LDAP_BIND_PASSWORD='example_bind_password' +fi diff --git a/manifest/CHANGELOG.md b/manifest/CHANGELOG.md new file mode 100644 index 0000000..f105c10 --- /dev/null +++ b/manifest/CHANGELOG.md @@ -0,0 +1,2 @@ +v15.0 +First release of Odoo 15.0. diff --git a/manifest/DESCRIPTION.md b/manifest/DESCRIPTION.md new file mode 100644 index 0000000..267617d --- /dev/null +++ b/manifest/DESCRIPTION.md @@ -0,0 +1,12 @@ +Run Odoo on Cloudron. + +Features +--- + +- Uses Cloudron LDAP for user federation +- Uses Cloudron SMTP for sending emails +- Uses Cloudron IMAP for incoming emails +- Hardened to disable database selection, debug mode, etc. +- Supports custom addons installed at `/app/data/extra-addons` +- Supports customization using `/app/data/odoo.conf` +- Supports long-polling actions like chat using custom `/run/nginx/nginx.conf` file \ No newline at end of file diff --git a/manifest/POSTINSTALL.md b/manifest/POSTINSTALL.md new file mode 100644 index 0000000..3b0870d --- /dev/null +++ b/manifest/POSTINSTALL.md @@ -0,0 +1,6 @@ +Log in with the default credentials and change your password immediately by clicking on the profile +(**Administrator**) button in the top right corner of the screen. + +Email : `admin` + +Password: `admin` diff --git a/manifest/logo.png b/manifest/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..36e5bfa78ff7b68d74225d22ceebe8a975846f57 GIT binary patch literal 7943 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 literal 0 HcmV?d00001 diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..45a9663 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,87 @@ +# Based on https://git.cloudron.io/cloudron/taiga-app/-/raw/master/nginx.conf +daemon off; +worker_processes auto; +pid /run/nginx/nginx.pid; +error_log stderr; + +events { + worker_connections 768; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + client_body_temp_path /run/nginx/client_body; + proxy_temp_path /run/nginx/proxy_temp; + fastcgi_temp_path /run/nginx/fastcgi_temp; + scgi_temp_path /run/nginx/scgi_temp; + uwsgi_temp_path /run/nginx/uwsgi_temp; + + ## + # Logging Settings + ## + + access_log /dev/stdout; + + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + ## + # Virtual Host Configs + ## + + #odoo server + upstream odoo { + server 127.0.0.1:8069; + } + upstream odoo-lp { + server 127.0.0.1:8072; + } + + server { + listen 8000; + + server_name __REPLACE_WITH_CLOUDRON_APP_DOMAIN__; + proxy_read_timeout 720s; + proxy_connect_timeout 720s; + proxy_send_timeout 720s; + + large_client_header_buffers 4 32k; + client_max_body_size 50M; + charset utf-8; + + # Add Headers for odoo proxy mode + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + + # Redirect longpoll requests to odoo longpolling port + location /longpolling { + proxy_pass http://odoo-lp; + } + + # Redirect requests to odoo backend server + location / { + proxy_redirect off; + proxy_pass http://odoo; + } + + # common gzip + gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript; + gzip on; + } +} \ No newline at end of file diff --git a/odoo.conf.sample b/odoo.conf.sample new file mode 100644 index 0000000..a2dfd95 --- /dev/null +++ b/odoo.conf.sample @@ -0,0 +1,3 @@ +[options] +addons_path = /app/code/addons,/app/data/extra-addons +data_dir = /app/data/odoo \ No newline at end of file diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..c8b4214 --- /dev/null +++ b/start.sh @@ -0,0 +1,138 @@ +#!/bin/bash +set -eu pipefail + +export LANG="C.UTF-8" +export ODOO_RC="/app/data/odoo.conf" + +pg_cli() { + PGPASSWORD=$CLOUDRON_POSTGRESQL_PASSWORD psql \ + -h $CLOUDRON_POSTGRESQL_HOST \ + -p $CLOUDRON_POSTGRESQL_PORT \ + -U $CLOUDRON_POSTGRESQL_USERNAME \ + -d $CLOUDRON_POSTGRESQL_DATABASE -c "$1" +} + +# Create required directories if they don't exist +mkdir -p /app/data/extra-addons /app/data/odoo /run/odoo /run/nginx +chown -R cloudron:cloudron /run + +# Check for First Run +if [[ ! -f /app/data/odoo.conf ]]; then + echo "First run. Initializing DB..." + + # Initialize the database, and exit. + /usr/local/bin/gosu cloudron:cloudron /app/code/odoo-bin -i base,auth_ldap,fetchmail --without-demo all --data-dir /app/data/odoo --logfile /run/odoo/runtime.log -d $CLOUDRON_POSTGRESQL_DATABASE --db_host $CLOUDRON_POSTGRESQL_HOST --db_user $CLOUDRON_POSTGRESQL_USERNAME --db_pass $CLOUDRON_POSTGRESQL_PASSWORD --stop-after-init + + echo "Initialized successfully." + + echo "Copying default configuration file to /app/data/odoo.conf..." + cp /app/pkg/odoo.conf.sample /app/data/odoo.conf + + echo "Adding required tables/relations for mail settings." + pg_cli "INSERT INTO public.res_config_settings (create_uid, create_date, write_uid, write_date, company_id, user_default_rights, external_email_server_default, module_base_import, module_google_calendar, module_microsoft_calendar, module_mail_plugin, module_google_drive, module_google_spreadsheet, module_auth_oauth, module_auth_ldap, module_base_gengo, module_account_inter_company_rules, module_pad, module_voip, module_web_unsplash, module_partner_autocomplete, module_base_geolocalize, module_google_recaptcha, group_multi_currency, show_effect, profiling_enabled_until, module_product_images, unsplash_access_key, fail_counter, alias_domain, restrict_template_rendering, use_twilio_rtc_servers, twilio_account_sid, twilio_account_token, auth_signup_reset_password, auth_signup_uninvited, auth_signup_template_user_id) VALUES (2, 'NOW()', 2, 'NOW()', 1, false, true, true, false, false, false, false, false, false, true, false, false, false, false, true, true, false, false, false, true, NULL, false, NULL, 0, '$CLOUDRON_APP_DOMAIN', false, false, NULL, NULL, false, 'b2c', 5) ON CONFLICT (id) DO NOTHING;" + + pg_cli "INSERT INTO public.ir_config_parameter (key, value, create_uid, create_date, write_uid, write_date) VALUES ('base_setup.default_external_email_server', 'True', 2, 'NOW()', 2, 'NOW()');" + pg_cli "INSERT INTO public.ir_config_parameter (key, value, create_uid, create_date, write_uid, write_date) VALUES ('mail.catchall.domain', '$CLOUDRON_APP_DOMAIN', 2, 'NOW()', 2, 'NOW()');" + + echo "First run complete." +fi + +# These values should be re-set to make Odoo work as expcected. +echo "Ensuring proper [options] in /app/data/odoo.conf ..." + +# Custom paths +crudini --set /app/data/odoo.conf 'options' addons_path "/app/code/addons,/app/data/extra-addons" +crudini --set /app/data/odoo.conf 'options' data_dir "/app/data/odoo" + +# Logging +crudini --set /app/data/odoo.conf 'options' logfile "/run/odoo.log" +crudini --set /app/data/odoo.conf 'options' logrotate 'False' +crudini --set /app/data/odoo.conf 'options' log_db 'False' +crudini --set /app/data/odoo.conf 'options' syslog 'False' + +# Http Server +crudini --set /app/data/odoo.conf 'options' proxy_mode "True" +crudini --set /app/data/odoo.conf 'options' secure 'False' +crudini --set /app/data/odoo.conf 'options' interface '127.0.0.1' +crudini --set /app/data/odoo.conf 'options' port '8069' +crudini --set /app/data/odoo.conf 'options' longpolling_port '8072' + +# Securing Odoo +crudini --set /app/data/odoo.conf 'options' list_db "False" +crudini --set /app/data/odoo.conf 'options' test_enable "False" +crudini --set /app/data/odoo.conf 'options' test_file "False" +crudini --set /app/data/odoo.conf 'options' test_report_directory "False" +crudini --set /app/data/odoo.conf 'options' without_demo "all" +crudini --set /app/data/odoo.conf 'options' debug_mode "False" +#TODO Disable debug mode + +# DB +crudini --set /app/data/odoo.conf 'options' db_host "$CLOUDRON_POSTGRESQL_HOST" +crudini --set /app/data/odoo.conf 'options' db_port "$CLOUDRON_POSTGRESQL_PORT" +crudini --set /app/data/odoo.conf 'options' db_user "$CLOUDRON_POSTGRESQL_USERNAME" +crudini --set /app/data/odoo.conf 'options' db_password "$CLOUDRON_POSTGRESQL_PASSWORD" +crudini --set /app/data/odoo.conf 'options' db_name "$CLOUDRON_POSTGRESQL_DATABASE" +crudini --set /app/data/odoo.conf 'options' db_filter "^$CLOUDRON_POSTGRESQL_DATABASE.*$" +crudini --set /app/data/odoo.conf 'options' db_sslmode 'False' + +# IMAP Configuration +if [[ -z "${CLOUDRON_MAIL_SMTP_SERVER+x}" ]]; then + echo "IMAP is disabled. Removing values from config." + pg_cli "DELETE FROM public.fetchmail_server WHERE id = 1 AND company = 1" +else + echo "IMAP is enabled. Adding values to config." + pg_cli "INSERT INTO public.fetchmail_server (id, name, active, state, server, port, server_type, is_ssl, attach, original, date, \"user\", password, object_id, priority, configuration, script, create_uid, create_date, write_uid, write_date) VALUES (1, 'Cloudron IMAP Service', true, 'done', '$CLOUDRON_MAIL_IMAP_SERVER', $CLOUDRON_MAIL_IMAP_PORT, 'imap', false, true, false, NULL, '$CLOUDRON_MAIL_IMAP_USERNAME', '$CLOUDRON_MAIL_IMAP_PASSWORD', 151, 5, NULL, '/mail/static/scripts/odoo-mailgate.py', 2, 'NOW()', 2, 'NOW()') ON CONFLICT (id) DO NOTHING;" +fi + +# SMTP Configuration +if [[ -z "${CLOUDRON_MAIL_SMTP_SERVER+x}" ]]; then + echo "SMTP is disabled. Removing values from config." + pg_cli "DELETE FROM public.ir_mail_server WHERE id = 1 AND company = 1" +else + echo "SMTP is enabled. Adding values to config." + pg_cli "INSERT INTO public.ir_mail_server (id, name, from_filter, smtp_host, smtp_port, smtp_authentication, smtp_user, smtp_pass, smtp_encryption, smtp_ssl_certificate, smtp_ssl_private_key, smtp_debug, sequence, active, create_uid, create_date, write_uid, write_date) VALUES (1, 'Cloudron SMTP Service', NULL, '$CLOUDRON_MAIL_SMTP_SERVER', $CLOUDRON_MAIL_SMTP_PORT, 'login', '$CLOUDRON_MAIL_SMTP_USERNAME', '$CLOUDRON_MAIL_SMTP_PASSWORD', 'none', NULL, NULL, false, 10, true, 2, 'NOW()', 2, 'NOW()') ON CONFLICT (id) DO NOTHING;" + +fi + +# LDAP Configuration +if [[ -z "${CLOUDRON_LDAP_SERVER+x}" ]]; then + echo "LDAP is disabled. Removing values from config." + pg_cli "DELETE FROM public.res_company_ldap WHERE id = 1 AND company = 1" +else + echo "LDAP is enabled. Adding values to config." + pg_cli "INSERT INTO public.res_company_ldap (id, sequence, company, ldap_server, ldap_server_port, ldap_binddn, ldap_password, ldap_filter, ldap_base, \"user\", create_user, ldap_tls, create_uid, create_date, write_uid, write_date) VALUES (1, 10, 1, '$CLOUDRON_LDAP_SERVER', $CLOUDRON_LDAP_PORT, '$CLOUDRON_LDAP_BIND_DN', '$CLOUDRON_LDAP_BIND_PASSWORD', '(objectclass=user)', '$CLOUDRON_LDAP_USERS_BASE_DN', NULL, true, false, 2, 'NOW()', 2, 'NOW()') ON CONFLICT (id) DO NOTHING;;" +fi + +# Start nginx process +sed -e "s,__REPLACE_WITH_CLOUDRON_APP_DOMAIN__,${CLOUDRON_APP_DOMAIN}," /app/pkg/nginx.conf >/run/nginx/nginx.conf + +chown -R cloudron:cloudron /app/data + +echo "=> Start nginx" +nginx -c /run/nginx/nginx.conf & +# Done nginx + +echo "Resource allocation (hard limit: 100% of available memory; soft limit: 80%)" +if [[ -f /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes ]]; then + memory_limit_hard=$(($(cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes))) + memory_limit_soft=$((memory_limit_hard * 4 / 5)) +else + memory_limit_hard=2684354560 + memory_limit_soft=2147483648 # (memory_limit_hard * 4 / 5) +fi + +worker_count=$((memory_limit_hard / 1024 / 1024 / 150)) # 1 worker for 150M +worker_count=$((worker_count > 8 ? 8 : worker_count)) # max of 8 +worker_count=$((worker_count < 1 ? 1 : worker_count)) # min of 1 + +echo "Memory limits - hard limit: $memory_limit_hard bytes, soft limit: $memory_limit_soft bytes" + +crudini --set /app/data/odoo.conf 'options' limit_memory_hard $memory_limit_hard +crudini --set /app/data/odoo.conf 'options' limit_memory_soft $memory_limit_soft +crudini --set /app/data/odoo.conf 'options' workers $worker_count + +echo "Done. Starting server with $worker_count workers.." + +chown -R cloudron:cloudron /app/data/ + +/usr/local/bin/gosu cloudron:cloudron /app/code/odoo-bin -c /app/data/odoo.conf