init odoo 18 docker compose

This commit is contained in:
minhng92 2024-10-11 23:48:53 +07:00
commit a693be9daf
8 changed files with 693 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
postgresql
etc/filestore
etc/sessions
etc/odoo-server.log

135
README.md Normal file
View File

@ -0,0 +1,135 @@
# Installing Odoo 18.0 with one command (Supports multiple Odoo instances on one server).
## Quick Installation
Install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/) yourself, then run the following to set up first Odoo instance @ `localhost:10018` (default master password: `minhng.info`):
``` bash
curl -s https://raw.githubusercontent.com/minhng92/odoo-18-docker-compose/master/run.sh | sudo bash -s odoo-one 10018 20018
```
and/or run the following to set up another Odoo instance @ `localhost:11018` (default master password: `minhng.info`):
``` bash
curl -s https://raw.githubusercontent.com/minhng92/odoo-18-docker-compose/master/run.sh | sudo bash -s odoo-two 11018 21018
```
Some arguments:
* First argument (**odoo-one**): Odoo deploy folder
* Second argument (**10018**): Odoo port
* Third argument (**20018**): live chat port
If `curl` is not found, install it:
``` bash
$ sudo apt-get install curl
# or
$ sudo yum install curl
```
## Usage
Start the container:
``` sh
docker-compose up
```
Then open `localhost:10018` to access Odoo 18.
- **If you get any permission issues**, change the folder permission to make sure that the container is able to access the directory:
``` sh
$ sudo chmod -R 777 addons
$ sudo chmod -R 777 etc
$ sudo chmod -R 777 postgresql
```
- If you want to start the server with a different port, change **10018** to another value in **docker-compose.yml** inside the parent dir:
```
ports:
- "10018:8069"
```
- To run Odoo container in detached mode (be able to close terminal without stopping Odoo):
```
docker-compose up -d
```
- To Use a restart policy, i.e. configure the restart policy for a container, change the value related to **restart** key in **docker-compose.yml** file to one of the following:
- `no` = Do not automatically restart the container. (the default)
- `on-failure[:max-retries]` = Restart the container if it exits due to an error, which manifests as a non-zero exit code. Optionally, limit the number of times the Docker daemon attempts to restart the container using the :max-retries option.
- `always` = Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
- `unless-stopped` = Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.
```
restart: always # run as a service
```
- To increase maximum number of files watching from 8192 (default) to **524288**. In order to avoid error when we run multiple Odoo instances. This is an *optional step*. These commands are for Ubuntu user:
```
$ if grep -qF "fs.inotify.max_user_watches" /etc/sysctl.conf; then echo $(grep -F "fs.inotify.max_user_watches" /etc/sysctl.conf); else echo "fs.inotify.max_user_watches = 524288" | sudo tee -a /etc/sysctl.conf; fi
$ sudo sysctl -p # apply new config immediately
```
## Custom addons
The **addons/** folder contains custom addons. Just put your custom addons if you have any.
## Odoo configuration & log
* To change Odoo configuration, edit file: **etc/odoo.conf**.
* Log file: **etc/odoo-server.log**
* Default database password (**admin_passwd**) is `minhng.info`, please change it @ [etc/odoo.conf#L60](/etc/odoo.conf#L60)
## Odoo container management
**Run Odoo**:
``` bash
docker-compose up -d
```
**Restart Odoo**:
``` bash
docker-compose restart
```
**Stop Odoo**:
``` bash
docker-compose down
```
## Live chat
In [docker-compose.yml#L21](docker-compose.yml#L21), we exposed port **20018** for live-chat on host.
Configuring **nginx** to activate live chat feature (in production):
``` conf
#...
server {
#...
location /longpolling/ {
proxy_pass http://0.0.0.0:20018/longpolling/;
}
#...
}
#...
```
## docker-compose.yml
* odoo:18
* postgres:17
## Odoo 18.0 screenshots after successful installation.
<img src="screenshots/odoo-18-welcome-screenshot.png" width="50%">
<img src="screenshots/odoo-18-apps-screenshot.png" width="100%">
<img src="screenshots/odoo-18-sales-screen.png" width="100%">
<img src="screenshots/odoo-18-product-form.png" width="100%">

1
addons/readme.md Executable file
View File

@ -0,0 +1 @@
This file is intentionally left blank.

35
docker-compose.yml Normal file
View File

@ -0,0 +1,35 @@
version: '2'
services:
db:
image: postgres:17
user: root
environment:
- POSTGRES_USER=odoo
- POSTGRES_PASSWORD=odoo18@2024
- POSTGRES_DB=postgres
restart: always # run as a service
volumes:
- ./postgresql:/var/lib/postgresql/data
odoo18:
image: odoo:18
user: root
depends_on:
- db
ports:
- "10018:8069"
- "20018:8072" # live chat
tty: true
command: --
environment:
- HOST=db
- USER=odoo
- PASSWORD=odoo18@2024
volumes:
#- /etc/timezone:/etc/timezone:ro
#- /etc/localtime:/etc/localtime:ro
# - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line!
- ./addons:/mnt/extra-addons
- ./etc:/etc/odoo
restart: always # run as a service

51
entrypoint.sh Normal file
View File

@ -0,0 +1,51 @@
#!/bin/bash
set -e
# set the postgres database host, port, user and password according to the environment
# and pass them as arguments to the odoo process if not present in the config file
: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}}
: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}}
: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}}
: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo18@2024'}}}
# install python packages
pip3 install pip --upgrade
pip3 install -r /etc/odoo/requirements.txt
# sed -i 's|raise werkzeug.exceptions.BadRequest(msg)|self.jsonrequest = {}|g' /usr/lib/python3/dist-packages/odoo/http.py
DB_ARGS=()
function check_config() {
param="$1"
value="$2"
if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then
value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g')
fi;
DB_ARGS+=("--${param}")
DB_ARGS+=("${value}")
}
check_config "db_host" "$HOST"
check_config "db_port" "$PORT"
check_config "db_user" "$USER"
check_config "db_password" "$PASSWORD"
case "$1" in
-- | odoo)
shift
if [[ "$1" == "scaffold" ]] ; then
exec odoo "$@"
else
wait-for-psql.py ${DB_ARGS[@]} --timeout=30
exec odoo "$@" "${DB_ARGS[@]}"
fi
;;
-*)
wait-for-psql.py ${DB_ARGS[@]} --timeout=30
exec odoo "$@" "${DB_ARGS[@]}"
;;
*)
exec "$@"
esac
exit 1

440
etc/odoo.conf Executable file
View File

@ -0,0 +1,440 @@
[options]
; ===================
; | Common options) |
; ===================
; ------
; -c / --config | specify alternate config file
; ------
; config =
; ------
; -s / --save | save configuration to ~/.odoorc (or to ~/.openerp_serverrc if it exists)
; ------
; save =
; ------
; -i / --init | install one or more modules (comma-separated list, use "all" for all modules), requires -d
; ------
; init =
; ------
; -u / --update | update one or more modules (comma-separated list, use "all" for all modules). Requires -d.
; ------
; update =
; ------
; --without-demo | disable loading demo data for modules to be installed (comma-separated, use "all" for all modules). Requires -d and -i. Default is %default
; ------
; without_demo =
; ------
; -P / --import-partial | Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states.
; ------
; import_partial =
; ------
; --pidfile | file where the server pid will be stored
; ------
; pidfile =
; ------
; --addons-path | type = string | specify additional addons paths (separated by commas).
; ------
addons_path = /mnt/extra-addons
; ------
; --upgrade-path | type = string | specify an additional upgrade path.
; ------
; upgrade_path =
; ------
; --load | Comma-separated list of server-wide modules.
; ------
; server_wide_modules = base,web
; ------
; -D / --data-dir | Directory where to store Odoo data
; ------
data_dir = /etc/odoo
admin_passwd = minhng.info
; ==============================
; | HTTP Service Configuration |
; ==============================
; ------
; --http-interface | Listen interface address for HTTP services. Keep empty to listen on all interfaces (0.0.0.0)
; ------
; http_interface =
; ------
; -p / --http-port | type = int | Listen port for the main HTTP service
; ------
; http_port = 8069
; ------
; --gevent-port | type = int | Listen port for the gevent worker
; ------
; gevent_port = 8072
; ------
; --no-http | Disable the HTTP and Longpolling services entirely
; ------
; http_enable = True
; ------
; --proxy-mode | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy!
; ------
; proxy_mode =
; ------
; --x-sendfile | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy!
; ------
; x_sendfile = False
; ------
; --xmlrpc-interface | SUPPRESSHELP
; ------
; http_interface =
; ------
; --xmlrpc-port | type = int | SUPPRESSHELP
; ------
; http_port =
; ------
; --no-xmlrpc | SUPPRESSHELP
; ------
; http_enable =
; ===============================
; | Web interface Configuration |
; ===============================
; ------
; --db-filter | Regular expressions for filtering available databases for Web UI. The expression can use %d (domain) and %h (host) placeholders.
; ------
; dbfilter =
; =========================
; | Testing Configuration |
; =========================
; ------
; --test-file | Launch a python test file.
; ------
; test_file =
; ------
; --test-enable | Enable unit tests.
; ------
; test_enable =
; ------
; --test-tags | Comma-separated list of spec to filter which tests to execute. Enable unit tests if set. A filter spec has the format: [-][tag][/module][:class][.method] The '-' specifies if we want to include or exclude tests matching this spec. The tag will match tags added on a class with a @tagged decorator. By default tag value is 'standard' when not given on include mode. '*' will match all tags. Tag will also match module name (deprecated, use /module) The module, class, and method will respectively match the module name, test class name and test method name. examples: :TestClass.test_func,/test_module,external
; ------
; test_tags =
; ------
; --screencasts | Screencasts will go in DIR/{db_name}/screencasts.
; ------
; screencasts =
; ------
; --screenshots | Screenshots will go in DIR/{db_name}/screenshots. Defaults to /etc/odoo/odoo_tests.
; ------
; screenshots = /etc/odoo/odoo_tests
; =========================
; | Logging Configuration |
; =========================
; ------
; --logfile | file where the server log will be stored
; ------
logfile = /etc/odoo/odoo-server.log
; ------
; --syslog | Send the log to the syslog server
; ------
; syslog =
; ------
; --log-handler | setup a handler at LEVEL for a given PREFIX. An empty PREFIX indicates the root logger. This option can be repeated. Example: "odoo.orm:DEBUG" or "werkzeug:CRITICAL" (default: ":INFO")
; ------
; None = :INFO
; ------
; --log-web | shortcut for --log-handler=odoo.http:DEBUG
; ------
; log_handler =
; ------
; --log-sql | shortcut for --log-handler=odoo.sql_db:DEBUG
; ------
; log_handler =
; ------
; --log-db | Logging database
; ------
; log_db =
; ------
; --log-db-level | Logging database level
; ------
; log_db_level = warning
; ------
; --log-level | type = choice | choices = ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset'] | specify the level of the logging. Accepted values: ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset'].
; ------
; log_level = info
; ======================
; | SMTP Configuration |
; ======================
; ------
; --email-from | specify the SMTP email address for sending email
; ------
; email_from =
; ------
; --from-filter | specify for which email address the SMTP configuration can be used
; ------
; from_filter = False
; ------
; --smtp | specify the SMTP server for sending email
; ------
; smtp_server = localhost
; ------
; --smtp-port | type = int | specify the SMTP port
; ------
; smtp_port = 25
; ------
; --smtp-ssl | if passed, SMTP connections will be encrypted with SSL (STARTTLS)
; ------
; smtp_ssl =
; ------
; --smtp-user | specify the SMTP username for sending email
; ------
; smtp_user =
; ------
; --smtp-password | specify the SMTP password for sending email
; ------
; smtp_password =
; ------
; --smtp-ssl-certificate-filename | specify the SSL certificate used for authentication
; ------
; smtp_ssl_certificate_filename = False
; ------
; --smtp-ssl-private-key-filename | specify the SSL private key used for authentication
; ------
; smtp_ssl_private_key_filename = False
; ============================
; | Database related options |
; ============================
; ------
; -d / --database | specify the database name
; ------
; db_name =
; ------
; -r / --db_user | specify the database user name
; ------
; db_user =
; ------
; -w / --db_password | specify the database password
; ------
; db_password =
; ------
; --pg_path | specify the pg executable path
; ------
; pg_path =
; ------
; --db_host | specify the database host
; ------
; db_host =
; ------
; --db_replica_host | specify the replica host. Specify an empty db_replica_host to use the default unix socket
; ------
; db_replica_host =
; ------
; --db_port | type = int | specify the database port
; ------
; db_port =
; ------
; --db_replica_port | type = int | specify the replica port
; ------
; db_replica_port =
; ------
; --db_sslmode | type = choice | choices = ['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full'] | specify the database ssl connection mode (see PostgreSQL documentation)
; ------
; db_sslmode = prefer
; ------
; --db_maxconn | type = int | specify the maximum number of physical connections to PostgreSQL
; ------
; db_maxconn = 64
; ------
; --db_maxconn_gevent | type = int | specify the maximum number of physical connections to PostgreSQL specifically for the gevent worker
; ------
; db_maxconn_gevent = False
; ------
; --db-template | specify a custom database template to create a new database
; ------
; db_template = template0
; ========================
; | Internationalisation |
; ========================
; ------
; --load-language | specifies the languages for the translations you want to be loaded
; ------
; load_language =
; ------
; -l / --language | specify the language of the translation file. Use it with --i18n-export or --i18n-import
; ------
; language =
; ------
; --i18n-export | export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit
; ------
; translate_out =
; ------
; --i18n-import | import a CSV or a PO file with translations and exit. The '-l' option is required.
; ------
; translate_in =
; ------
; --i18n-overwrite | overwrites existing translation terms on updating a module or importing a CSV or a PO file.
; ------
; overwrite_existing_translations =
; ------
; --modules | specify modules to export. Use in combination with --i18n-export
; ------
; translate_modules =
; ============================
; | Security-related options |
; ============================
; ------
; --no-database-list | Disable the ability to obtain or view the list of databases. Also disable access to the database manager and selector, so be sure to set a proper --database parameter first
; ------
; list_db = True
; ====================
; | Advanced options |
; ====================
; ------
; --dev | type = string | Enable developer mode. Param: List of options separated by comma. Options : all, [pudb|wdb|ipdb|pdb], reload, qweb, werkzeug, xml
; ------
dev_mode = reload
; ------
; --shell-interface | type = string | Specify a preferred REPL to use in shell mode. Supported REPLs are: [ipython|ptpython|bpython|python]
; ------
; shell_interface =
; ------
; --stop-after-init | stop the server after its initialization
; ------
; stop_after_init =
; ------
; --osv-memory-count-limit | type = int | Force a limit on the maximum number of records kept in the virtual osv_memory tables. The default is False, which means no count-based limit.
; ------
; osv_memory_count_limit =
; ------
; --transient-age-limit | type = float | Time limit (decimal value in hours) records created with a TransientModel (mosly wizard) are kept in the database. Default to 1 hour.
; ------
; transient_age_limit = 1.0
; ------
; --osv-memory-age-limit | type = float | Deprecated alias to the transient-age-limit option
; ------
; osv_memory_age_limit =
; ------
; --max-cron-threads | type = int | Maximum number of threads processing concurrently cron jobs (default 2).
; ------
; max_cron_threads = 2
; ------
; --unaccent | Try to enable the unaccent extension when creating new databases.
; ------
; unaccent =
; ------
; --geoip-city-db / --geoip-db | Absolute path to the GeoIP City database file.
; ------
; geoip_city_db = /usr/share/GeoIP/GeoLite2-City.mmdb
; ------
; --geoip-country-db | Absolute path to the GeoIP Country database file.
; ------
; geoip_country_db = /usr/share/GeoIP/GeoLite2-Country.mmdb
; ===========================
; | Multiprocessing options |
; ===========================
; ------
; --workers | type = int | Specify the number of workers, 0 disable prefork mode.
; ------
; workers =
; ------
; --limit-memory-soft | type = int | Maximum allowed virtual memory per worker (in bytes), when reached the worker be reset after the current request (default 2048MiB).
; ------
; limit_memory_soft = 2147483648
; ------
; --limit-memory-soft-gevent | type = int | Maximum allowed virtual memory per gevent worker (in bytes), when reached the worker will be reset after the current request. Defaults to `--limit-memory-soft`.
; ------
; limit_memory_soft_gevent = False
; ------
; --limit-memory-hard | type = int | Maximum allowed virtual memory per worker (in bytes), when reached, any memory allocation will fail (default 2560MiB).
; ------
; limit_memory_hard = 2684354560
; ------
; --limit-memory-hard-gevent | type = int | Maximum allowed virtual memory per gevent worker (in bytes), when reached, any memory allocation will fail. Defaults to `--limit-memory-hard`.
; ------
; limit_memory_hard_gevent = False
; ------
; --limit-time-cpu | type = int | Maximum allowed CPU time per request (default 60).
; ------
; limit_time_cpu = 60
; ------
; --limit-time-real | type = int | Maximum allowed Real time per request (default 120).
; ------
; limit_time_real = 120
; ------
; --limit-time-real-cron | type = int | Maximum allowed Real time per cron job. (default: --limit-time-real). Set to 0 for no limit.
; ------
; limit_time_real_cron = -1
; ------
; --limit-request | type = int | Maximum number of request to be processed per worker (default 8192).
; ------
; limit_request = 8192

8
etc/requirements.txt Normal file
View File

@ -0,0 +1,8 @@
# -----------------------
# | Add Python packages |
# -----------------------
# To install below packages at startup, uncomment this line in "docker-compose.yml" file!
# - ./entrypoint.sh:/entrypoint.sh
# then down the docker container ($ docker-compose down) and up it again ($ docker-compose up -d).
# -----------------------
# paramiko==2.7.2 # for auto_backup module

19
run.sh Normal file
View File

@ -0,0 +1,19 @@
#!/bin/bash
DESTINATION=$1
PORT=$2
CHAT=$3
# clone Odoo directory
git clone --depth=1 https://github.com/minhng92/odoo-18-docker-compose $DESTINATION
rm -rf $DESTINATION/.git
# set permission
mkdir -p $DESTINATION/postgresql
sudo chmod -R 777 $DESTINATION
# config
if grep -qF "fs.inotify.max_user_watches" /etc/sysctl.conf; then echo $(grep -F "fs.inotify.max_user_watches" /etc/sysctl.conf); else echo "fs.inotify.max_user_watches = 524288" | sudo tee -a /etc/sysctl.conf; fi
sudo sysctl -p
sed -i 's/10018/'$PORT'/g' $DESTINATION/docker-compose.yml
sed -i 's/20018/'$CHAT'/g' $DESTINATION/docker-compose.yml
# run Odoo
docker-compose -f $DESTINATION/docker-compose.yml up -d
echo 'Started Odoo @ http://localhost:'$PORT' | Master Password: minhng.info | Live chat port: '$CHAT