diff --git a/.env.example b/.env.example
index 08059b8..4270084 100644
--- a/.env.example
+++ b/.env.example
@@ -6,19 +6,30 @@ APP_ENV=local
INIT=
UPDATE=
LOAD=base,web
-WORKERS=2
-DEV_MODE=reload,qweb
+ROOT_PATH=/usr/lib/python3/dist-packages/odoo
+WORKERS=0
+DEV_MODE=reload,xml
DOMAIN=erp.odoocker.test
+ADMIN_PASSWD=odoo
+
+# Services
+PROJECT_NAME=odoocker
+SERVICES=odoo,nginx,proxy,postgres
+
+# Service configuration
+USE_REDIS=false
+USE_S3=false
+USE_SENTRY=false # Currently not working
+USE_PGADMIN=false
# Enterprise
GITHUB_USER=
GITHUB_ACCESS_TOKEN=
# Database
-ADMIN_PASSWD=odoo
DB_HOST=postgres
DB_PORT=5432
-DB_NAME=odoo
+DB_NAME=
DB_USER=odoo
DB_PASSWORD=odoo
LOAD_LANGUAGE=
@@ -26,14 +37,24 @@ LOAD_LANGUAGE=
DB_SSLMODE=prefer
DB_MAXCONN=64
DB_TEMPLATE=unaccent_template
-UNACCENT=True
+UNACCENT=False
LIST_DB=True
DBFILTER=.*
# Logging
-LOG_LEVEL=debug
+LOG_LEVEL=info
# Additional logs
LOG_HANDLER_LEVEL=INFO
+# Sentry
+SENTRY_DSN=
+SENTRY_ENABLED=true
+SENTRY_LOGGING_LEVEL=warn
+SENTRY_EXCLUDE_LOGGERS=
+SENTRY_IGNORE_EXCEPTIONS=
+SENTRY_INCLUDE_CONTEXT=true
+SENTRY_ENVIRONMENT=production
+SENTRY_RELEASE=
+SENTRY_ODOO_DIR=${ROOT_PATH}
# Nginx
CORS_ALLOWED_DOMAIN="'http://external-domain.test'"
@@ -52,24 +73,94 @@ SMTP_PASSWORD=
EMAIL_FROM=
FROM_FILTER=
+# Postgres
+POSTGRES_MAIN_HOST=${DB_HOST}
+POSTGRES_MAIN_PORT=${DB_PORT}
+POSTGRES_MAIN_DB=postgres
+POSTGRES_MAIN_USER=postgres
+POSTGRES_MAIN_PASSWORD=${DB_PASSWORD}
+
+# Redis
+SESSION_REDIS=true
+REDIS_HOST=redis
+REDIS_PORT=6379
+REDIS_PASSWORD=
+REDIS_URL=
+REDIS_PREFIX=${PROJECT_NAME}
+REDIS_SENTINEL_MASTER_NAME=
+REDIS_SENTINEL_HOST=
+REDIS_SENTINEL_PORT=26379
+REDIS_EXPIRATION=604800
+REDIS_EXPIRATION_ANONYMOUS=10800
+
+# Filesystem
+S3_VIRTUAL_HOST=s3.odoocker.test
+S3_API_PORT=9000
+S3_CONSOLE_PORT=9001
+
+AWS_HOST=http://s3:${S3_API_PORT}
+AWS_REGION=
+AWS_ACCESS_KEY_ID=myaccesskey
+AWS_SECRET_ACCESS_KEY=mysecretkey
+AWS_BUCKETNAME=${PROJECT_NAME}-{db}
+
# PgAdmin
PGADMIN_DOMAIN=pgadmin.odoocker.test
-PGADMIN_PASSWORD=odoo
+PGADMING_DB_NAME=pgadmin
+PGADMING_DB_USER=pgadmin
+PGADMIN_DB_PASSWORD=${DB_PASSWORD}
+PGADMIN_DB_HOST="'postgresql://${PGADMING_DB_USER}:${PGADMIN_DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${PGADMING_DB_NAME}'"
+
+PGADMIN_EMAIL=pgadmin@example.com
+PGADMIN_PASSWORD=pgadmin
+
+PGADMIN_SERVERS_JSON=
+PGADMIN_CONFIG_SERVER_MODE=True
#------------------------------#
# Project Configurations #
#------------------------------#
# Docker
-PROJECT_NAME=odoocker
+PROJECT_NAME=${PROJECT_NAME}
SUPPORT_EMAIL=mail@example.com
+# Service configuration
+USE_REDIS=${USE_REDIS}
+USE_S3=${USE_S3}
+USE_SENTRY=${USE_SENTRY}
+USE_PGADMIN=${USE_PGADMIN}
+
+# Which services are going to be brought up
+COMPOSE_PROFILES=${SERVICES}
+
+# Service profiles
+ODOO_PROFILES="odoo"
+POSTGRES_PROFILES="postgres"
+NGINX_PROFILES="nginx"
+NGINX_PROXY_PROFILES="proxy"
+ACME_COMPANION_PROFILES="acme"
+KEYDB_PROFILES="keydb"
+MINIO_PROFILES="minio"
+PGADMIN_PROFILES="pgadmin"
+
# Containers' Tags
ODOO_TAG=13.0
-POSTGRES_TAG=15.4
-NGINX_TAG=1.25.2
-NGINX_PROXY_TAG=1.3.1
-ACME_COMPANION_TAG=2.2.8
-PGADMIN_TAG=7.6
+POSTGRES_TAG=16.1
+KEYDB_TAG=latest
+MINIO_TAG=latest
+NGINX_TAG=1.25.3
+NGINX_PROXY_TAG=1.4.0
+ACME_COMPANION_TAG=2.2.9
+PGADMIN_TAG=8.0
+
+# Odoocker paths
+COMMUNITY_ADDONS=${ROOT_PATH}/addons
+ENTERPRISE_ADDONS=${ROOT_PATH}/enterprise
+THIRD_PARTY_ADDONS=${ROOT_PATH}/third-party-addons
+EXTRA_ADDONS=${ROOT_PATH}/extra-addons
+CUSTOM_ADDONS=${ROOT_PATH}/custom-addons
+LOG_PATH=/var/log/odoo/odoo.log
+DEBUG_PATH=/usr/bin/odoo
#------------#
# Odoo #
@@ -78,22 +169,14 @@ PGADMIN_TAG=7.6
ADMIN_PASSWD=${ADMIN_PASSWD}
CSV_INTERNAL_SEP=,
PUBLISHER_WARRANTY_URL=http://services.openerp.com/publisher-warranty/
-ROOT_PATH=/usr/lib/python3/dist-packages/odoo
+ROOT_PATH=${ROOT_PATH}
REPORTGZ=False
WEBSOCKET_KEEP_ALIVE_TIMEOUT=3600
WEBSOCKET_RATE_LIMIT_BURST=10
WEBSOCKET_RATE_LIMIT_DELAY=0.2
-# Custom paths
-COMMUNITY_ADDONS=${ROOT_PATH}/addons
-ENTERPRISE_ADDONS=${ROOT_PATH}/enterprise
-EXTRA_ADDONS=${ROOT_PATH}/extra-addons
-CUSTOM_ADDONS=${ROOT_PATH}/custom-addons
-LOG_PATH=/var/log/odoo/odoo.log
-DEBUG_PATH=/usr/bin/odoo
-
# Server startup config
-ODOO_RC=/etc/odoo/odoo.conf
+ODOO_RC=${ROOT_PATH}/odoo.conf
SAVE=False
INIT=${INIT}
UPDATE=${UPDATE}
@@ -101,7 +184,7 @@ DEMO=False
WITHOUT_DEMO=all
IMPORT_PARTIAL=False
PIDFILE=
-ADDONS_PATH=${COMMUNITY_ADDONS},${ENTERPRISE_ADDONS},${EXTRA_ADDONS},${CUSTOM_ADDONS}
+ADDONS_PATH=${COMMUNITY_ADDONS},${ENTERPRISE_ADDONS},${THIRD_PARTY_ADDONS},${EXTRA_ADDONS},${CUSTOM_ADDONS}
UPGRADE_PATH=
SERVER_WIDE_MODULES=${LOAD}
DATA_DIR=/var/lib/odoo
@@ -119,21 +202,22 @@ XMLRPCS=True
PROXY_MODE=True
X_SENDFILE=False
-# Testing
+# Testing Group
TEST_FILE=False
TEST_ENABLE=${TEST_ENABLE}
TEST_TAGS=${TEST_TAGS}
SCREENCASTS=None
SCREENSHOTS=/tmp/odoo_tests
-# Logging
+# Logging Group
LOG_LEVEL=${LOG_LEVEL}
LOG_HANDLER=odoo.http.rpc.request:${LOG_HANDLER_LEVEL},odoo.http.rpc.response:${LOG_HANDLER_LEVEL},:${LOG_HANDLER_LEVEL},odoo.sql_db:${LOG_HANDLER_LEVEL}
+LOG_DB=False
LOG_DB_LEVEL=${LOG_LEVEL}
SYSLOG=False
LOGFILE=
-# Email
+# SMTP Group
EMAIL_FROM=${EMAIL_FROM}
FROM_FILTER=${FROM_FILTER}
SMTP_SERVER=${SMTP_SERVER}
@@ -183,6 +267,29 @@ LIMIT_TIME_REAL=480
LIMIT_TIME_REAL_CRON=600
LIMIT_REQUEST=8192
+# Redis
+ODOO_SESSION_REDIS=${SESSION_REDIS}
+ODOO_SESSION_REDIS_HOST=${REDIS_HOST}
+ODOO_SESSION_REDIS_PORT=${REDIS_PORT}
+ODOO_SESSION_REDIS_PASSWORD=${REDIS_PASSWORD}
+ODOO_SESSION_REDIS_URL=${REDIS_URL}
+ODOO_SESSION_REDIS_PREFIX=${REDIS_PREFIX}
+ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME=${REDIS_SENTINEL_MASTER_NAME}
+ODOO_SESSION_REDIS_SENTINEL_HOST=${REDIS_SENTINEL_HOST}
+ODOO_SESSION_REDIS_SENTINEL_PORT=${REDIS_SENTINEL_PORT}
+ODOO_SESSION_REDIS_EXPIRATION=${REDIS_EXPIRATION}
+ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS=${REDIS_EXPIRATION_ANONYMOUS}
+
+# Base Attachment Object Storage
+DISABLE_ATTACHMENT_STORAGE=0
+
+# S3
+AWS_HOST=${AWS_HOST}
+AWS_REGION=${AWS_REGION}
+AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
+AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
+AWS_BUCKETNAME=${AWS_BUCKETNAME}
+
#--------------#
# Docker #
#--------------#
@@ -193,11 +300,11 @@ TEMP_DOCKER_SOCK=/tmp/docker.sock
#----------------#
# Postgres #
#----------------#
-POSTGRES_HOST=${DB_HOST}
-POSTGRES_PORT=${DB_PORT}
-POSTGRES_DB=postgres
-POSTGRES_USER=${DB_USER}
-POSTGRES_PASSWORD=${DB_PASSWORD}
+POSTGRES_HOST=${POSTGRES_MAIN_HOST}
+POSTGRES_PORT=${POSTGRES_MAIN_PORT}
+POSTGRES_DB=${POSTGRES_MAIN_DB}
+POSTGRES_USER=${POSTGRES_MAIN_USER}
+POSTGRES_PASSWORD=${POSTGRES_MAIN_PASSWORD}
PGDATA=/var/lib/postgresql/data/${PROJECT_NAME}
#-------------#
@@ -210,16 +317,6 @@ LETSENCRYPT_HOST=${DOMAIN}
LETSENCRYPT_EMAIL=${SUPPORT_EMAIL}
CORS_ALLOWED_DOMAIN=${CORS_ALLOWED_DOMAIN}
-#-------------#
-# PgAdmin #
-#-------------#
-PGADMIN_DATA=/var/lib/pgadmin
-PGADMIN_VIRTUAL_HOST=${PGADMIN_DOMAIN}
-PGADMIN_DEFAULT_EMAIL=${SUPPORT_EMAIL}
-PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
-PGADMIN_LETSENCRYPT_HOST=${PGADMIN_DOMAIN}
-LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
-
#-------------------#
# Nginx Proxy #
#-------------------#
@@ -234,4 +331,77 @@ CORS_ALLOWED_DOMAIN=${CORS_ALLOWED_DOMAIN}
#----------------------#
# ACME Companion #
#----------------------#
+# For prod use: https://acme-v02.api.letsencrypt.org/directory
+ACME_CA_URI=https://acme-staging-v02.api.letsencrypt.org/directory
+CERTS_UPDATE_INTERVAL=3600
DEFAULT_EMAIL=${SUPPORT_EMAIL}
+
+#-------------#
+# Redis #
+#-------------#
+KEYDB_PORT=${REDIS_PORT}
+KEYDB_DATA=/var/lib/keydb
+
+#-------------#
+# Minio #
+#-------------#
+MINIO_ROOT_USER=${AWS_ACCESS_KEY_ID}
+MINIO_ROOT_PASSWORD=${AWS_SECRET_ACCESS_KEY}
+MINIO_VIRTUAL_HOST=${S3_VIRTUAL_HOST}
+MINIO_BROWSER_REDIRECT_URL=http://${MINIO_VIRTUAL_HOST}
+MINIO_API_PORT=${S3_API_PORT}
+MINIO_CONSOLE_PORT=${S3_CONSOLE_PORT}
+MINIO_DATA=/data
+
+#-------------#
+# PgAdmin #
+#-------------#
+# Volume path
+PGADMIN_DATA=/var/lib/pgadmin
+
+# Nginx Proxy Configuration
+PGADMIN_VIRTUAL_HOST=${PGADMIN_DOMAIN}
+PGADMIN_LETSENCRYPT_HOST=${PGADMIN_DOMAIN}
+PGADMIN_LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
+
+# PgAdmin Configuration
+PGADMIN_CONFIG_APP_NAME="'pgAdmin 4'"
+PGADMIN_CONFIG_SERVER_MODE=${PGADMIN_CONFIG_SERVER_MODE}
+PGADMIN_CONFIG_DEFAULT_SERVER="'127.0.0.1'"
+PGADMIN_CONFIG_DEFAULT_SERVER_PORT=5050
+PGADMIN_CONFIG_MAX_SESSION_IDLE_TIME=120
+PGADMIN_CONFIG_MAX_QUERY_HIST_STORED=20
+# Security Settings
+PGADMIN_CONFIG_PASSWORD_LENGTH_MIN=6
+PGADMIN_CONFIG_ALLOW_SAVE_PASSWORD=True
+PGADMIN_CONFIG_ALLOW_SAVE_TUNNEL_PASSWORD=True
+PGADMIN_CONFIG_MAX_LOGIN_ATTEMPTS=10
+# DB Configuration
+PGADMIN_CONFIG_CONFIG_DATABASE_URI=${PGADMIN_DB_HOST}
+PGADMIN_CONFIG_CONFIG_DATABASE_CONNECTION_POOL_SIZE=5
+# Load Shared Servers Configuration into DB
+PGADMIN_SERVERS_JSON=${PGADMIN_SERVERS_JSON}
+
+# Authentication
+PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
+PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
+
+# PgAdmin SMTP Server
+PGADMIN_CONFIG_MAIL_SERVER="'localhost'"
+PGADMIN_CONFIG_MAIL_PORT=25
+PGADMIN_CONFIG_MAIL_USE_SSL=False
+PGADMIN_CONFIG_MAIL_USE_TLS=False
+PGADMIN_CONFIG_MAIL_USERNAME="''"
+PGADMIN_CONFIG_MAIL_PASSWORD="''"
+PGADMIN_CONFIG_MAIL_DEBUG=False
+PGADMIN_CONFIG_SECURITY_EMAIL_SENDER="'$PGADMIN_DEFAULT_EMAIL'"
+
+# Dynamic PgAdmin Servers (Add as many as you need following copying these variables like {DB1}, {DB2}, DB3)
+PGADMIN_DB1_NAME=Odoocker
+PGADMIN_DB1_HOST=localhost
+PGADMIN_DB1_PORT=5432
+PGADMIN_DB1_MAINTENANCE_DB=odoocker
+PGADMIN_DB1_USERNAME=odoo
+PGADMIN_DB1_TUNNEL_HOST=erp.odoocker.test
+PGADMIN_DB1_TUNNEL_PORT=22
+PGADMIN_DB1_TUNNEL_USERNAME=ubuntu
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 0749d0a..ee4da10 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,6 +1,6 @@
### :rocket: Deployment
- `INIT="my_custom_addon_1"`
-- `ADDONS_TO_UPGRADE="my_custom_addon_2"`
+- `UPDATE="my_custom_addon_2"`
### :jigsaw: Odoo/Asana Tasks
- *Paste Task URL*
diff --git a/.gitignore b/.gitignore
index d65093e..fbfe9ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
# Ignores the main configuration file.
/.env
+# Ignores the pgadmin private key
+pgadmin/private_key
+
# Ignores the docker compose local or production environment.
docker-compose.override.yml
diff --git a/docker-compose.override.local.yml b/docker-compose.override.local.yml
index 6c6c3d8..b5363f4 100644
--- a/docker-compose.override.local.yml
+++ b/docker-compose.override.local.yml
@@ -11,7 +11,7 @@ services:
restart: 'no'
ports:
- 5432:5432
-
+
nginx:
restart: 'no'
@@ -19,3 +19,4 @@ services:
restart: 'no'
ports:
- 80:80
+ - 443:443
diff --git a/docker-compose.override.production.yml b/docker-compose.override.production.yml
index d01c989..81e0e77 100644
--- a/docker-compose.override.production.yml
+++ b/docker-compose.override.production.yml
@@ -3,6 +3,7 @@ services:
restart: unless-stopped
ports:
- 127.0.0.1:8069:8069
+ - 127.0.0.1:8070:8070
- 127.0.0.1:8071:8071
- 127.0.0.1:8072:8072
@@ -11,28 +12,11 @@ services:
ports:
- 127.0.0.1:5432:5432
+ nginx:
+ restart: unless-stopped
+
nginx-proxy:
restart: unless-stopped
ports:
- 80:80
- 443:443
-
- letsencrypt:
- image: nginxproxy/acme-companion:${ACME_COMPANION_TAG}
- depends_on:
- - nginx-proxy
- restart: unless-stopped
- volumes_from:
- - nginx-proxy:rw
- volumes:
- - certs:${NGINX_CERTS}:rw
- - acme:${NGINX_ACME}
- - ${DOCKER_SOCK}:${DOCKER_SOCK}:ro
- environment:
- - DEFAULT_EMAIL
- networks:
- - internal
-
-volumes:
- acme:
- certs:
diff --git a/docker-compose.pgadmin.yml b/docker-compose.pgadmin.yml
deleted file mode 100644
index 2d55e15..0000000
--- a/docker-compose.pgadmin.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-services:
- pgadmin:
- image: dpage/pgadmin4:${PGADMIN_TAG}
- restart: unless-stopped
- expose:
- - 80
- volumes:
- - pgadmin-data:${PGADMIN_DATA}
- environment:
- - PGADMIN_DEFAULT_EMAIL
- - PGADMIN_DEFAULT_PASSWORD
- - VIRTUAL_HOST=${PGADMIN_VIRTUAL_HOST}
- - LETSENCRYPT_HOST=${PGADMIN_LETSENCRYPT_HOST}
- - LETSENCRYPT_EMAIL
- networks:
- - internal
-
-volumes:
- pgadmin-data:
diff --git a/docker-compose.yml b/docker-compose.yml
index 171320c..4151c34 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -10,25 +10,52 @@ services:
- GITHUB_USER
- GITHUB_ACCESS_TOKEN
- ENTERPRISE_ADDONS
+ - THIRD_PARTY_ADDONS
- LOG_PATH
- depends_on:
- - postgres
+ - USE_REDIS
+ - USE_S3
+ - USE_SENTRY
tty: true
volumes:
- - data-dir:${DATA_DIR}
+ - odoo-data:${DATA_DIR}
- ./odoo/extra-addons:${EXTRA_ADDONS}
- ./odoo/custom-addons:${CUSTOM_ADDONS}
- ./odoo/entrypoint.sh:/entrypoint.sh
- - ./odoo/odoorc.sh:/odoorc.sh
- env_file:
- - ./.env
+ environment:
+ - HOST=${DB_HOST}
+ - PORT=${DB_PORT}
+ - USER=${DB_USER}
+ - PASSWORD=${DB_PASSWORD}
+ - ODOO_TAG
+ - ODOO_RC
+ - USE_REDIS
+ - USE_S3
+ - USE_SENTRY
+ - THIRD_PARTY_ADDONS
+ - ODOO_SESSION_REDIS
+ - ODOO_SESSION_REDIS_HOST
+ - ODOO_SESSION_REDIS_PORT
+ - ODOO_SESSION_REDIS_PASSWORD
+ - ODOO_SESSION_REDIS_URL
+ - ODOO_SESSION_REDIS_PREFIX
+ - ODOO_SESSION_REDIS_SENTINEL_MASTER_NAME
+ - ODOO_SESSION_REDIS_SENTINEL_HOST
+ - ODOO_SESSION_REDIS_SENTINEL_PORT
+ - ODOO_SESSION_REDIS_EXPIRATION
+ - ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS
+ - AWS_HOST
+ - AWS_REGION
+ - AWS_ACCESS_KEY_ID
+ - AWS_SECRET_ACCESS_KEY
+ - AWS_BUCKETNAME
networks:
- internal
+ profiles: [$ODOO_PROFILES]
postgres:
build:
- context: ./postgres
- dockerfile: Dockerfile
+ context: ./
+ dockerfile: ./postgres/Dockerfile
args:
- POSTGRES_TAG
restart: unless-stopped
@@ -41,8 +68,15 @@ services:
- POSTGRES_USER
- POSTGRES_PASSWORD
- PGDATA
+ - DB_USER
+ - DB_TEMPLATE
+ - UNACCENT_TEMPLATE
+ - PGADMING_DB_NAME
+ - PGADMING_DB_USER
+ - PGADMIN_DB_PASSWORD
networks:
- internal
+ profiles: [$POSTGRES_PROFILES]
nginx:
image: nginx:${NGINX_TAG}
@@ -62,6 +96,7 @@ services:
- CORS_ALLOWED_DOMAIN
networks:
- internal
+ profiles: [$NGINX_PROFILES]
nginx-proxy:
image: nginxproxy/nginx-proxy:${NGINX_PROXY_TAG}
@@ -72,22 +107,117 @@ services:
volumes:
- ./nginx-proxy/nginx.conf:${NGINX_CONF}
- ./nginx-proxy/cors.conf:${NGINX_PROXY_CORS_CONF}
- - certs:${NGINX_CERTS}:ro
- - vhost:${NGINX_VHOST}
- html:${NGINX_HTML}
+ - vhost:${NGINX_VHOST}
+ - certs:${NGINX_CERTS}:ro
- ${DOCKER_SOCK}:${TEMP_DOCKER_SOCK}:ro
environment:
- TRUST_DOWNSTREAM_PROXY
- CORS_ALLOWED_DOMAIN
networks:
- internal
+ profiles: [$NGINX_PROXY_PROFILES]
+
+ redis:
+ image: eqalpha/keydb:${KEYDB_TAG}
+ platform: linux/amd64
+ ports:
+ - ${KEYDB_PORT}:${KEYDB_PORT}
+ restart: unless-stopped
+ volumes:
+ - redis-data:${KEYDB_DATA}
+ networks:
+ - internal
+ profiles: [$KEYDB_PROFILES]
+
+ s3:
+ image: minio/minio:${MINIO_TAG}
+ environment:
+ - MINIO_ROOT_USER
+ - MINIO_ROOT_PASSWORD
+ - MINIO_BROWSER_REDIRECT_URL
+ - VIRTUAL_HOST=${MINIO_VIRTUAL_HOST}
+ - VIRTUAL_PORT=${MINIO_CONSOLE_PORT}
+ command: server ${MINIO_DATA} --console-address ":${MINIO_CONSOLE_PORT}"
+ volumes:
+ - s3-data:${MINIO_DATA}
+ ports:
+ - ${MINIO_API_PORT}:${MINIO_API_PORT}
+ - ${MINIO_CONSOLE_PORT}:${MINIO_CONSOLE_PORT}
+ networks:
+ - internal
+ profiles: [$MINIO_PROFILES]
+
+ letsencrypt:
+ image: nginxproxy/acme-companion:${ACME_COMPANION_TAG}
+ depends_on:
+ - nginx-proxy
+ restart: unless-stopped
+ volumes_from:
+ - nginx-proxy:rw
+ volumes:
+ - certs:${NGINX_CERTS}:rw
+ - acme:${NGINX_ACME}
+ - ${DOCKER_SOCK}:${DOCKER_SOCK}:ro
+ environment:
+ - ACME_CA_URI
+ - CERTS_UPDATE_INTERVAL
+ - DEFAULT_EMAIL
+ networks:
+ - internal
+ profiles: [$ACME_COMPANION_PROFILES]
+
+ pgadmin:
+ build:
+ context: ./
+ dockerfile: ./pgadmin/Dockerfile
+ args:
+ - PGADMIN_TAG
+ restart: 'no'
+ expose:
+ - 80
+ volumes:
+ - pgadmin-data:${PGADMIN_DATA}
+ environment:
+ - PGADMIN_DEFAULT_EMAIL
+ - PGADMIN_DEFAULT_PASSWORD
+ - VIRTUAL_HOST=${PGADMIN_VIRTUAL_HOST}
+ - LETSENCRYPT_HOST=${PGADMIN_LETSENCRYPT_HOST}
+ - LETSENCRYPT_EMAIL=${PGADMIN_LETSENCRYPT_EMAIL}
+ - PGADMIN_CONFIG_APP_NAME
+ - PGADMIN_CONFIG_CONFIG_DATABASE_CONNECTION_POOL_SIZE
+ - PGADMIN_CONFIG_SERVER_MODE
+ - PGADMIN_CONFIG_DEFAULT_SERVER
+ - PGADMIN_CONFIG_DEFAULT_SERVER_PORT
+ - PGADMIN_CONFIG_PASSWORD_LENGTH_MIN
+ - PGADMIN_CONFIG_MAX_SESSION_IDLE_TIME
+ - PGADMIN_CONFIG_CONFIG_DATABASE_URI
+ - PGADMIN_CONFIG_ALLOW_SAVE_PASSWORD
+ - PGADMIN_CONFIG_MAX_QUERY_HIST_STORED
+ - PGADMIN_CONFIG_MAIL_SERVER
+ - PGADMIN_CONFIG_MAIL_PORT
+ - PGADMIN_CONFIG_MAIL_USE_SSL
+ - PGADMIN_CONFIG_MAIL_USE_TLS
+ - PGADMIN_CONFIG_MAIL_USERNAME
+ - PGADMIN_CONFIG_MAIL_PASSWORD
+ - PGADMIN_CONFIG_MAIL_DEBUG
+ - PGADMIN_CONFIG_SECURITY_EMAIL_SENDER
+ - PGADMIN_CONFIG_ALLOW_SAVE_TUNNEL_PASSWORD
+ - PGADMIN_CONFIG_MAX_LOGIN_ATTEMPTS
+ networks:
+ - internal
+ profiles: [$PGADMIN_PROFILES]
volumes:
- data-dir:
+ odoo-data:
pg-data:
- certs:
- vhost:
+ redis-data:
+ s3-data:
+ pgadmin-data:
html:
+ vhost:
+ certs:
+ acme:
networks:
internal:
diff --git a/nginx-proxy/nginx.conf b/nginx-proxy/nginx.conf
index 08927f5..4d17afa 100644
--- a/nginx-proxy/nginx.conf
+++ b/nginx-proxy/nginx.conf
@@ -5,7 +5,7 @@ error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
- worker_connections 10240;
+ worker_connections 1024;
}
http {
@@ -27,7 +27,7 @@ http {
proxy_read_timeout 900;
send_timeout 900;
- client_max_body_size 1024m;
+ client_max_body_size 2048m;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/cors.conf;
diff --git a/nginx/default.conf b/nginx/default.conf
index 97f5929..424a6be 100644
--- a/nginx/default.conf
+++ b/nginx/default.conf
@@ -4,7 +4,7 @@ map $http_x_cors_allowed_domain $CORS_ALLOWED_DOMAIN {
}
server {
- client_max_body_size 1024m;
+ client_max_body_size 2048m;
proxy_connect_timeout 900;
proxy_send_timeout 900;
@@ -22,11 +22,12 @@ server {
}
location / {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header Host $host;
proxy_pass http://odoo:8069;
+ proxy_redirect off;
+ 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;
# Add CORS headers
add_header 'Access-Control-Allow-Origin' $CORS_ALLOWED_DOMAIN;
@@ -39,19 +40,14 @@ server {
}
}
- location ~* /web/static/ {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header Host $host;
- proxy_pass http://odoo:8069;
- }
-
- location /longpolling {
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header Host $host;
+ location /websocket {
proxy_pass http://odoo:8072;
+ proxy_redirect off;
+ 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;
}
}
diff --git a/odoo/Dockerfile b/odoo/Dockerfile
index 2b7724a..ebeaa6e 100644
--- a/odoo/Dockerfile
+++ b/odoo/Dockerfile
@@ -14,14 +14,22 @@ ARG LOG_PATH
ARG GITHUB_USER
ARG GITHUB_ACCESS_TOKEN
ARG ENTERPRISE_ADDONS
+ARG THIRD_PARTY_ADDONS
ARG ODOO_RC
+ARG USE_REDIS
+ARG USE_S3
+ARG USE_SENTRY
ENV ODOO_TAG=${ODOO_TAG} \
LOG_PATH=${LOG_PATH} \
GITHUB_USER=${GITHUB_USER} \
GITHUB_ACCESS_TOKEN=${GITHUB_ACCESS_TOKEN} \
ENTERPRISE_ADDONS=${ENTERPRISE_ADDONS} \
- ODOO_RC=${ODOO_RC}
+ THIRD_PARTY_ADDONS=${THIRD_PARTY_ADDONS} \
+ ODOO_RC=${ODOO_RC} \
+ USE_REDIS=${USE_REDIS} \
+ USE_S3=${USE_S3} \
+ USE_SENTRY=${USE_SENTRY}
#------------------------#
# APT Dependencies #
@@ -42,6 +50,18 @@ RUN apt-get update && apt-get install -y \
# Clean up the apt cache to reduce the image size
&& rm -rf /var/lib/apt/lists/*
+#---------------------#
+# PIP Dependecies #
+#---------------------#
+# Upgrade pip
+RUN pip3 install --upgrade pip
+
+# Copy & Install PIP requirements
+COPY --chown=odoo:odoo ./odoo/requirements.txt /tmp/requirements.txt
+
+RUN python3 -m pip install -r /tmp/requirements.txt && \
+ rm /tmp/requirements.txt
+
#-----------------------#
# Odoo Enterprise #
#-----------------------#
@@ -55,17 +75,15 @@ RUN if [ -n "$GITHUB_USER" ] && [ -n "$GITHUB_ACCESS_TOKEN" ]; then \
git clone https://${GITHUB_USER}:${GITHUB_ACCESS_TOKEN}@github.com/odoo/enterprise.git ${ENTERPRISE_ADDONS} --depth 1 --branch ${ODOO_TAG} --single-branch --no-tags; \
fi
-#---------------------#
-# PIP Dependecies #
-#---------------------#
-# Upgrade pip
-RUN pip3 install --upgrade pip
+#-------------------------#
+# Odoo Extra Addons #
+#-------------------------#
-# Copy & Install PIP requirements
-COPY --chown=odoo:odoo ./odoo/requirements.txt /tmp/requirements.txt
+RUN mkdir -p ${THIRD_PARTY_ADDONS} && chown odoo:odoo -R ${THIRD_PARTY_ADDONS}
-RUN python3 -m pip install --upgrade -r /tmp/requirements.txt && \
- rm /tmp/requirements.txt
+COPY --chown=odoo:odoo ./odoo/fix-manifest.py /
+COPY --chown=odoo:odoo ./odoo/third-party-addons.sh /
+RUN /third-party-addons.sh && chown odoo:odoo -R ${THIRD_PARTY_ADDONS}
#---------------------#
# Logging #
@@ -80,6 +98,7 @@ RUN touch ${LOG_PATH} && chown odoo:odoo ${LOG_PATH}
# Copy environment variables & script to generate odoo.conf
COPY --chown=odoo:odoo ./.env /
+COPY --chown=odoo:odoo ./odoo/odoo.conf /
COPY --chown=odoo:odoo ./odoo/odoorc.sh /
# Generate odoo.conf
diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.sh
index ff9ccf6..8f04cc2 100755
--- a/odoo/entrypoint.sh
+++ b/odoo/entrypoint.sh
@@ -2,6 +2,34 @@
set -e
+while IFS='=' read -r key value || [[ -n $key ]]; do
+ # Skip comments and empty lines
+ [[ $key =~ ^#.* ]] || [[ -z $key ]] && continue
+
+ # Removing any quotes around the value
+ value=${value%\"}
+ value=${value#\"}
+
+ # Declare variable
+ eval "$key=\"$value\""
+done < .env
+
+# Check the USE_REDIS to add base_attachment_object_storage & session_redis to LOAD variable
+if [[ $USE_REDIS == "true" ]]; then
+ LOAD+=",session_redis"
+fi
+
+# Check the USE_REDIS to add attachment_s3 to LOAD variable
+if [[ $USE_S3 == "true" ]]; then
+ LOAD+=",base_attachment_object_storage"
+ LOAD+=",attachment_s3"
+fi
+
+# Check the USE_REDIS to add sentry to LOAD variable
+if [[ $USE_SENTRY == "true" ]]; then
+ LOAD+=",sentry"
+fi
+
case "$1" in
-- | odoo)
shift
@@ -9,27 +37,20 @@ case "$1" in
# Creates new module.
exec odoo "$@"
else
- wait-for-psql.py --db_host ${DB_HOST} --db_port ${DB_PORT} --db_user ${DB_USER} --db_password ${DB_PASSWORD} --timeout=30
+ wait-for-psql.py --db_host ${HOST} --db_port ${PORT} --db_user ${USER} --db_password ${PASSWORD} --timeout=30
if [ ${APP_ENV} = 'fresh' ] || [ ${APP_ENV} = 'restore' ]; then
# Ideal for a fresh install or restore a production database.
- echo odoo --config ${ODOO_RC} --database= --init= --update= --load=${SERVER_WIDE_MODULES} --log-level=${LOG_LEVEL} --load-language= --workers=0 --limit-time-cpu=3600 --limit-time-real=7200
+ echo odoo --config ${ODOO_RC} --database= --init= --update= --load=${LOAD} --log-level=${LOG_LEVEL} --load-language= --workers=0 --limit-time-cpu=3600 --limit-time-real=7200
exec odoo --config ${ODOO_RC} --database= --init= --update= --load-language= --workers=0 --limit-time-cpu=3600 --limit-time-real=7200
fi
- if [ ${APP_ENV} = 'full' ] ; then
- # Ideal for initializing a fresh database with a huge amount of addons.
- echo odoo --config ${ODOO_RC} --database=${DB_NAME} --init=${INIT} --update= --load=${SERVER_WIDE_MODULES} --log-level=${LOG_LEVEL} --load-language=${LOAD_LANGUAGE} --max-cron-threads=${MAX_CRON_THREADS} --limit-time-cpu=3600 --limit-time-real=7200
-
- exec odoo --config ${ODOO_RC} --update= --workers=0 --limit-time-cpu=3600 --limit-time-real=7200
- fi
-
if [ ${APP_ENV} = 'local' ] ; then
# Listens to all .env variables mapped into odoo.conf file.
- echo odoo --config ${ODOO_RC}
+ echo odoo --config ${ODOO_RC} --database=${DB_NAME} --init=${INIT} --update=${UPDATE} --load=${LOAD} --workers=${WORKERS} --log-level=${LOG_LEVEL} --dev=${DEV_MODE}
- exec odoo --config ${ODOO_RC}
+ exec odoo --config ${ODOO_RC} --init=${INIT} --update=${UPDATE} --dev=${DEV_MODE}
fi
if [ ${APP_ENV} = 'debug' ] ; then
@@ -41,29 +62,29 @@ case "$1" in
if [ ${APP_ENV} = 'testing' ] ; then
# Initializies a fresh 'test_*' database, installs the addons to test, and runs tests you specify in the test tags.
- echo odoo --config ${ODOO_RC} --database=test_${DB_NAME} --test-enable --test-tags ${TEST_TAGS} --init=${ADDONS_TO_TEST} --update=${ADDONS_TO_TEST} --load=${SERVER_WIDE_MODULES} --log-level=${LOG_LEVEL} --without-demo= --workers=0 --stop-after-init
+ echo odoo --config ${ODOO_RC} --database=test_${DB_NAME} --test-enable --test-tags ${TEST_TAGS} --init=${ADDONS_TO_TEST} --update=${ADDONS_TO_TEST} --load=${LOAD} --log-level=${LOG_LEVEL} --without-demo= --workers=0 --dev= --stop-after-init
- exec odoo --config ${ODOO_RC} --database=test_${DB_NAME} --test-enable --test-tags ${TEST_TAGS} --init=${ADDONS_TO_TEST} --update=${ADDONS_TO_TEST} --without-demo= --workers=0 --stop-after-init
+ exec odoo --config ${ODOO_RC} --database=test_${DB_NAME} --test-enable --test-tags ${TEST_TAGS} --init=${ADDONS_TO_TEST} --update=${ADDONS_TO_TEST} --without-demo= --workers=0 --dev= --stop-after-init
fi
if [ ${APP_ENV} = 'staging' ] ; then
# Automagically upgrade all addons and install new ones. Ideal for deployment process.
- echo odoo --config ${ODOO_RC} --database=${DB_NAME} --init=${INIT} --update=all --load=${SERVER_WIDE_MODULES} --log-level=${LOG_LEVEL} --load-language=${LOAD_LANGUAGE} --limit-time-cpu=3600 --limit-time-real=7200
+ echo odoo --config ${ODOO_RC} --database=${DB_NAME} --init=${INIT} --update=all --load=${LOAD} --log-level=${LOG_LEVEL} --load-language=${LOAD_LANGUAGE} --limit-time-cpu=3600 --limit-time-real=7200 --dev=
- exec odoo --config ${ODOO_RC} --update=all --without-demo=all --workers=0 --limit-time-cpu=3600 --limit-time-real=7200
+ exec odoo --config ${ODOO_RC} --update=all --without-demo=all --workers=0 --limit-time-cpu=3600 --limit-time-real=7200 --dev=
fi
if [ ${APP_ENV} = 'production' ] ; then
# Bring up Odoo ready for production.
- echo odoo --config ${ODOO_RC} --database= --init= --update= --load=${SERVER_WIDE_MODULES} --workers=${WORKERS} --log-level=${LOG_LEVEL} --load-language= --without-demo=all --dev=
+ echo odoo --config ${ODOO_RC} --database=${DB_NAME} --init=${INIT} --update=${UPDATE} --load=${LOAD} --workers=${WORKERS} --log-level=${LOG_LEVEL} --without-demo=${WITHOUT_DEMO} --load-language= --dev=
- exec odoo --config ${ODOO_RC} --database= --init= --update= --load-language= --without-demo=all --dev=
+ exec odoo --config ${ODOO_RC} --init=${INIT} --update=${UPDATE} --load-language= --dev=
fi
fi
;;
-*)
- wait-for-psql.py --db_host ${DB_HOST} --db_port ${DB_PORT} --db_user ${DB_USER} --db_password ${DB_PASSWORD} --timeout=30
+ wait-for-psql.py --db_host ${HOST} --db_port ${PORT} --db_user ${USER} --db_password ${PASSWORD} --timeout=30
echo odoo --config ${ODOO_RC}
exec odoo --config ${ODOO_RC}
;;
diff --git a/odoo/extra-addons/report_url/__manifest__.py b/odoo/extra-addons/odoocker_base/__manifest__.py
similarity index 67%
rename from odoo/extra-addons/report_url/__manifest__.py
rename to odoo/extra-addons/odoocker_base/__manifest__.py
index 061038e..4628660 100644
--- a/odoo/extra-addons/report_url/__manifest__.py
+++ b/odoo/extra-addons/odoocker_base/__manifest__.py
@@ -1,8 +1,8 @@
{
- 'name': 'Report URL',
- 'summary': 'Adds Report URL to Odoo Container',
+ 'name': 'Odoocker Base',
+ 'summary': 'Supercharge Odoo with Odoocker',
'description': '''
- Odoo Containers doesn't come with report.url param out of the box, so we add it for you to work with Odoocker.
+ Some Odoocker dependencies require to some custom values that we cover with this Addon for you.
''',
'version': '1.0.0',
'category': 'Technical',
diff --git a/odoo/extra-addons/report_url/data/ir_config_parameter.xml b/odoo/extra-addons/odoocker_base/data/ir_config_parameter.xml
similarity index 56%
rename from odoo/extra-addons/report_url/data/ir_config_parameter.xml
rename to odoo/extra-addons/odoocker_base/data/ir_config_parameter.xml
index 9e9fb65..5032b76 100644
--- a/odoo/extra-addons/report_url/data/ir_config_parameter.xml
+++ b/odoo/extra-addons/odoocker_base/data/ir_config_parameter.xml
@@ -5,4 +5,10 @@
report.url
http://127.0.0.1:8069
+
+
+
+ ir_attachment.location
+ s3
+
diff --git a/odoo/fix-manifest.py b/odoo/fix-manifest.py
new file mode 100644
index 0000000..5075e79
--- /dev/null
+++ b/odoo/fix-manifest.py
@@ -0,0 +1,34 @@
+import sys
+
+# Define the path to the manifest file
+manifest_file_path = sys.argv[1]
+
+# Read the file content
+with open(manifest_file_path, 'r') as file:
+ lines = file.readlines()
+
+# Find the start and end index of the manifest dictionary
+start_index = next(i for i, line in enumerate(lines) if line.strip().startswith('{'))
+end_index = next(i for i, line in enumerate(lines) if line.strip().endswith('}'))
+
+# Construct and evaluate the manifest dictionary
+manifest_dict = eval(''.join(lines[start_index:end_index + 1]))
+
+# Modify the manifest dictionary
+manifest_dict['installable'] = True
+manifest_dict['auto_install'] = True
+
+# Construct the modified manifest string
+modified_manifest_lines = ['{\n']
+for key, value in manifest_dict.items():
+ modified_manifest_lines.append(f" '{key}': {repr(value)},\n")
+modified_manifest_lines.append('}\n')
+
+# Replace the manifest dictionary string in the content
+lines[start_index:end_index + 1] = modified_manifest_lines
+
+# Write the modified content back to the file
+with open(manifest_file_path, 'w') as file:
+ file.writelines(lines)
+
+print(f"Modified {manifest_file_path}")
diff --git a/odoo/__manifest__.example.py b/odoo/manifest.example.py
similarity index 91%
rename from odoo/__manifest__.example.py
rename to odoo/manifest.example.py
index d514518..edc1080 100644
--- a/odoo/__manifest__.example.py
+++ b/odoo/manifest.example.py
@@ -48,6 +48,11 @@
# ... other qweb templates
],
'assets': {
+ 'web.assets_frontend': [
+ 'module_name/static/src/js/file.js',
+ 'module_name/static/src/css/style.css'
+ # ... other assets
+ ],
'web.assets_backend': [
'module_name/static/src/js/file.js',
'module_name/static/src/css/style.css'
diff --git a/odoo/odoo.conf b/odoo/odoo.conf
new file mode 100644
index 0000000..c285553
--- /dev/null
+++ b/odoo/odoo.conf
@@ -0,0 +1,326 @@
+[options]
+;------------------------------------------;
+; Options not exposed on the command line. ;
+;------------------------------------------;
+
+admin_passwd = ${ADMIN_PASSWD}
+csv_internal_sep = ${CSV_INTERNAL_SEP}
+publisher_warranty_url = ${PUBLISHER_WARRANTY_URL}
+root_path = ${ROOT_PATH}
+reportgz = ${REPORTGZ}
+websocket_keep_alive_timeout = ${WEBSOCKET_KEEP_ALIVE_TIMEOUT}
+websocket_rate_limit_burst = ${WEBSOCKET_RATE_LIMIT_BURST}
+websocket_rate_limit_delay = ${WEBSOCKET_RATE_LIMIT_DELAY}
+
+;-----------------------;
+; Server startup config ;
+;-----------------------;
+; --config | -c
+config = ${ODOO_RC}
+
+; --save
+save = ${SAVE}
+
+; --init | -i
+init = ${INIT}
+
+; --update | -u
+update = ${UPDATE}
+
+; --without-demo
+demo = ${DEMO}
+without_demo = ${WITHOUT_DEMO}
+
+; --import-partial
+import_partial = ${IMPORT_PARTIAL}
+
+; --pidfile
+pidfile = ${PIDFILE}
+
+; --addons-path
+addons_path = ${ADDONS_PATH}
+
+; --upgrade-path
+upgrade_path = ${UPGRADE_PATH}
+
+; --load
+server_wide_modules = ${LOAD}
+
+; --data-dir
+data_dir = ${DATA_DIR}
+
+;------;
+; HTTP ;
+;------;
+; --http-interface | --xmlrpc-interface
+http_interface = ${HTTP_INTERFACE}
+
+; --http-port | -p | --xmlrpc-port
+http_port = ${HTTP_PORT}
+
+; --xmlrpcs-interface
+xmlrpcs_interface = ${XMLRPCS_INTERFACE}
+
+; --xmlrpcs-port
+xmlrpcs_port = ${XMLRPCS_PORT}
+
+; --longpolling-port
+longpolling_port = ${LONGPOLLING_PORT}
+
+; --no-http | --no-xmlrpc
+http_enable = ${HTTP_ENABLE}
+
+; --no-xmlrpcs
+xmlrpcs = ${XMLRPCS}
+
+; --proxy-mode
+proxy_mode = ${PROXY_MODE}
+
+; --x-sendfile
+x_sendfile = ${X_SENDFILE}
+
+;---------------;
+; Testing Group ;
+;---------------;
+; --test-file
+test_file = ${TEST_FILE}
+
+; --test-enable
+test_enable = ${TEST_ENABLE}
+
+; --test-tags
+test_tags = ${TEST_FILE}
+
+; --screencasts
+screencasts = ${SCREENCASTS}
+
+; --screenshots
+screenshots = ${SCREENSHOTS}
+
+;---------------;
+; Logging Group ;
+;---------------;
+; --logfile
+logfile = ${LOGFILE}
+
+; --syslog
+syslog = ${SYSLOG}
+
+; --log-handler | --log-web (--log-handler=odoo.http:DEBUG) | --log-sql (--log-handler=odoo.sql_db:DEBUG)
+log_handler = ${LOG_HANDLER}
+
+; --log-db
+log_db = ${LOG_DB}
+
+; --log-db-level
+log_db_level = ${LOG_DB_LEVEL}
+
+; --log-level
+log_level = ${LOG_LEVEL}
+
+;------------;
+; SMTP Group ;
+;------------;
+; --email-from
+email_from = ${EMAIL_FROM}
+
+; --from-filter
+from_filter = ${FROM_FILTER}
+
+; --smtp
+smtp_server = ${SMTP_SERVER}
+
+; --smtp-port
+smtp_port = ${SMTP_PORT}
+
+; --smtp-ssl
+smtp_ssl = ${SMTP_SSL}
+
+; --smtp-user
+smtp_user = ${SMTP_USER}
+
+; --smtp-password
+smtp_password = ${SMTP_PASSWORD}
+
+; --smtp-ssl-certificate-filename
+smtp_ssl_certificate_filename = ${SMTP_SSL_CERTIFICATE_FILENAME}
+
+; --smtp-ssl-private-key-filename
+smtp_ssl_private_key_filename = ${SMTP_SSL_PRIVATE_KEY_FILENAME}
+
+;----------;
+; DB Group ;
+;----------;
+; --database | -d
+db_name = ${DB_NAME}
+
+; --db_user | -r
+db_user = ${DB_USER}
+
+; --db_password | -w
+db_password = ${DB_PASSWORD}
+
+; --pg_path
+pg_path = ${PG_PATH}
+
+; --db_host
+db_host = ${DB_HOST}
+
+; --db_port
+db_port = ${DB_PORT}
+
+; --db_sslmode
+db_sslmode = ${DB_SSLMODE}
+
+; --db_maxconn
+db_maxconn = ${DB_MAXCONN}
+
+; --db-template
+db_template = ${DB_TEMPLATE}
+
+;------------------------------;
+; Internationalisation options ;
+;------------------------------;
+; --load-language
+load_language = ${LOAD_LANGUAGE}
+
+; --language
+language = ${LANGUAGE}
+
+; --i18n-export
+translate_out = ${TRANSLATE_OUT}
+
+; --i18n-import
+translate_in = ${TRANSLATE_IN}
+
+; --i18n-overwrite
+overwrite_existing_translations = ${OVERWRITE_EXISTING_TRANSLATIONS}
+
+; --modules
+translate_modules = ${TRANSLATE_MODULES}
+
+;----------;
+; Security ;
+;----------;
+; --no-database-list
+list_db = ${LIST_DB}
+
+;-----;
+; WEB ;
+;-----;
+; --db-filter
+dbfilter = ${DBFILTER}
+
+;------------------;
+; Advanced options ;
+;------------------;
+; --dev (all, reload, xml, qweb, werkzeug, sql, shell, assets, tests)
+dev_mode = ${DEV_MODE}
+
+; --shell-interface
+shell_interface = ${SHELL_INTERFACE}
+
+; --stop-after-init
+stop_after_init = ${STOP_AFTER_INIT}
+
+; --osv-memory-count-limit
+osv_memory_count_limit = ${OSV_MEMORY_COUNT_LIMIT}
+
+; --transient-age-limit | --osv-memory-age-limit (deprecated)
+transient_age_limit = ${TRANSIENT_AGE_LIMIT}
+
+; --max-cron-threads
+max_cron_threads = ${MAX_CRON_THREADS}
+
+; --unaccent
+unaccent = ${UNACCENT}
+
+; --geoip-db
+geoip_database = ${GEOIP_DATABASE}
+
+; --workers
+workers = ${WORKERS}
+
+; --limit-memory-soft
+limit_memory_soft = ${LIMIT_MEMORY_SOFT}
+
+; --limit-memory-hard
+limit_memory_hard = ${LIMIT_MEMORY_HARD}
+
+; --limit-time-cpu
+limit_time_cpu = ${LIMIT_TIME_CPU}
+
+; --limit-time-real
+limit_time_real = ${LIMIT_TIME_REAL}
+
+; --limit-time-real-cron
+limit_time_real_cron = ${LIMIT_TIME_REAL_CRON}
+
+; --limit-request
+limit_request = ${LIMIT_REQUEST}
+
+;-----------------------------;
+; External Integrations ;
+;-----------------------------;
+
+;--------------;
+; Sentry ;
+;--------------;
+sentry_dsn = ${SENTRY_DSN}
+sentry_enabled = ${SENTRY_ENABLED}
+sentry_logging_level = ${SENTRY_LOGGING_LEVEL}
+sentry_exclude_loggers = ${SENTRY_EXCLUDE_LOGGERS}
+sentry_ignore_exceptions = ${SENTRY_IGNORE_EXCEPTIONS}
+sentry_include_context = ${SENTRY_INCLUDE_CONTEXT}
+sentry_environment = ${SENTRY_ENVIRONMENT}
+sentry_release = ${SENTRY_RELEASE}
+sentry_odoo_dir = ${SENTRY_ODOO_DIR}
+
+;-------------;
+; Redis ;
+;-------------;
+; -- Possible values: 1 or true
+ODOO_SESSION_REDIS = ${ODOO_SESSION_REDIS}
+
+; -- Defaults to is localhost
+ODOO_SESSION_REDIS_HOST = ${ODOO_SESSION_REDIS_HOST}
+
+; -- Defaults to 6379
+ODOO_SESSION_REDIS_PORT = ${ODOO_SESSION_REDIS_PORT}
+
+; -- Sets the password for the AUTH command (optional)
+ODOO_SESSION_REDIS_PASSWORD = ${ODOO_SESSION_REDIS_PASSWORD}
+
+; -- Alternative way to define the Redis server address like rediss:// protocol.
+ODOO_SESSION_REDIS_URL = ${ODOO_SESSION_REDIS_URL}
+
+; -- Prefix for the session keys (optional)
+ODOO_SESSION_REDIS_PREFIX = ${ODOO_SESSION_REDIS_PREFIX}
+
+; -- Time in seconds before expiration of the sessions (default is 7 days)
+ODOO_SESSION_REDIS_EXPIRATION = ${ODOO_SESSION_REDIS_EXPIRATION}
+
+; -- Time in seconds before expiration of the anonymous sessions (default is 3 hours)
+ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS = ${ODOO_SESSION_REDIS_EXPIRATION_ANONYMOUS}
+
+;--------------------------------------;
+; Base Attachment Object Storage ;
+;--------------------------------------;
+; -- Disable Attachment Object Storage
+DISABLE_ATTACHMENT_STORAGE = ${DISABLE_ATTACHMENT_STORAGE}
+
+;----------;
+; S3 ;
+;----------;
+; -- Not required if using AWS S3
+AWS_HOST = ${AWS_HOST}
+
+; -- Required if using AWS services
+AWS_REGION = ${AWS_REGION}
+
+; -- AWS Authentication
+AWS_ACCESS_KEY_ID = ${AWS_ACCESS_KEY_ID}
+AWS_SECRET_ACCESS_KEY = ${AWS_SECRET_ACCESS_KEY}
+
+; Optional db_name placeholder
+AWS_BUCKETNAME = ${AWS_BUCKETNAME}
diff --git a/odoo/odoo.example.conf b/odoo/odoo.example.conf
deleted file mode 100644
index 84e2820..0000000
--- a/odoo/odoo.example.conf
+++ /dev/null
@@ -1,260 +0,0 @@
-[options]
-;------------------------------------------;
-; Options not exposed on the command line. ;
-;------------------------------------------;
-
-admin_passwd = {ADMIN_PASSWD}
-csv_internal_sep = {CSV_INTERNAL_SEP}
-publisher_warranty_url = {PUBLISHER_WARRANTY_URL}
-root_path = {ROOT_PATH}
-reportgz = {REPORTGZ}
-websocket_keep_alive_timeout = {WEBSOCKET_KEEP_ALIVE_TIMEOUT}
-websocket_rate_limit_burst = {WEBSOCKET_RATE_LIMIT_BURST}
-websocket_rate_limit_delay = {WEBSOCKET_RATE_LIMIT_DELAY}
-
-;-----------------------;
-; Server startup config ;
-;-----------------------;
-; --config | -c
-config = {ODOO_RC}
-
-; --save
-save = {SAVE}
-
-; --init | -i
-init = {INIT}
-
-; --update | -u
-update = {UPDATE}
-
-; --without-demo
-demo = {DEMO}
-without_demo = {WITHOUT_DEMO}
-
-; --import-partial
-import_partial = {IMPORT_PARTIAL}
-
-; --pidfile
-pidfile = {PIDFILE}
-
-; --addons-path
-addons_path = {ADDONS_PATH}
-
-; --upgrade-path
-upgrade_path = {UPGRADE_PATH}
-
-; --load
-server_wide_modules = {SERVER_WIDE_MODULES}
-
-; --data-dir
-data_dir = {DATA_DIR}
-
-;------;
-; HTTP ;
-;------;
-; --http-interface | --xmlrpc-interface
-http_interface = {HTTP_INTERFACE}
-
-; --http-port | -p | --xmlrpc-port
-http_port = {HTTP_PORT}
-
-; --xmlrpcs-interface
-xmlrpcs_interface = {XMLRPCS_INTERFACE}
-
-; --xmlrpcs-port
-xmlrpcs_port = {XMLRPCS_PORT}
-
-; --longpolling_port
-longpolling_port = {LONGPOLLING_PORT}
-
-; --no-http | --no-xmlrpc
-http_enable = {HTTP_ENABLE}
-
-; --no-xmlrpcs
-xmlrpcs = {XMLRPCS}
-
-; --proxy-mode
-proxy_mode = {PROXY_MODE}
-
-; --x-sendfile
-x_sendfile = {X_SENDFILE}
-
-;---------------;
-; Testing Group ;
-;---------------;
-; --test-file
-test_file = {TEST_FILE}
-
-; --test-enable
-test_enable = {TEST_ENABLE}
-
-; --test-tags
-test_tags = {TEST_FILE}
-
-; --screencasts
-screencasts = {SCREENCASTS}
-
-; --screenshots
-screenshots = {SCREENSHOTS}
-
-;---------------;
-; Logging Group ;
-;---------------;
-; --logfile
-logfile = {LOGFILE}
-
-; --syslog
-syslog = {SYSLOG}
-
-; --log-handler | --log-web (--log-handler=odoo.http:DEBUG) | --log-sql (--log-handler=odoo.sql_db:DEBUG)
-log_handler = {LOG_HANDLER}
-
-; --log-db
-log_db = {LOG_DB}
-
-; --log-db-level
-log_db_level = {LOG_DB_LEVEL}
-
-; --log-level
-log_level = {LOG_LEVEL}
-
-;------------;
-; SMTP Group ;
-;------------;
-; --email-from
-email_from = {EMAIL_FROM}
-
-; --from-filter
-from_filter = {FROM_FILTER}
-
-; --smtp
-smtp_server = {SMTP_SERVER}
-
-; --smtp-port
-smtp_port = {SMTP_PORT}
-
-; --smtp-ssl
-smtp_ssl = {SMTP_SSL}
-
-; --smtp-user
-smtp_user = {SMTP_USER}
-
-; --smtp-password
-smtp_password = {SMTP_PASSWORD}
-
-; --smtp-ssl-certificate-filename
-smtp_ssl_certificate_filename = {SMTP_SSL_CERTIFICATE_FILENAME}
-
-; --smtp-ssl-private-key-filename
-smtp_ssl_private_key_filename = {SMTP_SSL_PRIVATE_KEY_FILENAME}
-
-;----------;
-; DB Group ;
-;----------;
-; --database | -d
-db_name = {DB_NAME}
-
-; --db_user | -r
-db_user = {DB_USER}
-
-; --db_password | -w
-db_password = {DB_PASSWORD}
-
-; --pg_path
-pg_path = {PG_PATH}
-
-; --db_host
-db_host = {DB_HOST}
-
-; --db_port
-db_port = {DB_PORT}
-
-; --db_sslmode
-db_sslmode = {DB_SSLMODE}
-
-; --db_maxconn
-db_maxconn = {DB_MAXCONN}
-
-; --db-template
-db_template = {DB_TEMPLATE}
-
-;------------------------------;
-; Internationalisation options ;
-;------------------------------;
-; --load-language
-load_language = {LOAD_LANGUAGE}
-
-; --language
-language = {LANGUAGE}
-
-; --i18n-export
-translate_out = {TRANSLATE_OUT}
-
-; --i18n-import
-translate_in = {TRANSLATE_IN}
-
-; --i18n-overwrite
-overwrite_existing_translations = {OVERWRITE_EXISTING_TRANSLATIONS}
-
-; --modules
-translate_modules = {TRANSLATE_MODULES}
-
-;----------;
-; Security ;
-;----------;
-; --no-database-list
-list_db = {LIST_DB}
-
-;-----;
-; WEB ;
-;-----;
-; --db-filter
-dbfilter = {DBFILTER}
-
-;------------------;
-; Advanced options ;
-;------------------;
-; --dev (all, reload, qweb, werkzeug, sql, shell, assets, tests)
-dev_mode = {DEV_MODE}
-
-; --shell-interface
-shell_interface = {SHELL_INTERFACE}
-
-; --stop-after-init
-stop_after_init = {STOP_AFTER_INIT}
-
-; --osv-memory-count-limit
-osv_memory_count_limit = {OSV_MEMORY_COUNT_LIMIT}
-
-; --transient-age-limit | --osv-memory-age-limit (deprecated)
-transient_age_limit = {TRANSIENT_AGE_LIMIT}
-
-; --max-cron-threads
-max_cron_threads = {MAX_CRON_THREADS}
-
-; --unaccent
-unaccent = {UNACCENT}
-
-; --geoip-db
-geoip_database = {GEOIP_DATABASE}
-
-; --workers
-workers = {WORKERS}
-
-; --limit-memory-soft
-limit_memory_soft = {LIMIT_MEMORY_SOFT}
-
-; --limit-memory-hard
-limit_memory_hard = {LIMIT_MEMORY_HARD}
-
-; --limit-time-cpu
-limit_time_cpu = {LIMIT_TIME_CPU}
-
-; --limit-time-real
-limit_time_real = {LIMIT_TIME_REAL}
-
-; --limit-time-real-cron
-limit_time_real_cron = {LIMIT_TIME_REAL_CRON}
-
-; --limit-request
-limit_request = {LIMIT_REQUEST}
diff --git a/odoo/odoorc.sh b/odoo/odoorc.sh
index 9b841f2..6726828 100755
--- a/odoo/odoorc.sh
+++ b/odoo/odoorc.sh
@@ -2,378 +2,55 @@
set -e
-# Define default values for environment variables
-set -a
-source /.env
-set +a
-
-declare -A defaults
-defaults=(
- [ADMIN_PASSWD]=${ADMIN_PASSWD}
- [CSV_INTERNAL_SEP]=${CSV_INTERNAL_SEP}
- [PUBLISHER_WARRANTY_URL]=${PUBLISHER_WARRANTY_URL}
- [ROOT_PATH]=${ROOT_PATH}
- [REPORTGZ]=${REPORTGZ}
- [WEBSOCKET_KEEP_ALIVE_TIMEOUT]=${WEBSOCKET_KEEP_ALIVE_TIMEOUT}
- [WEBSOCKET_RATE_LIMIT_BURST]=${WEBSOCKET_RATE_LIMIT_BURST}
- [WEBSOCKET_RATE_LIMIT_DELAY]=${WEBSOCKET_RATE_LIMIT_DELAY}
-
- [ODOO_RC]=${ODOO_RC}
- [SAVE]=${SAVE}
- [INIT]=${INIT}
- [UPDATE]=${UPDATE}
- [DEMO]=${DEMO}
- [WITHOUT_DEMO]=${WITHOUT_DEMO}
- [IMPORT_PARTIAL]=${IMPORT_PARTIAL}
- [PIDFILE]=${PIDFILE}
- [ADDONS_PATH]=${ADDONS_PATH}
- [UPGRADE_PATH]=${UPGRADE_PATH}
- [SERVER_WIDE_MODULES]=${SERVER_WIDE_MODULES}
- [DATA_DIR]=${DATA_DIR}
-
- [HTTP_INTERFACE]=${HTTP_INTERFACE}
- [HTTP_PORT]=${HTTP_PORT}
- [XMLRPCS_INTERFACE]=${XMLRPCS_INTERFACE}
- [XMLRPCS_PORT]=${XMLRPCS_PORT}
- [LONGPOLLING_PORT]=${LONGPOLLING_PORT}
- [HTTP_ENABLE]=${HTTP_ENABLE}
- [XMLRPCS]=${XMLRPCS}
- [PROXY_MODE]=${PROXY_MODE}
- [X_SENDFILE]=${X_SENDFILE}
-
- [DBFILTER]=${DBFILTER}
-
- [TEST_FILE]=${TEST_FILE}
- [TEST_ENABLE]=${TEST_ENABLE}
- [TEST_TAGS]=${TEST_TAGS}
- [SCREENCASTS]=${SCREENCASTS}
- [SCREENSHOTS]=${SCREENSHOTS}
-
- [LOGFILE]=${LOGFILE}
- [SYSLOG]=${SYSLOG}
- [LOG_HANDLER]=${LOG_HANDLER}
- [LOG_DB]=${LOG_DB}
- [LOG_DB_LEVEL]=${LOG_DB_LEVEL}
- [LOG_LEVEL]=${LOG_LEVEL}
-
- [EMAIL_FROM]=${EMAIL_FROM}
- [FROM_FILTER]=${FROM_FILTER}
- [SMTP_SERVER]=${SMTP_SERVER}
- [SMTP_PORT]=${SMTP_PORT}
- [SMTP_SSL]=${SMTP_SSL}
- [SMTP_USER]=${SMTP_USER}
- [SMTP_PASSWORD]=${SMTP_PASSWORD}
- [SMTP_SSL_CERTIFICATE_FILENAME]=${SMTP_SSL_CERTIFICATE_FILENAME}
- [SMTP_SSL_PRIVATE_KEY_FILENAME]=${SMTP_SSL_PRIVATE_KEY_FILENAME}
-
- [DB_NAME]=${DB_NAME}
- [DB_USER]=${DB_USER}
- [DB_PASSWORD]=${DB_PASSWORD}
- [PG_PATH]=${PG_PATH}
- [DB_HOST]=${DB_HOST}
- [DB_PORT]=${DB_PORT}
- [DB_SSLMODE]=${DB_SSLMODE}
- [DB_MAXCONN]=${DB_MAXCONN}
- [DB_TEMPLATE]=${DB_TEMPLATE}
-
- [LOAD_LANGUAGE]=${LOAD_LANGUAGE}
- [LANGUAGE]=${LANGUAGE}
- [TRANSLATE_OUT]=${TRANSLATE_OUT}
- [TRANSLATE_IN]=${TRANSLATE_IN}
- [OVERWRITE_EXISTING_TRANSLATIONS]=${OVERWRITE_EXISTING_TRANSLATIONS}
- [TRANSLATE_MODULES]=${TRANSLATE_MODULES}
-
- [LIST_DB]=${LIST_DB}
-
- [DEV_MODE]=${DEV_MODE}
- [SHELL_INTERFACE]=${SHELL_INTERFACE}
- [STOP_AFTER_INIT]=${STOP_AFTER_INIT}
- [OSV_MEMORY_COUNT_LIMIT]=${OSV_MEMORY_COUNT_LIMIT}
- [TRANSIENT_AGE_LIMIT]=${TRANSIENT_AGE_LIMIT}
- [MAX_CRON_THREADS]=${MAX_CRON_THREADS}
- [UNACCENT]=${UNACCENT}
- [GEOIP_DATABASE]=${GEOIP_DATABASE}
- [WORKERS]=${WORKERS}
- [LIMIT_MEMORY_SOFT]=${LIMIT_MEMORY_SOFT}
- [LIMIT_MEMORY_HARD]=${LIMIT_MEMORY_HARD}
- [LIMIT_TIME_CPU]=${LIMIT_TIME_CPU}
- [LIMIT_TIME_REAL]=${LIMIT_TIME_REAL}
- [LIMIT_TIME_REAL_CRON]=${LIMIT_TIME_REAL_CRON}
- [LIMIT_REQUEST]=${LIMIT_REQUEST}
-)
-
-# Define the template
-template=$(cat << EOF
-[options]
-;------------------------------------------;
-; Options not exposed on the command line. ;
-;------------------------------------------;
-
-admin_passwd = {ADMIN_PASSWD}
-csv_internal_sep = {CSV_INTERNAL_SEP}
-publisher_warranty_url = {PUBLISHER_WARRANTY_URL}
-root_path = {ROOT_PATH}
-reportgz = {REPORTGZ}
-websocket_keep_alive_timeout = {WEBSOCKET_KEEP_ALIVE_TIMEOUT}
-websocket_rate_limit_burst = {WEBSOCKET_RATE_LIMIT_BURST}
-websocket_rate_limit_delay = {WEBSOCKET_RATE_LIMIT_DELAY}
-
-;-----------------------;
-; Server startup config ;
-;-----------------------;
-; --config | -c
-config = {ODOO_RC}
-
-; --save
-save = {SAVE}
-
-; --init | -i
-init = {INIT}
-
-; --update | -u
-update = {UPDATE}
-
-; --without-demo
-demo = {DEMO}
-without_demo = {WITHOUT_DEMO}
-
-; --import-partial
-import_partial = {IMPORT_PARTIAL}
-
-; --pidfile
-pidfile = {PIDFILE}
-
-; --addons-path
-addons_path = {ADDONS_PATH}
-
-; --upgrade-path
-upgrade_path = {UPGRADE_PATH}
-
-; --load
-server_wide_modules = {SERVER_WIDE_MODULES}
-
-; --data-dir
-data_dir = {DATA_DIR}
-
-;------;
-; HTTP ;
-;------;
-; --http-interface | --xmlrpc-interface
-http_interface = {HTTP_INTERFACE}
-
-; --http-port | -p | --xmlrpc-port
-http_port = {HTTP_PORT}
-
-; --xmlrpcs-interface
-xmlrpcs_interface = {XMLRPCS_INTERFACE}
-
-; --xmlrpcs-port
-xmlrpcs_port = {XMLRPCS_PORT}
-
-; --longpolling_port
-longpolling_port = {LONGPOLLING_PORT}
-
-; --no-http | --no-xmlrpc
-http_enable = {HTTP_ENABLE}
-
-; --no-xmlrpcs
-xmlrpcs = {XMLRPCS}
-
-; --proxy-mode
-proxy_mode = {PROXY_MODE}
-
-; --x-sendfile
-x_sendfile = {X_SENDFILE}
-
-;---------------;
-; Testing Group ;
-;---------------;
-; --test-file
-test_file = {TEST_FILE}
-
-; --test-enable
-test_enable = {TEST_ENABLE}
-
-; --test-tags
-test_tags = {TEST_FILE}
-
-; --screencasts
-screencasts = {SCREENCASTS}
-
-; --screenshots
-screenshots = {SCREENSHOTS}
-
-;---------------;
-; Logging Group ;
-;---------------;
-; --logfile
-logfile = {LOGFILE}
-
-; --syslog
-syslog = {SYSLOG}
-
-; --log-handler | --log-web (--log-handler=odoo.http:DEBUG) | --log-sql (--log-handler=odoo.sql_db:DEBUG)
-log_handler = {LOG_HANDLER}
-
-; --log-db
-log_db = {LOG_DB}
-
-; --log-db-level
-log_db_level = {LOG_DB_LEVEL}
-
-; --log-level
-log_level = {LOG_LEVEL}
-
-;------------;
-; SMTP Group ;
-;------------;
-; --email-from
-email_from = {EMAIL_FROM}
-
-; --from-filter
-from_filter = {FROM_FILTER}
-
-; --smtp
-smtp_server = {SMTP_SERVER}
-
-; --smtp-port
-smtp_port = {SMTP_PORT}
-
-; --smtp-ssl
-smtp_ssl = {SMTP_SSL}
-
-; --smtp-user
-smtp_user = {SMTP_USER}
-
-; --smtp-password
-smtp_password = {SMTP_PASSWORD}
-
-; --smtp-ssl-certificate-filename
-smtp_ssl_certificate_filename = {SMTP_SSL_CERTIFICATE_FILENAME}
-
-; --smtp-ssl-private-key-filename
-smtp_ssl_private_key_filename = {SMTP_SSL_PRIVATE_KEY_FILENAME}
-
-;----------;
-; DB Group ;
-;----------;
-; --database | -d
-db_name = {DB_NAME}
-
-; --db_user | -r
-db_user = {DB_USER}
-
-; --db_password | -w
-db_password = {DB_PASSWORD}
-
-; --pg_path
-pg_path = {PG_PATH}
-
-; --db_host
-db_host = {DB_HOST}
-
-; --db_port
-db_port = {DB_PORT}
-
-; --db_sslmode
-db_sslmode = {DB_SSLMODE}
-
-; --db_maxconn
-db_maxconn = {DB_MAXCONN}
-
-; --db-template
-db_template = {DB_TEMPLATE}
-
-;------------------------------;
-; Internationalisation options ;
-;------------------------------;
-; --load-language
-load_language = {LOAD_LANGUAGE}
-
-; --language
-language = {LANGUAGE}
-
-; --i18n-export
-translate_out = {TRANSLATE_OUT}
-
-; --i18n-import
-translate_in = {TRANSLATE_IN}
-
-; --i18n-overwrite
-overwrite_existing_translations = {OVERWRITE_EXISTING_TRANSLATIONS}
-
-; --modules
-translate_modules = {TRANSLATE_MODULES}
-
-;----------;
-; Security ;
-;----------;
-; --no-database-list
-list_db = {LIST_DB}
-
-;-----;
-; WEB ;
-;-----;
-; --db-filter
-dbfilter = {DBFILTER}
-
-;------------------;
-; Advanced options ;
-;------------------;
-; --dev
-dev_mode = {DEV_MODE}
-
-; --shell-interface
-shell_interface = {SHELL_INTERFACE}
-
-; --stop-after-init
-stop_after_init = {STOP_AFTER_INIT}
-
-; --osv-memory-count-limit
-osv_memory_count_limit = {OSV_MEMORY_COUNT_LIMIT}
-
-; --transient-age-limit | --osv-memory-age-limit (deprecated)
-transient_age_limit = {TRANSIENT_AGE_LIMIT}
-
-; --max-cron-threads
-max_cron_threads = {MAX_CRON_THREADS}
-
-; --unaccent
-unaccent = {UNACCENT}
-
-; --geoip-db
-geoip_database = {GEOIP_DATABASE}
-
-; --workers
-workers = {WORKERS}
-
-; --limit-memory-soft
-limit_memory_soft = {LIMIT_MEMORY_SOFT}
-
-; --limit-memory-hard
-limit_memory_hard = {LIMIT_MEMORY_HARD}
-
-; --limit-time-cpu
-limit_time_cpu = {LIMIT_TIME_CPU}
-
-; --limit-time-real
-limit_time_real = {LIMIT_TIME_REAL}
-
-; --limit-time-real-cron
-limit_time_real_cron = {LIMIT_TIME_REAL_CRON}
-
-; --limit-request
-limit_request = {LIMIT_REQUEST}
-EOF
-)
-
-# Override defaults with values from environment variables
-for key in "${!defaults[@]}"; do
- if [[ ! ${defaults[$key]} =~ ^\{.*\}$ ]]; then
- value=${!key:-${defaults[$key]}}
- template="${template//\{$key\}/$value}"
- fi
-done
-
-# Store the result to the odoo.conf file
-echo "$template" > ${ODOO_RC}
+# Define the path to the example configuration file
+TEMPLATE_CONF="odoo.conf"
+
+# First pass: Evaluate any nested variables within .env file and export them
+while IFS='=' read -r key value || [[ -n $key ]]; do
+ # Skip comments and empty lines
+ [[ $key =~ ^#.* ]] || [[ -z $key ]] && continue
+
+ # Removing any quotes around the value
+ value=${value%\"}
+ value=${value#\"}
+
+ # Evaluate any variables within value
+ eval "value=\"$value\""
+
+ export "$key=$value"
+done < .env
+
+# Check the USE_REDIS to add base_attachment_object_storage & session_redis to LOAD variable
+if [[ $USE_REDIS == "true" ]]; then
+ LOAD+=",session_redis"
+fi
+
+# Check the USE_REDIS to add attachment_s3 to LOAD variable
+if [[ $USE_S3 == "true" ]]; then
+ LOAD+=",base_attachment_object_storage"
+ LOAD+=",attachment_s3"
+fi
+
+# Check the USE_REDIS to add sentry to LOAD variable
+if [[ $USE_SENTRY == "true" ]]; then
+ LOAD+=",sentry"
+fi
+
+# Copy the example conf to the destination to start replacing the variables
+cp "$TEMPLATE_CONF" "$ODOO_RC"
+
+# Second pass: Replace the variables in $ODOO_RC
+while IFS='=' read -r key value || [[ -n $key ]]; do
+ # Skip comments and empty lines
+ [[ $key =~ ^#.* ]] || [[ -z $key ]] && continue
+
+ value=${!key} # Get the value of the variable whose name is $key
+
+ # Escape characters which are special to sed
+ value_escaped=$(echo "$value" | sed 's/[\/&]/\\&/g')
+
+ # Replace occurrences of the key with the value in $ODOO_RC
+ sed -i "s/\${$key}/${value_escaped}/g" "$ODOO_RC"
+done < .env
+
+echo "Configuration file is generated at $ODOO_RC"
diff --git a/odoo/requirements.txt b/odoo/requirements.txt
index 3054caa..1ee0342 100644
--- a/odoo/requirements.txt
+++ b/odoo/requirements.txt
@@ -1,5 +1,7 @@
jinja2
-sortedcontainers
debugpy
websocket-client
-pyOpenSSL
+redis
+boto3
+sentry-sdk
+aiohttp
diff --git a/odoo/third-party-addons.sh b/odoo/third-party-addons.sh
new file mode 100755
index 0000000..d101247
--- /dev/null
+++ b/odoo/third-party-addons.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+# Check if the repository directory exists and either Redis or S3 is to be used
+if [[ ${USE_REDIS} == "true" || ${USE_S3} == "true" ]]; then
+ git clone https://github.com/odoocker/odoo-cloud-platform.git --depth 1 --branch ${ODOO_TAG} --single-branch --no-tags;
+fi
+
+if [[ ${USE_REDIS} == "true" ]]; then
+ cp -r odoo-cloud-platform/session_redis ${THIRD_PARTY_ADDONS}/session_redis
+fi
+
+# Check the USE_S3 variable to decide whether to copy S3 directories
+if [[ ${USE_S3} == "true" ]]; then
+ cp -r odoo-cloud-platform/base_attachment_object_storage ${THIRD_PARTY_ADDONS}/base_attachment_object_storage
+ cp -r odoo-cloud-platform/attachment_s3 ${THIRD_PARTY_ADDONS}/attachment_s3
+fi
+
+# Check if the repository directory exists and Sentry is to be used
+if [[ ${USE_SENTRY} == "true" ]]; then
+ git clone https://github.com/odoocker/server-tools.git --depth 1 --branch ${ODOO_TAG} --single-branch --no-tags;
+ cp -r server-tools/sentry ${THIRD_PARTY_ADDONS}/sentry
+fi
diff --git a/pgadmin/Dockerfile b/pgadmin/Dockerfile
new file mode 100644
index 0000000..848ede4
--- /dev/null
+++ b/pgadmin/Dockerfile
@@ -0,0 +1,35 @@
+#------------------------#
+# PGAdmin Server #
+#------------------------#
+ARG PGADMIN_TAG
+FROM dpage/pgadmin4:${PGADMIN_TAG}
+
+# Receive ARGs from docker-compose.yml & convert them into ENVs
+ARG PGADMIN_DEFAULT_EMAIL
+
+ENV PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL}
+
+# Switch to root user
+USER root
+
+# Install bash
+RUN apk add --no-cache bash jq sqlite
+
+# Check if the private key exists, copy it and set permissions if it does
+RUN if [ -f ./pgadmin/private_key ]; then \
+ cp ./pgadmin/private_key /pgadmin4/private_key && \
+ chown pgadmin:root /pgadmin4/private_key && \
+ chmod 600 /pgadmin4/private_key; \
+ fi
+
+# Copy your script file into the Docker image
+COPY --chown=pgadmin:root ./.env /
+COPY ./pgadmin/start_pgadmin.sh /var/lib/pgadmin/start_pgadmin.sh
+
+# Make the script executable
+RUN chmod +x /var/lib/pgadmin/start_pgadmin.sh
+# Run your script
+RUN /var/lib/pgadmin/start_pgadmin.sh
+
+# Expose the necessary port
+EXPOSE 80
diff --git a/pgadmin/start_pgadmin.sh b/pgadmin/start_pgadmin.sh
new file mode 100755
index 0000000..e8133b4
--- /dev/null
+++ b/pgadmin/start_pgadmin.sh
@@ -0,0 +1,86 @@
+#!/bin/bash
+
+set -e
+
+# Source environment variables
+set -a
+source /.env
+set +a
+
+# Check if PGADMIN_DEFAULT_EMAIL is set
+if [[ -z $PGADMIN_DEFAULT_EMAIL ]]; then
+ echo "PGADMIN_DEFAULT_EMAIL is not set. Exiting..."
+ exit 1
+fi
+
+# Modify the email to replace @ with _
+DIR_NAME="/var/lib/pgadmin/storage/${PGADMIN_DEFAULT_EMAIL//@/_}"
+
+# Create the directory using the modified name
+mkdir -p "$DIR_NAME"
+
+# Generate JSON for each matching variable
+DB_PATH="/var/lib/pgadmin/pgadmin4.db"
+json_output="{\"Servers\":{"
+index=1
+while true; do
+ name_var="PGADMIN_DB${index}_NAME"
+ if [[ -z ${!name_var} ]]; then
+ break
+ fi
+
+ host_var="PGADMIN_DB${index}_HOST"
+ port_var="PGADMIN_DB${index}_PORT"
+ maintenance_db_var="PGADMIN_DB${index}_MAINTENANCE_DB"
+ username_var="PGADMIN_DB${index}_USERNAME"
+ tunnel_host_var="PGADMIN_DB${index}_TUNNEL_HOST"
+ tunnel_port_var="PGADMIN_DB${index}_TUNNEL_PORT"
+ tunnel_username_var="PGADMIN_DB${index}_TUNNEL_USERNAME"
+
+ json_output+="\"$index\":$(jq -n \
+ --arg name "${!name_var}" \
+ --arg host "${!host_var:-localhost}" \
+ --arg port "${!port_var:-5432}" \
+ --arg db "${!maintenance_db_var:-${!name_var}}" \
+ --arg username "${!username_var:-odoo}" \
+ --arg thost "${!tunnel_host_var}" \
+ --arg tport "${!tunnel_port_var:-22}" \
+ --arg tuser "${!tunnel_username_var:-ubuntu}" \
+ '{
+ "Name": $name,
+ "Group": "Servers",
+ "Host": $host,
+ "Port": $port|tonumber,
+ "MaintenanceDB": $db,
+ "Username": $username,
+ "UseSSHTunnel": 1,
+ "TunnelHost": $thost,
+ "TunnelPort": $tport,
+ "TunnelUsername": $tuser,
+ "TunnelAuthentication": 1,
+ "KerberosAuthentication": false,
+ "ConnectionParameters": {
+ "sslmode": "prefer",
+ "connect_timeout": 10,
+ "sslcert": "'"$DIR_NAME"'/.postgresql/postgresql.crt",
+ "sslkey": "'"$DIR_NAME"'/.postgresql/postgresql.key"
+ },
+ "Shared": true
+ }'),"
+
+ index=$((index + 1))
+done
+
+# Remove trailing comma and close JSON braces
+json_output=${json_output%,}
+json_output+="}}"
+
+# Save the well-formatted JSON to a file using jq
+if [[ $PGADMIN_SERVERS_JSON ]]; then
+ echo $json_output | jq '.' > "$PGADMIN_SERVERS_JSON"
+
+ # Make the Servers.json file readable for all users
+ chmod 755 "/pgadmin4/servers.json"
+
+ echo "JSON configuration saved to $DIR_NAME/servers.json"
+fi
diff --git a/postgres/Dockerfile b/postgres/Dockerfile
index 94227e6..3eb39ed 100644
--- a/postgres/Dockerfile
+++ b/postgres/Dockerfile
@@ -8,8 +8,11 @@ FROM postgres:${POSTGRES_TAG}
RUN apt-get update && apt-get install -y \
# Unaccent extension dependencies
postgresql-contrib \
+ apt-utils \
# Clean up the apt cache to reduce the image size
&& rm -rf /var/lib/apt/lists/*
+COPY --chown=postgres:postgres ./.env /
+
# Copy the script to create the unaccent template
-COPY ./entrypoint.sh /docker-entrypoint-initdb.d/entrypoint.sh
+COPY ./postgres/entrypoint.sh /docker-entrypoint-initdb.d/entrypoint.sh
diff --git a/postgres/entrypoint.sh b/postgres/entrypoint.sh
index de38ff1..f6a832e 100755
--- a/postgres/entrypoint.sh
+++ b/postgres/entrypoint.sh
@@ -1,3 +1,35 @@
-psql -p 5432 -U odoo -d postgres -c "CREATE DATABASE unaccent_template WITH TEMPLATE = template0"
-psql -p 5432 -U odoo -d postgres -c "\\c unaccent_template"
-psql -p 5432 -U odoo -d postgres -c "CREATE EXTENSION IF NOT EXISTS unaccent;"
+#!/bin/bash
+
+set -e
+
+# Source environment variables
+set -a
+source /.env
+set +a
+
+# Create the $DB_TEMPLATE database
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "CREATE DATABASE $DB_TEMPLATE WITH TEMPLATE = template0;"
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "\\c $DB_TEMPLATE;"
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $DB_TEMPLATE -c "CREATE EXTENSION IF NOT EXISTS unaccent;"
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $DB_TEMPLATE -c "ALTER FUNCTION unaccent(text) IMMUTABLE;"
+
+# Create Odoo user and give proper privileges
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "ALTER USER $DB_USER CREATEDB;"
+
+# Give Odoo user access to copy $DB_TEMPLATE
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "GRANT ALL PRIVILEGES ON DATABASE $DB_TEMPLATE TO $DB_USER;"
+psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $DB_TEMPLATE -c "ALTER DATABASE $DB_TEMPLATE OWNER TO $DB_USER;"
+
+# Check the USE_REDIS to add sentry to LOAD variable
+if [[ $USE_PGADMIN == "true" ]]; then
+ # Create PgAdmin user and give proper privileges
+ psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "CREATE DATABASE $PGADMING_DB_NAME;"
+ psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "CREATE USER $PGADMING_DB_USER WITH PASSWORD '$PGADMIN_DB_PASSWORD';"
+ psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "GRANT ALL PRIVILEGES ON DATABASE $PGADMING_DB_NAME TO $PGADMING_DB_USER;"
+ psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $PGADMING_DB_NAME -c "GRANT ALL PRIVILEGES ON SCHEMA public TO $PGADMING_DB_USER;"
+ # Revoke Odoo user's access to pgadmin database
+ psql -p $POSTGRES_PORT -U $POSTGRES_MAIN_USER -d $POSTGRES_DB -c "REVOKE CONNECT ON DATABASE $PGADMING_DB_NAME FROM $DB_USER;"
+fi
+
+echo "Setup completed."