commit 038eb4bee0cbae79f6686f6dc5b065e0704ee760 Author: Disassembler Date: Sun Sep 1 11:27:28 2024 +0200 Odoo 14 diff --git a/.env b/.env new file mode 100644 index 0000000..6772518 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +ODOO_ADMIN_PASSWORD=odoo +POSTGRES_HOST=odoo-postgres +POSTGRES_USER=odoo +POSTGRES_PASSWORD=odoo +POSTGRES_DB=odoo +SMTP_HOST=odoo-smtp +SMTP_SENDER=odoo@example.com diff --git a/README.md b/README.md new file mode 100644 index 0000000..8cdf5c3 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +Odoo +==== + +Overview +-------- + +Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, +accounting, inventory, point of sale, project management, etc. Odoo runs on python 3 and uses +PostgreSQL database. + +Development without docker-compose +---------------------------------- + +```bash +rm -rf ~/postgres_data +mkdir ~/postgres_data +podman run -it --rm \ + --env "POSTGRES_USER=odoo" \ + --env "POSTGRES_PASSWORD=odoo" \ + --env "POSTGRES_DB=odoo" \ + --volume ~/postgres_data:/var/lib/postgresql/data \ + --ip 10.88.0.2 \ + docker.io/postgres:16-alpine +``` + +```bash +podman build -t odoo:latest odoo + +rm -rf ~/odoo_{conf,data} +mkdir ~/odoo_{conf,data} +podman run -it --rm \ + --env-file .env \ + --volume ~/odoo_conf:/srv/odoo/conf \ + --volume ~/odoo_data:/srv/odoo/data \ + --add-host odoo-postgres:10.88.0.2 \ + --ip 10.88.0.3 \ + odoo:latest +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b0aed47 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,34 @@ +--- +version: '3' +services: + + odoo: + build: odoo + image: odoo:14.0.0-240826 + restart: unless-stopped + depends_on: + - odoo-postgres + env_file: + - .env + expose: + - 8080 + ports: + - 8080:8080 + volumes: + - odoo_conf:/srv/odoo/conf + - odoo_data:/srv/odoo/data + + odoo-postgres: + image: postgres:16-alpine + restart: unless-stopped + environment: + - POSTGRES_USER + - POSTGRES_PASSWORD + - POSTGRES_DB + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + odoo_conf: + odoo_data: + postgres_data: diff --git a/odoo/Dockerfile b/odoo/Dockerfile new file mode 100644 index 0000000..bdc05aa --- /dev/null +++ b/odoo/Dockerfile @@ -0,0 +1,52 @@ +FROM docker.io/alpine:3.12 + +RUN \ + # Update packages + apk --no-cache upgrade && \ + # Install common packages + apk --no-cache add libbz2 libgcc libressl libstdc++ libxml2 libxslt ncurses-libs pcre readline s6 xz-libs && \ + # Install python + apk --no-cache add python3 py3-pip py3-wheel && \ + # Install runtime dependencies + apk --no-cache add libffi libjpeg-turbo libpq nodejs postgresql-client ttf-dejavu ttf-droid ttf-freefont ttf-liberation ttf-ubuntu-font-family wkhtmltopdf && \ + # Set time zone data + apk --no-cache add tzdata && \ + cp /usr/share/zoneinfo/UTC /etc/localtime && \ + apk --no-cache del tzdata && \ + # Set python interpret + ln -s /usr/bin/python3 /usr/bin/python && \ + # Replace wkhtmltopdf + # Extracted from https://github.com/Surnet/docker-wkhtmltopdf + # wkhtmltopdf 0.12.7 is expected to support Alpine linux out of the box + wget https://repo.spotter.cz/libwkhtmltox.tar.xz -O - | tar -xJf - -C / && \ + # Cleanup + rm -rf /etc/crontabs/root /etc/periodic + +RUN \ + # Install build dependencies + apk --no-cache add --virtual .deps build-base git libffi-dev libjpeg-turbo-dev libxml2-dev libxslt-dev linux-headers msttcorefonts-installer openldap-dev postgresql-dev python3-dev && \ + # Update fonts + update-ms-fonts && \ + fc-cache -f && \ + # Install Odoo + git clone -b 14.0 --depth 1 https://github.com/odoo/odoo.git /srv/odoo && \ + cd /srv/odoo && \ + pip3 install gevent==20.9.0 --no-build-isolation && \ + pip3 install -r requirements.txt && \ + mkdir /srv/odoo/conf && \ + # Create OS user + addgroup -S -g 8080 odoo && \ + adduser -S -u 8080 -h /srv/odoo -s /bin/false -g odoo -G odoo odoo && \ + chown -R odoo:odoo /srv/odoo && \ + # Cleanup + apk --no-cache del .deps && \ + find /srv/odoo -name '.git*' -exec rm -rf {} + && \ + rm -rf /root/.cache + +COPY image.d/srv/odoo/ /srv/odoo/ +COPY image.d/etc/ /etc/ +COPY image.d/entrypoint.sh / + +VOLUME ["/srv/odoo/conf", "/srv/odoo/data"] +EXPOSE 8080 +ENTRYPOINT ["/entrypoint.sh"] diff --git a/odoo/image.d/entrypoint.sh b/odoo/image.d/entrypoint.sh new file mode 100755 index 0000000..22de76d --- /dev/null +++ b/odoo/image.d/entrypoint.sh @@ -0,0 +1,43 @@ +#!/bin/sh +set -e + +if [ "$*" != "" ]; then + exec "$@" +fi + +echo "Starting Odoo..." + +# Fix volume permissions +chown -R odoo:odoo /srv/odoo/conf /srv/odoo/data + +# Configure Odoo +python3 /srv/odoo/conf-from-env-vars.py + +# Populate database +export PGPASSWORD=${POSTGRES_PASSWORD} +DB_EXISTS=$(psql -h "${POSTGRES_HOST}" -Atc "SELECT 1 FROM res_users" "${POSTGRES_DB}" "${POSTGRES_USER}" 2>/dev/null || true) +if [ -z "${DB_EXISTS}" ]; then + echo "Populating database..." + su - odoo -s /bin/sh -c '/srv/odoo/odoo-bin -c /srv/odoo/conf/odoo.conf -i base --without-demo all --load-language cs_CZ' >/tmp/odoo.log 2>&1 & + ODOO_PID=$! + until grep -q 'odoo.modules.loading: Modules loaded.' /tmp/odoo.log; do + if ! kill -0 ${ODOO_PID} 2>/dev/null; then + cat /tmp/odoo.log >&2 + echo "Odoo database population process ended unexpectedly." >&2 + exit 1 + fi + sleep 1 + done + kill ${ODOO_PID} + psql -h "${POSTGRES_HOST}" -Atc "UPDATE res_lang SET active = true WHERE code = 'cs_CZ'" "${POSTGRES_DB}" "${POSTGRES_USER}" >/dev/null + psql -h "${POSTGRES_HOST}" -Atc "UPDATE res_partner SET lang = 'cs_CZ', tz = 'Europe/Prague' WHERE id = 3" "${POSTGRES_DB}" "${POSTGRES_USER}" >/dev/null +fi +# Update admin +if [ -n "${ODOO_ADMIN_PASSWORD}" ]; then + ODOO_ADMIN_HASH=$(python3 -c "from passlib.hash import pbkdf2_sha512;print(pbkdf2_sha512.hash('${ODOO_ADMIN_PASSWORD}'))") + psql -h "${POSTGRES_HOST}" -Atc "UPDATE res_users SET password = '${ODOO_ADMIN_HASH}' WHERE login = 'admin'" "${POSTGRES_DB}" "${POSTGRES_USER}" >/dev/null +fi +unset PGPASSWORD + +# Exec into s6 supervisor +exec /bin/s6-svscan /etc/services.d diff --git a/odoo/image.d/etc/services.d/.s6-svscan/finish b/odoo/image.d/etc/services.d/.s6-svscan/finish new file mode 100755 index 0000000..db3885d --- /dev/null +++ b/odoo/image.d/etc/services.d/.s6-svscan/finish @@ -0,0 +1,3 @@ +#!/bin/execlineb + +exit 0 diff --git a/odoo/image.d/etc/services.d/odoo/run b/odoo/image.d/etc/services.d/odoo/run new file mode 100755 index 0000000..32408b9 --- /dev/null +++ b/odoo/image.d/etc/services.d/odoo/run @@ -0,0 +1,4 @@ +#!/bin/execlineb -P + +s6-setuidgid odoo +/srv/odoo/odoo-bin -c /srv/odoo/conf/odoo.conf diff --git a/odoo/image.d/etc/services.d/odoo/timeout-kill b/odoo/image.d/etc/services.d/odoo/timeout-kill new file mode 100644 index 0000000..13de30f --- /dev/null +++ b/odoo/image.d/etc/services.d/odoo/timeout-kill @@ -0,0 +1 @@ +3000 diff --git a/odoo/image.d/srv/odoo/conf-from-env-vars.py b/odoo/image.d/srv/odoo/conf-from-env-vars.py new file mode 100644 index 0000000..63cbd85 --- /dev/null +++ b/odoo/image.d/srv/odoo/conf-from-env-vars.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import os +from configparser import ConfigParser + + +ODOO_CONFIG_FILE = "/srv/odoo/conf/odoo.conf" + + +config = ConfigParser() +config.add_section("options") +config.read(ODOO_CONFIG_FILE) + +options_dict = { + "admin_passwd": os.getenv("ODOO_ADMIN_PASSWORD") or options.get("admin_passwd") or "odoo", + "data_dir": "/srv/odoo/data", + "db_host": os.getenv("POSTGRES_HOST") or options.get("db_host") or "localhost", + "db_name": os.getenv("POSTGRES_DB") or options.get("db_name") or "odoo", + "db_user": os.getenv("POSTGRES_USER") or options.get("db_user") or "odoo", + "db_password": os.getenv("POSTGRES_PASSWORD") or options.get("db_password") or "odoo", + "smtp_server": os.getenv("SMTP_HOST") or options.get("smtp_server") or "localhost", + "email_from": os.getenv("SMTP_SENDER") or options.get("email_from") or "odoo@example.com", + "http_port": "8080", + "proxy_mode": "True", + "list_db": "False", +} +config.read_dict({"options": options_dict}) + +with open(ODOO_CONFIG_FILE, "w", encoding="utf-8") as f: + config.write(f)