[MERGE] Forward-port of branch 14.0 to master

This commit is contained in:
Antoine Vandevenne (anv)
2021-07-07 15:40:27 +02:00
220 changed files with 1841 additions and 2574 deletions
+80
View File
@@ -0,0 +1,80 @@
===========================================
Setting up a Content Delivery Network (CDN)
===========================================
.. _reference/cdn/keycdn:
Deploying with KeyCDN_
======================
.. sectionauthor:: Fabien Meghazi
This document will guide you through the setup of a KeyCDN_ account with your
Odoo powered website.
Step 1: Create a pull zone in the KeyCDN dashboard
--------------------------------------------------
.. image:: cdn/keycdn_create_a_pull_zone.png
:class: img-fluid
When creating the zone, enable the CORS option in the
:guilabel:`advanced features` submenu. (more on that later)
.. image:: cdn/keycdn_enable_CORS.png
:class: img-fluid
Once done, you'll have to wait a bit while KeyCDN_ is crawling your website.
.. image:: cdn/keycdn_progressbar.png
:class: img-fluid
.. note:: a new URL has been generated for your Zone, in this case it is
``http://pulltest-b49.kxcdn.com``
Step 2: Configure the odoo instance with your zone
--------------------------------------------------
In the Odoo back end, go to the :guilabel:`Website Settings`: menu, then
activate the CDN support and copy/paste your zone URL in the
:guilabel:`CDN Base URL` field. This field is only visible and configurable if
you have developer mode activated.
.. image:: cdn/odoo_cdn_base_url.png
:class: img-fluid
Now your website is using the CDN for the resources matching the
:guilabel:`CDN filters` regular expressions.
You can have a look to the HTML of your website in order to check if the CDN
integration is properly working.
.. image:: cdn/odoo_check_your_html.png
:class: img-fluid
Why should I activate CORS?
---------------------------
A security restriction in some browsers (Firefox and Chrome at time of writing)
prevents a remotely linked CSS file to fetch relative resources on this same
external server.
If you don't activate the CORS option in the CDN zone, the more obvious
resulting problem on a default Odoo website will be the lack of font-awesome
icons because the font file declared in the font-awesome CSS won't be loaded on
the remote server.
Here's what you would see on your homepage in such a case:
.. image:: cdn/odoo_font_file_not_loaded.png
:class: img-fluid
A security error message will also appear in the browser's console:
.. image:: cdn/odoo_security_message.png
:class: img-fluid
Enabling the CORS option in the CDN fixes this issue.
.. _KeyCDN: https://www.keycdn.com
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

+660
View File
@@ -0,0 +1,660 @@
====================
System configuration
====================
This document describes basic steps to set up Odoo in production or on an
internet-facing server. It follows :ref:`installation <setup/install>`, and is
not generally necessary for a development systems that is not exposed on the
internet.
.. warning:: If you are setting up a public server, be sure to check our :ref:`security` recommandations!
.. _db_filter:
dbfilter
========
Odoo is a multi-tenant system: a single Odoo system may run and serve a number
of database instances. It is also highly customizable, with customizations
(starting from the modules being loaded) depending on the "current database".
This is not an issue when working with the backend (web client) as a logged-in
company user: the database can be selected when logging in, and customizations
loaded afterwards.
However it is an issue for non-logged users (portal, website) which aren't
bound to a database: Odoo needs to know which database should be used to load
the website page or perform the operation. If multi-tenancy is not used that is not an
issue, there's only one database to use, but if there are multiple databases
accessible Odoo needs a rule to know which one it should use.
That is one of the purposes of :option:`--db-filter <odoo-bin --db-filter>`:
it specifies how the database should be selected based on the hostname (domain)
that is being requested. The value is a `regular expression`_, possibly
including the dynamically injected hostname (``%h``) or the first subdomain
(``%d``) through which the system is being accessed.
For servers hosting multiple databases in production, especially if ``website``
is used, dbfilter **must** be set, otherwise a number of features will not work
correctly.
Configuration samples
---------------------
* Show only databases with names beginning with 'mycompany'
in ``/etc/odoo.conf`` set:
.. code-block:: ini
[options]
dbfilter = ^mycompany.*$
* Show only databases matching the first subdomain after ``www``: for example
the database "mycompany" will be shown if the incoming request
was sent to ``www.mycompany.com`` or ``mycompany.co.uk``, but not
for ``www2.mycompany.com`` or ``helpdesk.mycompany.com``.
in ``/etc/odoo.conf`` set:
.. code-block:: ini
[options]
dbfilter = ^%d$
.. note::
Setting a proper :option:`--db-filter <odoo-bin --db-filter>` is an important part
of securing your deployment.
Once it is correctly working and only matching a single database per hostname, it
is strongly recommended to block access to the database manager screens,
and to use the ``--no-database-list`` startup parameter to prevent listing
your databases, and to block access to the database management screens.
See also security_.
PostgreSQL
==========
By default, PostgreSQL only allows connection over UNIX sockets and loopback
connections (from "localhost", the same machine the PostgreSQL server is
installed on).
UNIX socket is fine if you want Odoo and PostgreSQL to execute on the same
machine, and is the default when no host is provided, but if you want Odoo and
PostgreSQL to execute on different machines [#different-machines]_ it will
need to `listen to network interfaces`_ [#remote-socket]_, either:
* Only accept loopback connections and `use an SSH tunnel`_ between the
machine on which Odoo runs and the one on which PostgreSQL runs, then
configure Odoo to connect to its end of the tunnel
* Accept connections to the machine on which Odoo is installed, possibly
over ssl (see `PostgreSQL connection settings`_ for details), then configure
Odoo to connect over the network
Configuration sample
--------------------
* Allow tcp connection on localhost
* Allow tcp connection from 192.168.1.x network
in ``/etc/postgresql/9.5/main/pg_hba.conf`` set:
.. code-block:: text
# IPv4 local connections:
host all all 127.0.0.1/32 md5
host all all 192.168.1.0/24 md5
in ``/etc/postgresql/9.5/main/postgresql.conf`` set:
.. code-block:: text
listen_addresses = 'localhost,192.168.1.2'
port = 5432
max_connections = 80
.. _setup/deploy/odoo:
Configuring Odoo
----------------
Out of the box, Odoo connects to a local postgres over UNIX socket via port
5432. This can be overridden using :ref:`the database options
<reference/cmdline/server/database>` when your Postgres deployment is not
local and/or does not use the installation defaults.
The :ref:`packaged installers <setup/install/packaged>` will automatically
create a new user (``odoo``) and set it as the database user.
* The database management screens are protected by the ``admin_passwd``
setting. This setting can only be set using configuration files, and is
simply checked before performing database alterations. It should be set to
a randomly generated value to ensure third parties can not use this
interface.
* All database operations use the :ref:`database options
<reference/cmdline/server/database>`, including the database management
screen. For the database management screen to work requires that the PostgreSQL user
have ``createdb`` right.
* Users can always drop databases they own. For the database management screen
to be completely non-functional, the PostgreSQL user needs to be created with
``no-createdb`` and the database must be owned by a different PostgreSQL user.
.. warning:: the PostgreSQL user *must not* be a superuser
Configuration sample
~~~~~~~~~~~~~~~~~~~~
* connect to a PostgreSQL server on 192.168.1.2
* port 5432
* using an 'odoo' user account,
* with 'pwd' as a password
* filtering only db with a name beginning with 'mycompany'
in ``/etc/odoo.conf`` set:
.. code-block:: ini
[options]
admin_passwd = mysupersecretpassword
db_host = 192.168.1.2
db_port = 5432
db_user = odoo
db_password = pwd
dbfilter = ^mycompany.*$
.. _postgresql_ssl_connect:
SSL Between Odoo and PostgreSQL
-------------------------------
Since Odoo 11.0, you can enforce ssl connection between Odoo and PostgreSQL.
in Odoo the db_sslmode control the ssl security of the connection
with value chosen out of 'disable', 'allow', 'prefer', 'require', 'verify-ca'
or 'verify-full'
`PostgreSQL Doc <https://www.postgresql.org/docs/current/static/libpq-ssl.html>`_
.. _builtin_server:
Builtin server
==============
Odoo includes built-in HTTP servers, using either multithreading or
multiprocessing.
For production use, it is recommended to use the multiprocessing server as it
increases stability, makes somewhat better use of computing resources and can
be better monitored and resource-restricted.
* Multiprocessing is enabled by configuring :option:`a non-zero number of
worker processes <odoo-bin --workers>`, the number of workers should be based
on the number of cores in the machine (possibly with some room for cron
workers depending on how much cron work is predicted)
* Worker limits can be configured based on the hardware configuration to avoid
resources exhaustion
.. warning:: multiprocessing mode currently isn't available on Windows
Worker number calculation
-------------------------
* Rule of thumb : (#CPU * 2) + 1
* Cron workers need CPU
* 1 worker ~= 6 concurrent users
memory size calculation
-----------------------
* We consider 20% of the requests are heavy requests, while 80% are simpler ones
* A heavy worker, when all computed field are well designed, SQL requests are well designed, ... is estimated to consume around 1GB of RAM
* A lighter worker, in the same scenario, is estimated to consume around 150MB of RAM
Needed RAM = #worker * ( (light_worker_ratio * light_worker_ram_estimation) + (heavy_worker_ratio * heavy_worker_ram_estimation) )
LiveChat
--------
In multiprocessing, a dedicated LiveChat worker is automatically started and
listening on :option:`the longpolling port <odoo-bin --longpolling-port>` but
the client will not connect to it.
Instead you must have a proxy redirecting requests whose URL starts with
``/longpolling/`` to the longpolling port. Other request should be proxied to
the :option:`normal HTTP port <odoo-bin --http-port>`
To achieve such a thing, you'll need to deploy a reverse proxy in front of Odoo,
like nginx or apache. When doing so, you'll need to forward some more http Headers
to Odoo, and activate the proxy_mode in Odoo configuration to have Odoo read those
headers.
Configuration sample
--------------------
* Server with 4 CPU, 8 Thread
* 60 concurrent users
* 60 users / 6 = 10 <- theoretical number of worker needed
* (4 * 2) + 1 = 9 <- theoretical maximal number of worker
* We'll use 8 workers + 1 for cron. We'll also use a monitoring system to measure cpu load, and check if it's between 7 and 7.5 .
* RAM = 9 * ((0.8*150) + (0.2*1024)) ~= 3Go RAM for Odoo
in ``/etc/odoo.conf``:
.. code-block:: ini
[options]
limit_memory_hard = 1677721600
limit_memory_soft = 629145600
limit_request = 8192
limit_time_cpu = 600
limit_time_real = 1200
max_cron_threads = 1
workers = 8
.. _https_proxy:
HTTPS
=====
Whether it's accessed via website/web client or web service, Odoo transmits
authentication information in cleartext. This means a secure deployment of
Odoo must use HTTPS\ [#switching]_. SSL termination can be implemented via
just about any SSL termination proxy, but requires the following setup:
* Enable Odoo's :option:`proxy mode <odoo-bin --proxy-mode>`. This should only be enabled when Odoo is behind a reverse proxy
* Set up the SSL termination proxy (`Nginx termination example`_)
* Set up the proxying itself (`Nginx proxying example`_)
* Your SSL termination proxy should also automatically redirect non-secure
connections to the secure port
Configuration sample
--------------------
* Redirect http requests to https
* Proxy requests to odoo
in ``/etc/odoo.conf`` set:
.. code-block:: ini
proxy_mode = True
in ``/etc/nginx/sites-enabled/odoo.conf`` set:
.. code-block:: nginx
#odoo server
upstream odoo {
server 127.0.0.1:8069;
}
upstream odoochat {
server 127.0.0.1:8072;
}
# http -> https
server {
listen 80;
server_name odoo.mycompany.com;
rewrite ^(.*) https://$host$1 permanent;
}
server {
listen 443;
server_name odoo.mycompany.com;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
# Add Headers for odoo proxy mode
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
# SSL parameters
ssl on;
ssl_certificate /etc/ssl/nginx/server.crt;
ssl_certificate_key /etc/ssl/nginx/server.key;
ssl_session_timeout 30m;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# log
access_log /var/log/nginx/odoo.access.log;
error_log /var/log/nginx/odoo.error.log;
# Redirect longpoll requests to odoo longpolling port
location /longpolling {
proxy_pass http://odoochat;
}
# Redirect requests to odoo backend server
location / {
proxy_redirect off;
proxy_pass http://odoo;
}
# common gzip
gzip_types text/css text/scss text/plain text/xml application/xml application/json application/javascript;
gzip on;
}
Odoo as a WSGI Application
==========================
It is also possible to mount Odoo as a standard WSGI_ application. Odoo
provides the base for a WSGI launcher script as ``odoo-wsgi.example.py``. That
script should be customized (possibly after copying it from the setup directory) to correctly set the
configuration directly in :mod:`odoo.tools.config` rather than through the
command-line or a configuration file.
However the WSGI server will only expose the main HTTP endpoint for the web
client, website and webservice API. Because Odoo does not control the creation
of workers anymore it can not setup cron or livechat workers
Cron Workers
------------
To run cron jobs for an Odoo deployment as a WSGI application requires
* A classical Odoo (run via ``odoo-bin``)
* Connected to the database in which cron jobs have to be run (via
:option:`odoo-bin -d`)
* Which should not be exposed to the network. To ensure cron runners are not
network-accessible, it is possible to disable the built-in HTTP server
entirely with :option:`odoo-bin --no-http` or setting ``http_enable = False``
in the configuration file
LiveChat
--------
The second problematic subsystem for WSGI deployments is the LiveChat: where
most HTTP connections are relatively short and quickly free up their worker
process for the next request, LiveChat require a long-lived connection for
each client in order to implement near-real-time notifications.
This is in conflict with the process-based worker model, as it will tie
up worker processes and prevent new users from accessing the system. However,
those long-lived connections do very little and mostly stay parked waiting for
notifications.
The solutions to support livechat/motifications in a WSGI application are:
* Deploy a threaded version of Odoo (instead of a process-based preforking
one) and redirect only requests to URLs starting with ``/longpolling/`` to
that Odoo, this is the simplest and the longpolling URL can double up as
the cron instance.
* Deploy an evented Odoo via ``odoo-gevent`` and proxy requests starting
with ``/longpolling/`` to
:option:`the longpolling port <odoo-bin --longpolling-port>`.
Serving Static Files
====================
For development convenience, Odoo directly serves all static files in its
modules. This may not be ideal when it comes to performances, and static
files should generally be served by a static HTTP server.
Odoo static files live in each module's ``static/`` folder, so static files
can be served by intercepting all requests to :samp:`/{MODULE}/static/{FILE}`,
and looking up the right module (and file) in the various addons paths.
.. todo:: test whether it would be interesting to serve filestored attachments
via this, and how (e.g. possibility of mapping ir.attachment id to
filestore hash in the database?)
.. _security:
Security
========
For starters, keep in mind that securing an information system is a continuous process,
not a one-shot operation. At any moment, you will only be as secure as the weakest link
in your environment.
So please do not take this section as the ultimate list of measures that will prevent
all security problems. It's only intended as a summary of the first important things
you should be sure to include in your security action plan. The rest will come
from best security practices for your operating system and distribution,
best practices in terms of users, passwords, and access control management, etc.
When deploying an internet-facing server, please be sure to consider the following
security-related topics:
- Always set a strong super-admin admin password, and restrict access to the database
management pages as soon as the system is set up. See :ref:`db_manager_security`.
- Choose unique logins and strong passwords for all administrator accounts on all databases.
Do not use 'admin' as the login. Do not use those logins for day-to-day operations,
only for controlling/managing the installation.
*Never* use any default passwords like admin/admin, even for test/staging databases.
- Do **not** install demo data on internet-facing servers. Databases with demo data contain
default logins and passwords that can be used to get into your systems and cause significant
trouble, even on staging/dev systems.
- Use appropriate database filters ( :option:`--db-filter <odoo-bin --db-filter>`)
to restrict the visibility of your databases according to the hostname.
See :ref:`db_filter`.
You may also use :option:`-d <odoo-bin -d>` to provide your own (comma-separated)
list of available databases to filter from, instead of letting the system fetch
them all from the database backend.
- Once your ``db_name`` and ``db_filter`` are configured and only match a single database
per hostname, you should set ``list_db`` configuration option to ``False``, to prevent
listing databases entirely, and to block access to the database management screens
(this is also exposed as the :option:`--no-database-list <odoo-bin --no-database-list>`
command-line option)
- Make sure the PostgreSQL user (:option:`--db_user <odoo-bin --db_user>`) is *not* a super-user,
and that your databases are owned by a different user. For example they could be owned by
the ``postgres`` super-user if you are using a dedicated non-privileged ``db_user``.
See also :ref:`setup/deploy/odoo`.
- Keep installations updated by regularly installing the latest builds,
either via GitHub or by downloading the latest version from
https://www.odoo.com/page/download or http://nightly.odoo.com
- Configure your server in multi-process mode with proper limits matching your typical
usage (memory/CPU/timeouts). See also :ref:`builtin_server`.
- Run Odoo behind a web server providing HTTPS termination with a valid SSL certificate,
in order to prevent eavesdropping on cleartext communications. SSL certificates are
cheap, and many free options exist.
Configure the web proxy to limit the size of requests, set appropriate timeouts,
and then enable the :option:`proxy mode <odoo-bin --proxy-mode>` option.
See also :ref:`https_proxy`.
- If you need to allow remote SSH access to your servers, make sure to set a strong password
for **all** accounts, not just `root`. It is strongly recommended to entirely disable
password-based authentication, and only allow public key authentication. Also consider
restricting access via a VPN, allowing only trusted IPs in the firewall, and/or
running a brute-force detection system such as `fail2ban` or equivalent.
- Consider installing appropriate rate-limiting on your proxy or firewall, to prevent
brute-force attacks and denial of service attacks. See also :ref:`login_brute_force`
for specific measures.
Many network providers provide automatic mitigation for Distributed Denial of
Service attacks (DDOS), but this is often an optional service, so you should consult
with them.
- Whenever possible, host your public-facing demo/test/staging instances on different
machines than the production ones. And apply the same security precautions as for
production.
- If your public-facing Odoo server has access to sensitive internal network resources
or services (e.g. via a private VLAN), implement appropriate firewall rules to
protect those internal resources. This will ensure that the Odoo server cannot
be used accidentally (or as a result of malicious user actions) to access or disrupt
those internal resources.
Typically this can be done by applying an outbound default DENY rule on the firewall,
then only explicitly authorizing access to internal resources that the Odoo server
needs to access.
`Systemd IP traffic access control <http://0pointer.net/blog/ip-accounting-and-access-lists-with-systemd.html>`_
may also be useful to implement per-process network access control.
- If your public-facing Odoo server is behind a Web Application Firewall, a load-balancer,
a transparent DDoS protection service (like CloudFlare) or a similar network-level
device, you may wish to avoid direct access to the Odoo system. It is generally
difficult to keep the endpoint IP addresses of your Odoo servers secret. For example
they can appear in web server logs when querying public systems, or in the headers
of emails posted from Odoo.
In such a situation you may want to configure your firewall so that the endpoints
are not accessible publicly except from the specific IP addresses of your WAF,
load-balancer or proxy service. Service providers like CloudFlare usually maintain
a public list of their IP address ranges for this purpose.
- If you are hosting multiple customers, isolate customer data and files from each other
using containers or appropriate "jail" techniques.
- Setup daily backups of your databases and filestore data, and copy them to a remote
archiving server that is not accessible from the server itself.
.. _login_brute_force:
Blocking Brute Force Attacks
----------------------------
For internet-facing deployments, brute force attacks on user passwords are very common, and this
threat should not be neglected for Odoo servers. Odoo emits a log entry whenever a login attempt
is performed, and reports the result: success or failure, along with the target login and source IP.
The log entries will have the following form.
Failed login::
2018-07-05 14:56:31,506 24849 INFO db_name odoo.addons.base.res.res_users: Login failed for db:db_name login:admin from 127.0.0.1
Successful login::
2018-07-05 14:56:31,506 24849 INFO db_name odoo.addons.base.res.res_users: Login successful for db:db_name login:admin from 127.0.0.1
These logs can be easily analyzed by an intrusion prevention system such as `fail2ban`.
For example, the following fail2ban filter definition should match a
failed login::
[Definition]
failregex = ^ \d+ INFO \S+ \S+ Login failed for db:\S+ login:\S+ from <HOST>
ignoreregex =
This could be used with a jail definition to block the attacking IP on HTTP(S).
Here is what it could look like for blocking the IP for 15 minutes when
10 failed login attempts are detected from the same IP within 1 minute::
[odoo-login]
enabled = true
port = http,https
bantime = 900 ; 15 min ban
maxretry = 10 ; if 10 attempts
findtime = 60 ; within 1 min /!\ Should be adjusted with the TZ offset
logpath = /var/log/odoo.log ; set the actual odoo log path here
.. _db_manager_security:
Database Manager Security
-------------------------
:ref:`setup/deploy/odoo` mentioned ``admin_passwd`` in passing.
This setting is used on all database management screens (to create, delete,
dump or restore databases).
If the management screens must not be accessible at all, you should set ``list_db``
configuration option to ``False``, to block access to all the database selection and
management screens.
.. warning::
It is strongly recommended to disable the Database Manager for any internet-facing
system! It is meant as a development/demo tool, to make it easy to quickly create
and manage databases. It is not designed for use in production, and may even expose
dangerous features to attackers. It is also not designed to handle large databases,
and may trigger memory limits.
On production systems, database management operations should always be performed by
the system administrator, including provisioning of new databases and automated backups.
Be sure to setup an appropriate ``db_name`` parameter
(and optionally, ``db_filter`` too) so that the system can determine the target database
for each request, otherwise users will be blocked as they won't be allowed to choose the
database themselves.
If the management screens must only be accessible from a selected set of machines,
use the proxy server's features to block access to all routes starting with ``/web/database``
except (maybe) ``/web/database/selector`` which displays the database-selection screen.
If the database-management screen should be left accessible, the
``admin_passwd`` setting must be changed from its ``admin`` default: this
password is checked before allowing database-alteration operations.
It should be stored securely, and should be generated randomly e.g.
.. code-block:: console
$ python3 -c 'import base64, os; print(base64.b64encode(os.urandom(24)))'
which will generate a 32 characters pseudorandom printable string.
Supported Browsers
==================
Odoo supports all the major desktop and mobile browsers available on the market,
as long as they are supported by their publishers.
Here are the supported browsers:
- Google Chrome
- Mozilla Firefox
- Microsoft Edge
- Apple Safari
.. warning:: Please make sure your browser is up-to-date and still supported by
its publisher before filing a bug report.
.. note::
Since Odoo 13.0, ES6 is supported. Therefore, IE support is dropped.
.. [#different-machines]
to have multiple Odoo installations use the same PostgreSQL database,
or to provide more computing resources to both software.
.. [#remote-socket]
technically a tool like socat_ can be used to proxy UNIX sockets across
networks, but that is mostly for software which can only be used over
UNIX sockets
.. [#switching]
or be accessible only over an internal packet-switched network, but that
requires secured switches, protections against `ARP spoofing`_ and
precludes usage of WiFi. Even over secure packet-switched networks,
deployment over HTTPS is recommended, and possible costs are lowered as
"self-signed" certificates are easier to deploy on a controlled
environment than over the internet.
.. _regular expression: https://docs.python.org/3/library/re.html
.. _ARP spoofing: https://en.wikipedia.org/wiki/ARP_spoofing
.. _Nginx termination example:
https://nginx.com/resources/admin-guide/nginx-ssl-termination/
.. _Nginx proxying example:
https://nginx.com/resources/admin-guide/reverse-proxy/
.. _socat: http://www.dest-unreach.org/socat/
.. _PostgreSQL connection settings:
.. _listen to network interfaces:
https://www.postgresql.org/docs/9.6/static/runtime-config-connection.html
.. _use an SSH tunnel:
https://www.postgresql.org/docs/9.6/static/ssh-tunnels.html
.. _WSGI: https://wsgi.readthedocs.org/
.. _POSBox: https://www.odoo.com/page/point-of-sale-hardware#part_2
@@ -0,0 +1,47 @@
=============
Email gateway
=============
The Odoo mail gateway allows you to inject directly all the received emails in Odoo.
Its principle is straightforward: your SMTP server executes the "mailgate" script for every new incoming email.
The script takes care of connecting to your Odoo database through XML-RPC, and send the emails via
the `MailThread.message_process()` feature.
Prerequisites
-------------
- Administrator access to the Odoo database.
- Your own mail server such as Postfix or Exim.
- Technical knowledge on how to configure an email server.
For Postfix
-----------
In you alias config (:file:`/etc/aliases`):
.. code-block:: text
email@address: "|/odoo-directory/addons/mail/static/scripts/odoo-mailgate.py -d <database-name> -u <userid> -p <password>"
.. note::
Resources
- `Postfix <http://www.postfix.org/documentation.html>`_
- `Postfix aliases <http://www.postfix.org/aliases.5.html>`_
- `Postfix virtual <http://www.postfix.org/virtual.8.html>`_
For Exim
--------
.. code-block:: text
*: |/odoo-directory/addons/mail/static/scripts/odoo-mailgate.py -d <database-name> -u <userid> -p <password>
.. note::
Resources
- `Exim <https://www.exim.org/docs.html>`_
.. tip::
If you don't have access/manage your email server, use :ref:`inbound messages
<discuss/email_servers/inbound_messages>`.
+782
View File
@@ -0,0 +1,782 @@
.. _setup/install:
===============
Installing Odoo
===============
There are multiple ways to install Odoo, or not install it at all, depending
on the intended use case.
This documents attempts to describe most of the installation options.
:ref:`setup/install/online`
The easiest way to use Odoo in production or to try it.
:ref:`setup/install/packaged`
Suitable for testing Odoo, developing modules and can be used for
long-term production use with additional deployment and maintenance work.
:ref:`setup/install/source`
Provides greater flexibility: e.g. allow multiple running Odoo versions on
the same system. Good for developing modules, can be used as base for
production deployment.
:ref:`setup/install/docker`
If you usually use docker_ for development or deployment, an official
docker_ base image is available.
.. _setup/install/editions:
Editions
========
There are two different Editions_ of Odoo: the Community and Enterprise versions.
Using the Enterprise version is possible on our SaaS_ and accessing the code is
restricted to Enterprise customers and partners. The Community version is freely
available to anyone.
If you already use the Community version and wish to upgrade to Enterprise, please
refer to :ref:`setup/enterprise` (except for :ref:`setup/install/source`).
.. _setup/install/online:
Online
======
Demo
----
To simply get a quick idea of Odoo, demo_ instances are available. They are
shared instances which only live for a few hours, and can be used to browse
around and try things out with no commitment.
Demo_ instances require no local installation, just a web browser.
SaaS
----
Trivial to start with, fully managed and migrated by Odoo S.A., Odoo's SaaS_
provides private instances and starts out free. It can be used to discover and
test Odoo and do non-code customizations (i.e. incompatible with custom modules
or the Odoo Apps Store) without having to install it locally.
Can be used for both testing Odoo and long-term production use.
Like demo_ instances, SaaS_ instances require no local installation, a web
browser is sufficient.
.. _setup/install/packaged:
Packaged installers
===================
Odoo provides packaged installers for Windows, deb-based distributions
(Debian, Ubuntu, …) and RPM-based distributions (Fedora, CentOS, RHEL, …) for
both the Community and Enterprise versions.
These packages automatically set up all dependencies (for the Community version),
but may be difficult to keep up-to-date.
Official Community packages with all relevant dependency requirements are
available on our nightly_ server. Both Communtiy and Enterprise packages can
be downloaded from our download_ page (you must to be logged in as a paying
customer or partner to download the Enterprise packages).
Windows
-------
#. Download the installer from our nightly_ server (Community only) or the Windows installer from
the download_ page (any edition).
#. Execute the downloaded file.
.. warning:: | On Windows 8 and later you may see a warning titled "Windows protected your PC".
| Click on **More Info** and then on **Run anyway**.
#. Accept the UAC_ prompt.
#. Go through the various installation steps.
Odoo will automatically be started at the end of the installation.
Linux
-----
Debian/Ubuntu
'''''''''''''
Odoo 13.0 'deb' package currently supports `Debian Buster`_, `Ubuntu 18.04`_ or above.
Prepare
^^^^^^^
Odoo needs a `PostgreSQL`_ server to run properly. The default configuration for
the Odoo 'deb' package is to use the PostgreSQL server on the same host as your
Odoo instance. Execute the following command in order to install the PostgreSQL server:
.. code-block:: console
$ sudo apt install postgresql -y
.. warning:: `wkhtmltopdf` is not installed through **pip** and must be installed manually in
version `0.12.5 <the wkhtmltopdf download page_>`_ for it to support headers and
footers. See our `wiki <https://github.com/odoo/odoo/wiki/Wkhtmltopdf>`_ for more
details on the various versions.
Repository
^^^^^^^^^^
Odoo S.A. provides a repository that can be used with Debian and Ubuntu distributions. It can be
used to install *Odoo Community Edition* by executing the following commands **as root**:
.. code-block:: console
# wget -O - https://nightly.odoo.com/odoo.key | apt-key add -
# echo "deb http://nightly.odoo.com/13.0/nightly/deb/ ./" >> /etc/apt/sources.list.d/odoo.list
# apt-get update && apt-get install odoo
You can then use the usual `apt-get upgrade` command to keep your installation up-to-date.
At this moment, there is no nightly repository for the Enterprise Edition.
Deb Package
^^^^^^^^^^^
Instead of using the repository as described above, the 'deb' packages for both the *Community* and
*Enterprise* editions can be downloaded from the `official download page <download_>`_.
Next, execute the following commands **as root**:
.. code-block:: console
# dpkg -i <path_to_installation_package> # this probably fails with missing dependencies
# apt-get install -f # should install the missing dependencies
# dpkg -i <path_to_installation_package>
This will install Odoo as a service, create the necessary PostgreSQL_ user
and automatically start the server.
.. warning:: The `python3-xlwt` Debian package does not exists in Debian Buster nor Ubuntu 18.04.
This python module is needed to export into xls format.
If you need the feature, you can install it manually with:
.. code-block:: console
$ sudo pip3 install xlwt
.. warning:: The `num2words` python package does not exists in Debian Buster nor Ubuntu 18.04.
Textual amounts will not be rendered by Odoo and this could cause problems with the
`l10n_mx_edi` module.
If you need this feature, you can install manually with:
.. code-block:: console
$ sudo pip3 install num2words
Fedora
''''''
Odoo 13.0 'rpm' package supports Fedora 30.
Prepare
^^^^^^^
Odoo needs a `PostgreSQL`_ server to run properly. Make sure that the `sudo` command is available
and well configured and, only then, execute the following command in order to install the PostgreSQL
server:
.. code-block:: console
$ sudo dnf install -y postgresql-server
$ sudo postgresql-setup --initdb --unit postgresql
$ sudo systemctl enable postgresql
$ sudo systemctl start postgresql
.. warning:: `wkhtmltopdf` is not installed through **pip** and must be installed manually in
version `0.12.5 <the wkhtmltopdf download page_>`_ for it to support headers and
footers. See our `wiki <https://github.com/odoo/odoo/wiki/Wkhtmltopdf>`_ for more
details on the various versions.
Repository
^^^^^^^^^^
Odoo S.A. provides a repository that can be used with the Fedora distributions.
It can be used to install *Odoo Community Edition* by executing the following
commands:
.. code-block:: console
$ sudo dnf config-manager --add-repo=https://nightly.odoo.com/13.0/nightly/rpm/odoo.repo
$ sudo dnf install -y odoo
$ sudo systemctl enable odoo
$ sudo systemctl start odoo
RPM package
^^^^^^^^^^^
Instead of using the repository as described above, the 'rpm' packages for both the *Community* and
*Enterprise* editions can be downloaded from the `official download page <download_>`_.
Once downloaded, the package can be installed using the 'dnf' package manager:
.. code-block:: console
$ sudo dnf localinstall odoo_13.0.latest.noarch.rpm
$ sudo systemctl enable odoo
$ sudo systemctl start odoo
.. _setup/install/source:
Source Install
==============
The source "installation" is really about not installing Odoo, and running it directly from source
instead.
This can be more convenient for module developers as the Odoo source is more easily accessible
than using packaged installation (for information or to build this documentation and have it
available offline).
It also makes starting and stopping Odoo more flexible and explicit than the services set up by the
packaged installations, and allows overriding settings using
:ref:`command-line parameters <reference/cmdline>` without needing to edit a configuration file.
Finally it provides greater control over the system's set up, and allows to more easily keep
(and run) multiple versions of Odoo side-by-side.
Windows
-------
Fetch the sources
'''''''''''''''''
There are two ways to obtain the source code of Odoo: as a zip **archive** or through **git**.
Archive
^^^^^^^
Community Edition:
* `Official download page <download_>`_
* `GitHub repository <community-repository_>`_
* `Nightly server <nightly_>`_
Enterprise Edition:
* `Official download page <download_>`_
* `GitHub repository <enterprise-repository_>`_
Git
^^^
The following requires git_ to be installed on your machine and that you have basic knowledge of
git commands.
Community Edition:
.. code-block:: doscon
C:\> git clone https://github.com/odoo/odoo.git
Enterprise Edition: (see :ref:`setup/install/editions` to get access)
.. code-block:: doscon
C:\> git clone https://github.com/odoo/enterprise.git
.. note:: **The Enterprise git repository does not contain the full Odoo source code**. It is only
a collection of extra add-ons. The main server code is in the Community version. Running
the Enterprise version actually means running the server from the Community version with
the addons-path option set to the folder with the Enterprise version. You need to clone
both the Community and Enterprise repository to have a working Odoo Enterprise
installation.
Prepare
'''''''
Python
^^^^^^
Odoo requires Python 3.6 or later to run. Visit `Python's download page <https://www.python.org/downloads/windows/>`_
to download and install the latest version of Python 3 on your machine.
During installation, check **Add Python 3 to PATH**, then click **Customize Installation** and make
sure that **pip** is checked.
.. note:: If Python 3 is already installed, make sure that the version is 3.6 or above, as previous
versions are not compatible with Odoo.
.. code-block:: doscon
C:\> python --version
Verify also that pip_ is installed for this version.
.. code-block:: doscon
C:\> pip --version
PostgreSQL
^^^^^^^^^^
Odoo uses PostgreSQL as database management system. `Download and install PostgreSQL <https://www.postgresql.org/download/windows/>`_
(supported version: 10.0 and later).
By default, the only user is `postgres` but Odoo forbids connecting as `postgres`, so you need to
create a new PostgreSQL user:
#. Add PostgreSQL's `bin` directory (by default: `C:\\Program Files\\PostgreSQL\\<version>\\bin`) to
your `PATH`.
#. Create a postgres user with a password using the pg admin gui:
1. Open **pgAdmin**.
2. Double-click the server to create a connection.
3. Select :menuselection:`Object --> Create --> Login/Group Role`.
4. Enter the username in the **Role Name** field (e.g. `odoo`).
5. Open the **Definition** tab and enter the password (e.g. ``odoo``), then click **Save**.
6. Open the **Privileges** tab and switch **Can login?** to `Yes` and **Create database?** to
`Yes`.
Dependencies
^^^^^^^^^^^^
Before installing the dependencies, you must download and install the
`Build Tools for Visual Studio <https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019>`_.
When prompted, select **C++ build tools** in the **Workloads** tab and install them.
Odoo dependencies are listed in the `requirements.txt` file located at the root of the Odoo
community directory.
.. tip:: It can be preferable to not mix python modules packages between different instances of Odoo
or with your system. You can use virtualenv_ to create isolated Python environments.
Navigate to the path of your Odoo Community installation (`CommunityPath`) and run **pip**
on the requirements file in a terminal **with Administrator privileges**:
.. code-block:: doscon
C:\> cd \CommunityPath
C:\> pip install setuptools wheel
C:\> pip install -r requirements.txt
.. warning:: `wkhtmltopdf` is not installed through **pip** and must be installed manually in
version `0.12.5 <the wkhtmltopdf download page_>`_ for it to support headers and
footers. See our `wiki <https://github.com/odoo/odoo/wiki/Wkhtmltopdf>`_ for more
details on the various versions.
For languages with right-to-left interface (such as Arabic or Hebrew), the package `rtlcss` is
needed:
#. Download and install `nodejs <https://nodejs.org/en/download/>`_.
#. Install `rtlcss`:
.. code-block:: doscon
C:\> npm install -g rtlcss
#. Edit the System Environment's variable `PATH` to add the folder where `rtlcss.cmd` is located
(typically: `C:\\Users\\<user>\\AppData\\Roaming\\npm\\`).
Running Odoo
''''''''''''
Once all dependencies are set up, Odoo can be launched by running `odoo-bin`, the
command-line interface of the server. It is located at the root of the Odoo Community directory.
To configure the server, you can either specify :ref:`command-line arguments <reference/cmdline/server>` or a
:ref:`configuration file <reference/cmdline/config>`.
.. tip:: For the Enterprise edition, you must add the path to the `enterprise` addons to the
`addons-path` argument. Note that it must come before the other paths in `addons-path` for
addons to be loaded correctly.
Common necessary configurations are:
* PostgreSQL user and password.
* Custom addon paths beyond the defaults, to load your own modules.
A typical way to run the server would be:
.. code-block:: doscon
C:\> cd CommunityPath/
C:\> python odoo-bin -r dbuser -w dbpassword --addons-path=addons -d mydb
Where `CommunityPath` is the path of the Odoo Community installation, `dbuser` is the
PostgreSQL login, `dbpassword` is the PostgreSQL password
and `mydb` is the default database to serve on `localhost:8069`. You can add other
directory paths separated by a comma to ``addons`` at the end of the addons-path option.
Linux
-----
Fetch the sources
'''''''''''''''''
There are two ways to obtain the source code of Odoo: as a zip **archive** or through **git**.
Archive
^^^^^^^
Community Edition:
* `Official download page <download_>`_
* `GitHub repository <community-repository_>`_
* `Nightly server <nightly_>`_
Enterprise Edition:
* `Official download page <download_>`_
* `GitHub repository <enterprise-repository_>`_
Git
^^^
The following requires git_ to be installed on your machine and that you have basic knowledge of
git commands.
Community Edition:
.. code-block:: console
$ git clone https://github.com/odoo/odoo.git
Enterprise Edition: (see :ref:`setup/install/editions` to get access)
.. code-block:: console
$ git clone https://github.com/odoo/enterprise.git
.. note:: **The Enterprise git repository does not contain the full Odoo source code**. It is only
a collection of extra add-ons. The main server code is in the Community version. Running
the Enterprise version actually means running the server from the Community version with
the addons-path option set to the folder with the Enterprise version. You need to clone
both the Community and Enterprise repository to have a working Odoo Enterprise
installation.
Prepare
'''''''
Python
^^^^^^
Odoo requires Python 3.6 or later to run. Use your package manager to download and install Python 3
on your machine if it is not already done.
.. note:: If Python 3 is already installed, make sure that the version is 3.6 or above, as previous
versions are not compatible with Odoo.
.. code-block:: console
$ python3 --version
Verify also that pip_ is installed for this version.
.. code-block:: console
$ pip3 --version
PostgreSQL
^^^^^^^^^^
Odoo uses PostgreSQL as database management system. Use your package manager to download and install
PostgreSQL (supported version: 10.0 and later).
On Debian/Unbuntu, it can be achieved by executing the following:
.. code-block:: console
$ sudo apt install postgresql postgresql-client
By default, the only user is `postgres` but Odoo forbids connecting as `postgres`, so you need to
create a new PostgreSQL user:
.. code-block:: console
$ sudo -u postgres createuser -s $USER
$ createdb $USER
.. note:: Because your PostgreSQL user has the same name as your Unix login, you will be able to
connect to the database without password.
Dependencies
^^^^^^^^^^^^
For libraries using native code, it is necessary to install development tools and native
dependencies before the Python dependencies of Odoo. They are available in `-dev` or `-devel`
packages for Python, PostgreSQL, libxml2, libxslt1, libevent, libsasl2 and libldap2.
On Debian/Unbuntu, the following command should install all the required libraries:
.. code-block:: console
$ sudo apt install python3-dev libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev libfreetype6-dev \
liblcms2-dev libwebp-dev libharfbuzz-dev libfribidi-dev libxcb1-dev libpq-dev
Odoo dependencies are listed in the `requirements.txt` file located at the root of the Odoo
community directory.
.. tip:: It can be preferable to not mix python modules packages between different instances of Odoo
or with your system. You can use virtualenv_ to create isolated Python environments.
Navigate to the path of your Odoo Community installation (`CommunityPath`) and run **pip**
on the requirements file:
.. code-block:: console
$ cd /CommunityPath
$ pip3 install setuptools wheel
$ pip3 install -r requirements.txt
.. warning:: `wkhtmltopdf` is not installed through **pip** and must be installed manually in
version `0.12.5 <the wkhtmltopdf download page_>`_ for it to support headers and
footers. See our `wiki <https://github.com/odoo/odoo/wiki/Wkhtmltopdf>`_ for more
details on the various versions.
For languages with right-to-left interface (such as Arabic or Hebrew), the package `rtlcss` is
needed:
#. Download and install **nodejs** and **npm** with your package manager.
#. Install `rtlcss`:
.. code-block:: console
$ sudo npm install -g rtlcss
Running Odoo
''''''''''''
Once all dependencies are set up, Odoo can be launched by running `odoo-bin`, the
command-line interface of the server. It is located at the root of the Odoo Community directory.
To configure the server, you can either specify :ref:`command-line arguments <reference/cmdline/server>` or a
:ref:`configuration file <reference/cmdline/config>`.
.. tip:: For the Enterprise edition, you must add the path to the `enterprise` addons to the
`addons-path` argument. Note that it must come before the other paths in `addons-path` for
addons to be loaded correctly.
Common necessary configurations are:
* PostgreSQL user and password. Odoo has no defaults beyond
`psycopg2's defaults <http://initd.org/psycopg/docs/module.html>`_: connects over a UNIX socket on
port `5432` with the current user and no password.
* Custom addon paths beyond the defaults, to load your own modules.
A typical way to run the server would be:
.. code-block:: console
$ cd /CommunityPath
$ python3 odoo-bin --addons-path=addons -d mydb
Where `CommunityPath` is the path of the Odoo Community installation
and `mydb` is the default database to serve on `localhost:8069`. You can add other
directory paths separated by a comma to ``addons`` at the end of the addons-path option.
Mac OS
------
Fetch the sources
'''''''''''''''''
There are two ways to obtain the source code of Odoo: as a zip **archive** or through **git**.
Archive
^^^^^^^
Community Edition:
* `Official download page <download_>`_
* `GitHub repository <community-repository_>`_
* `Nightly server <nightly_>`_
Enterprise Edition:
* `Official download page <download_>`_
* `GitHub repository <enterprise-repository_>`_
Git
^^^
The following requires git_ to be installed on your machine and that you have basic knowledge of
git commands.
Community Edition:
.. code-block:: console
$ git clone https://github.com/odoo/odoo.git
Enterprise Edition: (see :ref:`setup/install/editions` to get access)
.. code-block:: console
$ git clone https://github.com/odoo/enterprise.git
.. note:: **The Enterprise git repository does not contain the full Odoo source code**. It is only
a collection of extra add-ons. The main server code is in the Community version. Running
the Enterprise version actually means running the server from the Community version with
the addons-path option set to the folder with the Enterprise version. You need to clone
both the Community and Enterprise repository to have a working Odoo Enterprise
installation.
Prepare
'''''''
Python
^^^^^^
Odoo requires Python 3.6 or later to run. Use your preferred package manager (homebrew_, macports_)
to download and install Python 3 on your machine if it is not already done.
.. note:: If Python 3 is already installed, make sure that the version is 3.6 or above, as previous
versions are not compatible with Odoo.
.. code-block:: console
$ python3 --version
Verify also that pip_ is installed for this version.
.. code-block:: console
$ pip3 --version
PostgreSQL
^^^^^^^^^^
Odoo uses PostgreSQL as database management system. Use `postgres.app <https://postgresapp.com>`_
to download and install PostgreSQL (supported version: 10.0 and later).
By default, the only user is `postgres` but Odoo forbids connecting as `postgres`, so you need to
create a new PostgreSQL user:
.. code-block:: console
$ sudo -u postgres createuser -s $USER
$ createdb $USER
.. note:: Because your PostgreSQL user has the same name as your Unix login, you will be able to
connect to the database without password.
Dependencies
^^^^^^^^^^^^
Odoo dependencies are listed in the `requirements.txt` file located at the root of the Odoo
community directory.
.. tip:: It can be preferable to not mix python modules packages between different instances of Odoo
or with your system. You can use virtualenv_ to create isolated Python environments.
Navigate to the path of your Odoo Community installation (`CommunityPath`) and run **pip**
on the requirements file:
.. code-block:: console
$ cd /CommunityPath
$ pip3 install setuptools wheel
$ pip3 install -r requirements.txt
.. warning:: Non-Python dependencies need to be installed with a package manager:
#. Download and install the **Command Line Tools**:
.. code-block:: console
$ xcode-select --install
#. Download and install the package manager of your choice (homebrew_, macports_).
#. Install non-python dependencies.
.. warning:: `wkhtmltopdf` is not installed through **pip** and must be installed manually in
version `0.12.5 <the wkhtmltopdf download page_>`_ for it to support headers and
footers. See our `wiki <https://github.com/odoo/odoo/wiki/Wkhtmltopdf>`_ for more
details on the various versions.
For languages with right-to-left interface (such as Arabic or Hebrew), the package `rtlcss` is
needed:
#. Download and install **nodejs** with your preferred package manager (homebrew_, macports_).
#. Install `rtlcss`:
.. code-block:: console
$ sudo npm install -g rtlcss
Running Odoo
''''''''''''
Once all dependencies are set up, Odoo can be launched by running `odoo-bin`, the
command-line interface of the server. It is located at the root of the Odoo Community directory.
To configure the server, you can either specify :ref:`command-line arguments <reference/cmdline/server>` or a
:ref:`configuration file <reference/cmdline/config>`.
.. tip:: For the Enterprise edition, you must add the path to the `enterprise` addons to the
`addons-path` argument. Note that it must come before the other paths in `addons-path` for
addons to be loaded correctly.
Common necessary configurations are:
* PostgreSQL user and password. Odoo has no defaults beyond
`psycopg2's defaults <http://initd.org/psycopg/docs/module.html>`_: connects over a UNIX socket on
port `5432` with the current user and no password.
* Custom addon paths beyond the defaults, to load your own modules.
A typical way to run the server would be:
.. code-block:: console
$ cd /CommunityPath
$ python3 odoo-bin --addons-path=addons -d mydb
Where `CommunityPath` is the path of the Odoo Community installation
and `mydb` is the default database to serve on `localhost:8069`. You can add other
directory paths separated by a comma to ``addons`` at the end of the addons-path option.
.. _setup/install/docker:
Docker
======
The full documentation on how to use Odoo with Docker can be found on the
official Odoo `docker image <https://registry.hub.docker.com/_/odoo/>`_ page.
.. _Debian Buster: https://www.debian.org/releases/buster/
.. _demo: https://demo.odoo.com
.. _docker: https://www.docker.com
.. _download: https://www.odoo.com/page/download
.. _Ubuntu 18.04: http://releases.ubuntu.com/18.04/
.. _EPEL: https://fedoraproject.org/wiki/EPEL
.. _PostgreSQL: http://www.postgresql.org
.. _the official installer:
.. _install pip:
https://pip.pypa.io/en/latest/installing.html#install-pip
.. _Quilt: http://en.wikipedia.org/wiki/Quilt_(software)
.. _saas: https://www.odoo.com/page/start
.. _the wkhtmltopdf download page: https://github.com/wkhtmltopdf/wkhtmltopdf/releases/tag/0.12.5
.. _UAC: http://en.wikipedia.org/wiki/User_Account_Control
.. _wkhtmltopdf: http://wkhtmltopdf.org
.. _pip: https://pip.pypa.io
.. _macports: https://www.macports.org
.. _homebrew: http://brew.sh
.. _wheels: https://wheel.readthedocs.org/en/latest/
.. _virtualenv: https://pypi.python.org/pypi/virtualenv
.. _virtualenvwrapper: https://virtualenvwrapper.readthedocs.io/en/latest/
.. _pywin32: http://sourceforge.net/projects/pywin32/files/pywin32/
.. _community-repository: https://github.com/odoo/odoo
.. _enterprise-repository: https://github.com/odoo/enterprise
.. _git: https://git-scm.com/
.. _Editions: https://www.odoo.com/pricing#pricing_table_features
.. _nightly: https://nightly.odoo.com/
.. _extra: https://nightly.odoo.com/extra/