summaryrefslogtreecommitdiff
path: root/doc/setup/deploy.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/setup/deploy.rst')
-rw-r--r--doc/setup/deploy.rst246
1 files changed, 246 insertions, 0 deletions
diff --git a/doc/setup/deploy.rst b/doc/setup/deploy.rst
new file mode 100644
index 00000000000..dc462dcf640
--- /dev/null
+++ b/doc/setup/deploy.rst
@@ -0,0 +1,246 @@
+==============
+Deploying Odoo
+==============
+
+This document describes basic steps to set up Odoo in production. It follows
+:ref:`installation <setup/install>`, but should not be used for development
+systems.
+
+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 need to know which database should be used for the
+operations or to get the data. 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.py --db-filter>`:
+it specifies the default database for the Odoo system. The value is a
+`regular expression`_, possibly including the dynamically injected hostname
+or subdomain through which the Odoo system is accessed.
+
+If an Odoo hosts multiple databases in production, especially if ``website``
+is used, it **must** use a dbfilter or a number of features will not work
+correctly or not use at all.
+
+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 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 with
+ over ssl (see `PostgreSQL connection settings`_ for details), then configure
+ Odoo to connect over the network
+
+.. _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 user
+ have ``createdb`` right.
+* users can always drop databases they own. For the database management screen
+ to be completely non-functional, the user needs to be created with
+ ``no-createdb`` and the database must be owned by a different user.
+
+ .. warning:: the user also needs to *not* be a superuser
+
+HTTPS
+=====
+
+Whether it's accessed via website/web client or the webservice, Odoo transmits
+authentication information in cleatext. 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.py --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
+
+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.py --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
+
+LiveChat
+--------
+
+In multiprocessing, a dedicated LiveChat worker is automatically started and
+listening on :option:`the longpolling port <odoo.py --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.py --xmlrpc-port>`
+
+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 ``openerp-wsgi.py``. That
+script should be customized (possibly after copying it) to correctly set the
+configuration directly in :mod:`openerp.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.py``)
+* connected to the database in which cron jobs have to be run (via
+ :option:`odoo.py -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.py --no-xmlrpc` or setting ``xmlrpc = 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's going to 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 (instread 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 ``openerp-gevent`` and proxy requests starting
+ with ``/longpolling/`` to
+ :option:`the longpolling port <odoo.py --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
+========
+
+"Super-admin" password
+----------------------
+
+: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, or 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
+
+ $ python -c 'import base64, os; print(base64.b64encode(os.urandom(24)))'
+
+which will generate a 32 characters pseudorandom printable string.
+
+.. [#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/2/library/re.html
+.. _ARP spoofing: http://en.wikipedia.org/wiki/ARP_spoofing
+.. _Nginx termination example:
+ http://nginx.com/resources/admin-guide/nginx-ssl-termination/
+.. _Nginx proxying example:
+ http://nginx.com/resources/admin-guide/reverse-proxy/
+.. _socat: http://www.dest-unreach.org/socat/
+.. _PostgreSQL connection settings:
+.. _listen to network interfaces:
+ http://www.postgresql.org/docs/9.3/static/runtime-config-connection.html
+.. _use an SSH tunnel:
+ http://www.postgresql.org/docs/9.3/static/ssh-tunnels.html
+.. _WSGI: http://wsgi.readthedocs.org/