diff --git a/.env.example b/.env.example index 3974d52..bf17f74 100644 --- a/.env.example +++ b/.env.example @@ -6,19 +6,30 @@ APP_ENV=local INIT= UPDATE= LOAD=base,web +ROOT_PATH=/usr/lib/python3/dist-packages/odoo WORKERS=2 -DEV_MODE=reload,qweb +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 +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=16.0 -POSTGRES_TAG=15.4 +POSTGRES_TAG=16.0 +KEYDB_TAG=latest +MINIO_TAG=latest NGINX_TAG=1.25.2 NGINX_PROXY_TAG=1.3.1 ACME_COMPANION_TAG=2.2.8 -PGADMIN_TAG=7.6 +PGADMIN_TAG=7.8 + +# 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 dcd7604..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 /websocket { - 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 X-Forwarded-Host $host; 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..399249f 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,25 +37,18 @@ 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} fi @@ -41,21 +62,21 @@ 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= --init= --update= --load=${LOAD} --workers=${WORKERS} --log-level=${LOG_LEVEL} --load-language= --without-demo=all --dev= exec odoo --config ${ODOO_RC} --database= --init= --update= --load-language= --without-demo=all --dev= fi @@ -63,7 +84,7 @@ case "$1" in ;; -*) - 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..f202f75 --- /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} + +; --gevent-port | --longpolling_port (deprecated) +gevent_port = ${GEVENT_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 30d8ee5..0000000 --- a/odoo/odoo.example.conf +++ /dev/null @@ -1,261 +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} - -; --gevent-port | --longpolling_port (deprecated) -gevent_port = {GEVENT_PORT} -longpolling_port = False - -; --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 4358e4f..6726828 100755 --- a/odoo/odoorc.sh +++ b/odoo/odoorc.sh @@ -2,379 +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} - [GEVENT_PORT]=${GEVENT_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} - -; --gevent-port | --longpolling_port (deprecated) -gevent_port = {GEVENT_PORT} -longpolling_port = False - -; --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 fb6626a..2fa9750 100644 --- a/odoo/requirements.txt +++ b/odoo/requirements.txt @@ -1,2 +1,5 @@ debugpy websocket-client +redis +boto3 +sentry-sdk 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."