├── .gitignore ├── README.md ├── addons └── readme.md ├── docker-compose.yml ├── entrypoint.sh ├── etc ├── logrotate ├── odoo.conf └── requirements.txt ├── run.sh └── screenshots ├── odoo-17-apps-screenshot.png ├── odoo-17-product-form.png ├── odoo-17-sales-screen.png └── odoo-17-welcome-screenshot.png /.gitignore: -------------------------------------------------------------------------------- 1 | postgresql/ 2 | etc/odoo-server.log 3 | etc/addons/ 4 | etc/sessions/ 5 | etc/filestore/ 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Installing Odoo 17.0 with one command (Supports multiple Odoo instances on one server). 2 | 3 | ## Quick Installation 4 | 5 | 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:10017` (default master password: `minhng.info`): 6 | 7 | ``` bash 8 | curl -s https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/master/run.sh | bash -s odoo-one 10017 20017 9 | ``` 10 | and/or run the following to set up another Odoo instance @ `localhost:11017` (default master password: `minhng.info`): 11 | 12 | ``` bash 13 | curl -s https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/master/run.sh | bash -s odoo-two 11017 21017 14 | ``` 15 | 16 | Some arguments: 17 | * First argument (**odoo-one**): Odoo deploy folder 18 | * Second argument (**10017**): Odoo port 19 | * Third argument (**20017**): live chat port 20 | 21 | If `curl` is not found, install it: 22 | 23 | ``` bash 24 | $ sudo apt-get install curl 25 | # or 26 | $ sudo yum install curl 27 | ``` 28 | 29 | ## Usage 30 | 31 | Start the container: 32 | ``` sh 33 | docker-compose up 34 | ``` 35 | Then open `localhost:10017` to access Odoo 17. 36 | 37 | - **If you get any permission issues**, change the folder permission to make sure that the container is able to access the directory: 38 | 39 | ``` sh 40 | $ sudo chmod -R 777 addons 41 | $ sudo chmod -R 777 etc 42 | $ sudo chmod -R 777 postgresql 43 | ``` 44 | 45 | - If you want to start the server with a different port, change **10017** to another value in **docker-compose.yml** inside the parent dir: 46 | 47 | ``` 48 | ports: 49 | - "10017:8069" 50 | ``` 51 | 52 | - To run Odoo container in detached mode (be able to close terminal without stopping Odoo): 53 | 54 | ``` 55 | docker-compose up -d 56 | ``` 57 | 58 | - 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: 59 | - `no` = Do not automatically restart the container. (the default) 60 | - `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. 61 | - `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) 62 | - `unless-stopped` = Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts. 63 | ``` 64 | restart: always # run as a service 65 | ``` 66 | 67 | - 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: 68 | 69 | ``` 70 | $ 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 71 | $ sudo sysctl -p # apply new config immediately 72 | ``` 73 | 74 | ## Custom addons 75 | 76 | The **addons/** folder contains custom addons. Just put your custom addons if you have any. 77 | 78 | ## Odoo configuration & log 79 | 80 | * To change Odoo configuration, edit file: **etc/odoo.conf**. 81 | * Log file: **etc/odoo-server.log** 82 | * Default database password (**admin_passwd**) is `minhng.info`, please change it @ [etc/odoo.conf#L60](/etc/odoo.conf#L60) 83 | 84 | ## Odoo container management 85 | 86 | **Run Odoo**: 87 | 88 | ``` bash 89 | docker-compose up -d 90 | ``` 91 | 92 | **Restart Odoo**: 93 | 94 | ``` bash 95 | docker-compose restart 96 | ``` 97 | 98 | **Stop Odoo**: 99 | 100 | ``` bash 101 | docker-compose down 102 | ``` 103 | 104 | ## Live chat 105 | 106 | In [docker-compose.yml#L21](docker-compose.yml#L21), we exposed port **20017** for live-chat on host. 107 | 108 | Configuring **nginx** to activate live chat feature (in production): 109 | 110 | ``` conf 111 | #... 112 | server { 113 | #... 114 | location /longpolling/ { 115 | proxy_pass http://0.0.0.0:20017/longpolling/; 116 | } 117 | #... 118 | } 119 | #... 120 | ``` 121 | 122 | ## docker-compose.yml 123 | 124 | * odoo:17 125 | * postgres:16 126 | 127 | ## Odoo 17.0 screenshots after successful installation. 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ## ☕ Buy Me a Coffee 138 | 139 | If you find this project helpful, consider buying me a coffee to support my work! 140 | 141 | Buy Me A Coffee 142 | -------------------------------------------------------------------------------- /addons/readme.md: -------------------------------------------------------------------------------- 1 | This file is intentionally left blank. -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | db: 4 | image: postgres:16 5 | user: root 6 | environment: 7 | - POSTGRES_USER=odoo 8 | - POSTGRES_PASSWORD=odoo17@2023 9 | - POSTGRES_DB=postgres 10 | restart: always # run as a service 11 | volumes: 12 | - ./postgresql:/var/lib/postgresql/data 13 | 14 | odoo17: 15 | image: odoo:17 16 | user: root 17 | depends_on: 18 | - db 19 | ports: 20 | - "10017:8069" 21 | - "20017:8072" # live chat 22 | tty: true 23 | command: -- 24 | environment: 25 | - HOST=db 26 | - USER=odoo 27 | - PASSWORD=odoo17@2023 28 | volumes: 29 | #- /etc/timezone:/etc/timezone:ro 30 | #- /etc/localtime:/etc/localtime:ro 31 | - ./entrypoint.sh:/entrypoint.sh 32 | - ./addons:/mnt/extra-addons 33 | - ./etc:/etc/odoo 34 | restart: always # run as a service 35 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | # set the postgres database host, port, user and password according to the environment 6 | # and pass them as arguments to the odoo process if not present in the config file 7 | : ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} 8 | : ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} 9 | : ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} 10 | : ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo17@2023'}}} 11 | 12 | # install python packages 13 | pip3 install pip --upgrade 14 | pip3 install -r /etc/odoo/requirements.txt 15 | 16 | # sed -i 's|raise werkzeug.exceptions.BadRequest(msg)|self.jsonrequest = {}|g' /usr/lib/python3/dist-packages/odoo/http.py 17 | 18 | # Install logrotate if not already installed 19 | if ! dpkg -l | grep -q logrotate; then 20 | apt-get update && apt-get install -y logrotate 21 | fi 22 | 23 | # Copy logrotate config 24 | cp /etc/odoo/logrotate /etc/logrotate.d/odoo 25 | 26 | # Start cron daemon (required for logrotate) 27 | cron 28 | 29 | DB_ARGS=() 30 | function check_config() { 31 | param="$1" 32 | value="$2" 33 | if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then 34 | value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') 35 | fi; 36 | DB_ARGS+=("--${param}") 37 | DB_ARGS+=("${value}") 38 | } 39 | check_config "db_host" "$HOST" 40 | check_config "db_port" "$PORT" 41 | check_config "db_user" "$USER" 42 | check_config "db_password" "$PASSWORD" 43 | 44 | case "$1" in 45 | -- | odoo) 46 | shift 47 | if [[ "$1" == "scaffold" ]] ; then 48 | exec odoo "$@" 49 | else 50 | wait-for-psql.py ${DB_ARGS[@]} --timeout=30 51 | exec odoo "$@" "${DB_ARGS[@]}" 52 | fi 53 | ;; 54 | -*) 55 | wait-for-psql.py ${DB_ARGS[@]} --timeout=30 56 | exec odoo "$@" "${DB_ARGS[@]}" 57 | ;; 58 | *) 59 | exec "$@" 60 | esac 61 | 62 | exit 1 -------------------------------------------------------------------------------- /etc/logrotate: -------------------------------------------------------------------------------- 1 | /etc/odoo/*.log { 2 | rotate 3 3 | daily 4 | nocompress 5 | missingok 6 | notifempty 7 | copytruncate 8 | } 9 | -------------------------------------------------------------------------------- /etc/odoo.conf: -------------------------------------------------------------------------------- 1 | [options] 2 | ; =================== 3 | ; | Common options) | 4 | ; =================== 5 | ; ------ 6 | ; -c / --config | specify alternate config file 7 | ; ------ 8 | ; config = 9 | 10 | ; ------ 11 | ; -s / --save | save configuration to ~/.odoorc (or to ~/.openerp_serverrc if it exists) 12 | ; ------ 13 | ; save = 14 | 15 | ; ------ 16 | ; -i / --init | install one or more modules (comma-separated list, use "all" for all modules), requires -d 17 | ; ------ 18 | ; init = 19 | 20 | ; ------ 21 | ; -u / --update | update one or more modules (comma-separated list, use "all" for all modules). Requires -d. 22 | ; ------ 23 | ; update = 24 | 25 | ; ------ 26 | ; --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 27 | ; ------ 28 | ; without_demo = 29 | 30 | ; ------ 31 | ; -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. 32 | ; ------ 33 | ; import_partial = 34 | 35 | ; ------ 36 | ; --pidfile | file where the server pid will be stored 37 | ; ------ 38 | ; pidfile = 39 | 40 | ; ------ 41 | ; --addons-path | type = string | specify additional addons paths (separated by commas). 42 | ; ------ 43 | addons_path = /mnt/extra-addons 44 | 45 | ; ------ 46 | ; --upgrade-path | type = string | specify an additional upgrade path. 47 | ; ------ 48 | ; upgrade_path = 49 | 50 | ; ------ 51 | ; --load | Comma-separated list of server-wide modules. 52 | ; ------ 53 | ; server_wide_modules = base,web 54 | 55 | ; ------ 56 | ; -D / --data-dir | Directory where to store Odoo data 57 | ; ------ 58 | data_dir = /etc/odoo 59 | 60 | admin_passwd = minhng.info 61 | 62 | ; ============================== 63 | ; | HTTP Service Configuration | 64 | ; ============================== 65 | ; ------ 66 | ; --http-interface | Listen interface address for HTTP services. Keep empty to listen on all interfaces (0.0.0.0) 67 | ; ------ 68 | ; http_interface = 69 | 70 | ; ------ 71 | ; -p / --http-port | type = int | Listen port for the main HTTP service 72 | ; ------ 73 | ; http_port = 8069 74 | 75 | ; ------ 76 | ; --longpolling-port | type = int | Deprecated alias to the gevent-port option 77 | ; ------ 78 | ; longpolling_port = 8072 79 | 80 | ; ------ 81 | ; --gevent-port | type = int | Listen port for the gevent worker 82 | ; ------ 83 | ; gevent_port = 8072 84 | 85 | ; ------ 86 | ; --no-http | Disable the HTTP and Longpolling services entirely 87 | ; ------ 88 | ; http_enable = True 89 | 90 | ; ------ 91 | ; --proxy-mode | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy! 92 | ; ------ 93 | ; proxy_mode = 94 | 95 | ; ------ 96 | ; --x-sendfile | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy! 97 | ; ------ 98 | ; x_sendfile = False 99 | 100 | ; ------ 101 | ; --xmlrpc-interface | SUPPRESSHELP 102 | ; ------ 103 | ; http_interface = 104 | 105 | ; ------ 106 | ; --xmlrpc-port | type = int | SUPPRESSHELP 107 | ; ------ 108 | ; http_port = 109 | 110 | ; ------ 111 | ; --no-xmlrpc | SUPPRESSHELP 112 | ; ------ 113 | ; http_enable = 114 | 115 | ; =============================== 116 | ; | Web interface Configuration | 117 | ; =============================== 118 | ; ------ 119 | ; --db-filter | Regular expressions for filtering available databases for Web UI. The expression can use %d (domain) and %h (host) placeholders. 120 | ; ------ 121 | ; dbfilter = 122 | 123 | ; ========================= 124 | ; | Testing Configuration | 125 | ; ========================= 126 | ; ------ 127 | ; --test-file | Launch a python test file. 128 | ; ------ 129 | ; test_file = 130 | 131 | ; ------ 132 | ; --test-enable | Enable unit tests. 133 | ; ------ 134 | ; test_enable = 135 | 136 | ; ------ 137 | ; --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 138 | ; ------ 139 | ; test_tags = 140 | 141 | ; ------ 142 | ; --screencasts | Screencasts will go in DIR/{db_name}/screencasts. 143 | ; ------ 144 | ; screencasts = 145 | 146 | ; ------ 147 | ; --screenshots | Screenshots will go in DIR/{db_name}/screenshots. Defaults to /etc/odoo/odoo_tests. 148 | ; ------ 149 | ; screenshots = /etc/odoo/odoo_tests 150 | 151 | ; ========================= 152 | ; | Logging Configuration | 153 | ; ========================= 154 | ; ------ 155 | ; --logfile | file where the server log will be stored 156 | ; ------ 157 | logfile = /etc/odoo/odoo-server.log 158 | 159 | ; ------ 160 | ; --syslog | Send the log to the syslog server 161 | ; ------ 162 | ; syslog = 163 | 164 | ; ------ 165 | ; --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") 166 | ; ------ 167 | ; None = :INFO 168 | 169 | ; ------ 170 | ; --log-web | shortcut for --log-handler=odoo.http:DEBUG 171 | ; ------ 172 | ; log_handler = 173 | 174 | ; ------ 175 | ; --log-sql | shortcut for --log-handler=odoo.sql_db:DEBUG 176 | ; ------ 177 | ; log_handler = 178 | 179 | ; ------ 180 | ; --log-db | Logging database 181 | ; ------ 182 | ; log_db = 183 | 184 | ; ------ 185 | ; --log-db-level | Logging database level 186 | ; ------ 187 | ; log_db_level = warning 188 | 189 | ; ------ 190 | ; --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']. 191 | ; ------ 192 | ; log_level = info 193 | 194 | ; ====================== 195 | ; | SMTP Configuration | 196 | ; ====================== 197 | ; ------ 198 | ; --email-from | specify the SMTP email address for sending email 199 | ; ------ 200 | ; email_from = 201 | 202 | ; ------ 203 | ; --from-filter | specify for which email address the SMTP configuration can be used 204 | ; ------ 205 | ; from_filter = False 206 | 207 | ; ------ 208 | ; --smtp | specify the SMTP server for sending email 209 | ; ------ 210 | ; smtp_server = localhost 211 | 212 | ; ------ 213 | ; --smtp-port | type = int | specify the SMTP port 214 | ; ------ 215 | ; smtp_port = 25 216 | 217 | ; ------ 218 | ; --smtp-ssl | if passed, SMTP connections will be encrypted with SSL (STARTTLS) 219 | ; ------ 220 | ; smtp_ssl = 221 | 222 | ; ------ 223 | ; --smtp-user | specify the SMTP username for sending email 224 | ; ------ 225 | ; smtp_user = 226 | 227 | ; ------ 228 | ; --smtp-password | specify the SMTP password for sending email 229 | ; ------ 230 | ; smtp_password = 231 | 232 | ; ------ 233 | ; --smtp-ssl-certificate-filename | specify the SSL certificate used for authentication 234 | ; ------ 235 | ; smtp_ssl_certificate_filename = False 236 | 237 | ; ------ 238 | ; --smtp-ssl-private-key-filename | specify the SSL private key used for authentication 239 | ; ------ 240 | ; smtp_ssl_private_key_filename = False 241 | 242 | ; ============================ 243 | ; | Database related options | 244 | ; ============================ 245 | ; ------ 246 | ; -d / --database | specify the database name 247 | ; ------ 248 | ; db_name = 249 | 250 | ; ------ 251 | ; -r / --db_user | specify the database user name 252 | ; ------ 253 | ; db_user = 254 | 255 | ; ------ 256 | ; -w / --db_password | specify the database password 257 | ; ------ 258 | ; db_password = 259 | 260 | ; ------ 261 | ; --pg_path | specify the pg executable path 262 | ; ------ 263 | ; pg_path = 264 | 265 | ; ------ 266 | ; --db_host | specify the database host 267 | ; ------ 268 | ; db_host = 269 | 270 | ; ------ 271 | ; --db_port | type = int | specify the database port 272 | ; ------ 273 | ; db_port = 274 | 275 | ; ------ 276 | ; --db_sslmode | type = choice | choices = ['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full'] | specify the database ssl connection mode (see PostgreSQL documentation) 277 | ; ------ 278 | ; db_sslmode = prefer 279 | 280 | ; ------ 281 | ; --db_maxconn | type = int | specify the maximum number of physical connections to PostgreSQL 282 | ; ------ 283 | ; db_maxconn = 64 284 | 285 | ; ------ 286 | ; --db_maxconn_gevent | type = int | specify the maximum number of physical connections to PostgreSQL specifically for the gevent worker 287 | ; ------ 288 | ; db_maxconn_gevent = False 289 | 290 | ; ------ 291 | ; --db-template | specify a custom database template to create a new database 292 | ; ------ 293 | ; db_template = template0 294 | 295 | ; ======================== 296 | ; | Internationalisation | 297 | ; ======================== 298 | ; ------ 299 | ; --load-language | specifies the languages for the translations you want to be loaded 300 | ; ------ 301 | ; load_language = 302 | 303 | ; ------ 304 | ; -l / --language | specify the language of the translation file. Use it with --i18n-export or --i18n-import 305 | ; ------ 306 | ; language = 307 | 308 | ; ------ 309 | ; --i18n-export | export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit 310 | ; ------ 311 | ; translate_out = 312 | 313 | ; ------ 314 | ; --i18n-import | import a CSV or a PO file with translations and exit. The '-l' option is required. 315 | ; ------ 316 | ; translate_in = 317 | 318 | ; ------ 319 | ; --i18n-overwrite | overwrites existing translation terms on updating a module or importing a CSV or a PO file. 320 | ; ------ 321 | ; overwrite_existing_translations = 322 | 323 | ; ------ 324 | ; --modules | specify modules to export. Use in combination with --i18n-export 325 | ; ------ 326 | ; translate_modules = 327 | 328 | ; ============================ 329 | ; | Security-related options | 330 | ; ============================ 331 | ; ------ 332 | ; --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 333 | ; ------ 334 | ; list_db = True 335 | 336 | ; ==================== 337 | ; | Advanced options | 338 | ; ==================== 339 | ; ------ 340 | ; --dev | type = string | Enable developer mode. Param: List of options separated by comma. Options : all, [pudb|wdb|ipdb|pdb], reload, qweb, werkzeug, xml 341 | ; ------ 342 | dev_mode = reload 343 | 344 | ; ------ 345 | ; --shell-interface | type = string | Specify a preferred REPL to use in shell mode. Supported REPLs are: [ipython|ptpython|bpython|python] 346 | ; ------ 347 | ; shell_interface = 348 | 349 | ; ------ 350 | ; --stop-after-init | stop the server after its initialization 351 | ; ------ 352 | ; stop_after_init = 353 | 354 | ; ------ 355 | ; --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. 356 | ; ------ 357 | ; osv_memory_count_limit = 358 | 359 | ; ------ 360 | ; --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. 361 | ; ------ 362 | ; transient_age_limit = 1.0 363 | 364 | ; ------ 365 | ; --osv-memory-age-limit | type = float | Deprecated alias to the transient-age-limit option 366 | ; ------ 367 | ; osv_memory_age_limit = 368 | 369 | ; ------ 370 | ; --max-cron-threads | type = int | Maximum number of threads processing concurrently cron jobs (default 2). 371 | ; ------ 372 | ; max_cron_threads = 2 373 | 374 | ; ------ 375 | ; --unaccent | Try to enable the unaccent extension when creating new databases. 376 | ; ------ 377 | ; unaccent = 378 | 379 | ; ------ 380 | ; --geoip-city-db / --geoip-db | Absolute path to the GeoIP City database file. 381 | ; ------ 382 | ; geoip_city_db = /usr/share/GeoIP/GeoLite2-City.mmdb 383 | 384 | ; ------ 385 | ; --geoip-country-db | Absolute path to the GeoIP Country database file. 386 | ; ------ 387 | ; geoip_country_db = /usr/share/GeoIP/GeoLite2-Country.mmdb 388 | 389 | ; =========================== 390 | ; | Multiprocessing options | 391 | ; =========================== 392 | ; ------ 393 | ; --workers | type = int | Specify the number of workers, 0 disable prefork mode. 394 | ; ------ 395 | ; workers = 396 | 397 | ; ------ 398 | ; --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). 399 | ; ------ 400 | ; limit_memory_soft = 2147483648 401 | 402 | ; ------ 403 | ; --limit-memory-hard | type = int | Maximum allowed virtual memory per worker (in bytes), when reached, any memory allocation will fail (default 2560MiB). 404 | ; ------ 405 | ; limit_memory_hard = 2684354560 406 | 407 | ; ------ 408 | ; --limit-time-cpu | type = int | Maximum allowed CPU time per request (default 60). 409 | ; ------ 410 | ; limit_time_cpu = 60 411 | 412 | ; ------ 413 | ; --limit-time-real | type = int | Maximum allowed Real time per request (default 120). 414 | ; ------ 415 | ; limit_time_real = 120 416 | 417 | ; ------ 418 | ; --limit-time-real-cron | type = int | Maximum allowed Real time per cron job. (default: --limit-time-real). Set to 0 for no limit. 419 | ; ------ 420 | ; limit_time_real_cron = -1 421 | 422 | ; ------ 423 | ; --limit-request | type = int | Maximum number of request to be processed per worker (default 8192). 424 | ; ------ 425 | ; limit_request = 8192 426 | -------------------------------------------------------------------------------- /etc/requirements.txt: -------------------------------------------------------------------------------- 1 | # ----------------------- 2 | # | Add Python packages | 3 | # ----------------------- 4 | # To install below packages at startup, uncomment this line in "docker-compose.yml" file! 5 | # - ./entrypoint.sh:/entrypoint.sh 6 | # then down the docker container ($ docker-compose down) and up it again ($ docker-compose up -d). 7 | # ----------------------- 8 | # paramiko==2.7.2 # for auto_backup module 9 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | DESTINATION=$1 3 | PORT=$2 4 | CHAT=$3 5 | 6 | # Clone Odoo directory 7 | git clone --depth=1 https://github.com/minhng92/odoo-17-docker-compose $DESTINATION 8 | rm -rf $DESTINATION/.git 9 | 10 | # Create PostgreSQL directory 11 | mkdir -p $DESTINATION/postgresql 12 | 13 | # Change ownership to current user and set restrictive permissions for security 14 | sudo chown -R $USER:$USER $DESTINATION 15 | sudo chmod -R 700 $DESTINATION # Only the user has access 16 | 17 | # Check if running on macOS 18 | if [[ "$OSTYPE" == "darwin"* ]]; then 19 | echo "Running on macOS. Skipping inotify configuration." 20 | else 21 | # System configuration 22 | if grep -qF "fs.inotify.max_user_watches" /etc/sysctl.conf; then 23 | echo $(grep -F "fs.inotify.max_user_watches" /etc/sysctl.conf) 24 | else 25 | echo "fs.inotify.max_user_watches = 524288" | sudo tee -a /etc/sysctl.conf 26 | fi 27 | sudo sysctl -p 28 | fi 29 | 30 | # Set ports in docker-compose.yml 31 | # Update docker-compose configuration 32 | if [[ "$OSTYPE" == "darwin"* ]]; then 33 | # macOS sed syntax 34 | sed -i '' 's/10017/'$PORT'/g' $DESTINATION/docker-compose.yml 35 | sed -i '' 's/20017/'$CHAT'/g' $DESTINATION/docker-compose.yml 36 | else 37 | # Linux sed syntax 38 | sed -i 's/10017/'$PORT'/g' $DESTINATION/docker-compose.yml 39 | sed -i 's/20017/'$CHAT'/g' $DESTINATION/docker-compose.yml 40 | fi 41 | 42 | # Set file and directory permissions after installation 43 | find $DESTINATION -type f -exec chmod 644 {} \; 44 | find $DESTINATION -type d -exec chmod 755 {} \; 45 | 46 | chmod +x $DESTINATION/entrypoint.sh 47 | 48 | # Run Odoo 49 | if ! is_present="$(type -p "docker-compose")" || [[ -z $is_present ]]; then 50 | docker compose -f $DESTINATION/docker-compose.yml up -d 51 | else 52 | docker-compose -f $DESTINATION/docker-compose.yml up -d 53 | fi 54 | 55 | echo "Odoo started at http://localhost:$PORT | Master Password: minhng.info | Live chat port: $CHAT" -------------------------------------------------------------------------------- /screenshots/odoo-17-apps-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/353f56d6cff25166857c66016968e3c2c82afe82/screenshots/odoo-17-apps-screenshot.png -------------------------------------------------------------------------------- /screenshots/odoo-17-product-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/353f56d6cff25166857c66016968e3c2c82afe82/screenshots/odoo-17-product-form.png -------------------------------------------------------------------------------- /screenshots/odoo-17-sales-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/353f56d6cff25166857c66016968e3c2c82afe82/screenshots/odoo-17-sales-screen.png -------------------------------------------------------------------------------- /screenshots/odoo-17-welcome-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minhng92/odoo-17-docker-compose/353f56d6cff25166857c66016968e3c2c82afe82/screenshots/odoo-17-welcome-screenshot.png --------------------------------------------------------------------------------