.. Licensed under the Apache License, Version 2.0 (the "License"); you may not .. use this file except in compliance with the License. You may obtain a copy of .. the License at .. .. http://www.apache.org/licenses/LICENSE-2.0 .. .. Unless required by applicable law or agreed to in writing, software .. distributed under the License is distributed on an "AS IS" BASIS, WITHOUT .. WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the .. License for the specific language governing permissions and limitations under .. the License. .. _best-practices/reverse-proxies: ======================== Reverse Proxies ======================== Reverse proxying with HAProxy ============================= CouchDB recommends the use of `HAProxy`_ as a load balancer and reverse proxy. The team's experience with using it in production has shown it to be superior for configuration and monitoring capabilities, as well as overall performance. CouchDB's sample haproxy configuration is present in the `code repository`_ and release tarball as ``rel/haproxy.cfg``. It is included below. This example is for a 3 node CouchDB cluster: .. code-block:: text global maxconn 512 spread-checks 5 defaults mode http log global monitor-uri /_haproxy_health_check option log-health-checks option httplog balance roundrobin option forwardfor option redispatch retries 4 option http-server-close timeout client 150000 timeout server 3600000 timeout connect 500 stats enable stats uri /_haproxy_stats # stats auth admin:admin # Uncomment for basic auth frontend http-in # This requires HAProxy 1.5.x # bind *:$HAPROXY_PORT bind *:5984 default_backend couchdbs backend couchdbs option httpchk GET /_up http-check disable-on-404 server couchdb1 x.x.x.x:5984 check inter 5s server couchdb2 x.x.x.x:5984 check inter 5s server couchdb2 x.x.x.x:5984 check inter 5s .. _HAProxy: http://haproxy.org/ .. _code repository: https://github.com/apache/couchdb/blob/main/rel/haproxy.cfg Reverse proxying with nginx =========================== Basic Configuration ------------------- Here's a basic excerpt from an nginx config file in ``/sites-available/default``. This will proxy all requests from ``http://domain.com/...`` to ``http://localhost:5984/...`` .. code-block:: text location / { proxy_pass http://localhost:5984; proxy_redirect off; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } Proxy buffering **must** be disabled, or continuous replication will not function correctly behind nginx. Reverse proxying CouchDB in a subdirectory with nginx ----------------------------------------------------- It can be useful to provide CouchDB as a subdirectory of your overall domain, especially to avoid CORS concerns. Here's an excerpt of a basic nginx configuration that proxies the URL ``http://domain.com/couchdb`` to ``http://localhost:5984`` so that requests appended to the subdirectory, such as ``http://domain.com/couchdb/db1/doc1`` are proxied to ``http://localhost:5984/db1/doc1``. .. code-block:: text location /couchdb { rewrite ^ $request_uri; rewrite ^/couchdb/(.*) /$1 break; proxy_pass http://localhost:5984$uri; proxy_redirect off; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } Session based replication is default functionality since CouchDB 2.3.0. To enable session based replication with reverse proxied CouchDB in a subdirectory. .. code-block:: text location /_session { proxy_pass http://localhost:5984/_session; proxy_redirect off; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } Authentication with nginx as a reverse proxy -------------------------------------------- Here's a sample config setting with basic authentication enabled, placing CouchDB in the ``/couchdb`` subdirectory: .. code-block:: text location /couchdb { auth_basic "Restricted"; auth_basic_user_file htpasswd; rewrite /couchdb/(.*) /$1 break; proxy_pass http://localhost:5984; proxy_redirect off; proxy_buffering off; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Authorization ""; } This setup leans entirely on nginx performing authorization, and forwarding requests to CouchDB with no authentication (with CouchDB in Admin Party mode), which isn't sufficient in CouchDB 3.0 anymore as Admin Party has been removed. You'd need to at the very least hard-code user credentials into this version with headers. For a better solution, see :ref:`api/auth/proxy`. SSL with nginx -------------------------------------------- In order to enable SSL, just enable the nginx SSL module, and add another proxy header: .. code-block:: text ssl on; ssl_certificate PATH_TO_YOUR_PUBLIC_KEY.pem; ssl_certificate_key PATH_TO_YOUR_PRIVATE_KEY.key; ssl_protocols SSLv3; ssl_session_cache shared:SSL:1m; location / { proxy_pass http://localhost:5984; proxy_redirect off; proxy_set_header Host $host; proxy_buffering off; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Ssl on; } The ``X-Forwarded-Ssl`` header tells CouchDB that it should use the ``https`` scheme instead of the ``http`` scheme. Otherwise, all CouchDB-generated redirects will fail. Reverse Proxying with Caddy 2 ============================= Caddy is ``https-by-default``, and will automatically acquire, install, activate and, when necessary, renew a trusted SSL certificate for you - all in the background. Certificates are issued by the **Let's Encrypt** certificate authority. Basic configuration ------------------- Here's a basic excerpt from a Caddyfile in ``/etc/caddy/Caddyfile``. This will proxy all requests from ``http(s)://domain.com/...`` to ``http://localhost:5984/...`` .. code-block:: text domain.com { reverse_proxy localhost:5984 } Reverse proxying CouchDB in a subdirectory with Caddy 2 ------------------------------------------------------- It can be useful to provide CouchDB as a subdirectory of your overall domain, especially to avoid CORS concerns. Here's an excerpt of a basic Caddy configuration that proxies the URL ``http(s)://domain.com/couchdb`` to ``http://localhost:5984`` so that requests appended to the subdirectory, such as ``http(s)://domain.com/couchdb/db1/doc1`` are proxied to ``http://localhost:5984/db1/doc1``. .. code-block:: text domain.com { reverse_proxy /couchdb/* localhost:5984 } Reverse proxying + load balancing for CouchDB clusters ------------------------------------------------------ Here's a basic excerpt from a Caddyfile in ``////Caddyfile``. This will proxy and evenly distribute all requests from ``http(s)://domain.com/...`` among 3 CouchDB cluster nodes at ``localhost:15984``, ``localhost:25984`` and ``localhost:35984``. Caddy will check the status, i.e. health, of each node every 5 seconds; if a node goes down, Caddy will avoid proxying requests to that node until it comes back online. .. code-block:: text domain.com { reverse_proxy http://localhost:15984 http://localhost:25984 http://localhost:35984 { lb_policy round_robin lb_try_interval 500ms health_interval 5s } } Authentication with Caddy 2 as a reverse proxy ---------------------------------------------- Here's a sample config setting with basic authentication enabled, placing CouchDB in the ``/couchdb`` subdirectory: .. code-block:: text domain.com { basicauth /couchdb/* { couch_username couchdb_hashed_password_base64 } reverse_proxy /couchdb/* localhost:5984 } This setup leans entirely on nginx performing authorization, and forwarding requests to CouchDB with no authentication (with CouchDB in Admin Party mode), which isn't sufficient in CouchDB 3.0 anymore as Admin Party has been removed. You'd need to at the very least hard-code user credentials into this version with headers. For a better solution, see :ref:`api/auth/proxy`. Reverse Proxying with Apache HTTP Server ======================================== .. warning:: As of this writing, there is no way to fully disable the buffering between Apache HTTPD Server and CouchDB. This may present problems with continuous replication. The Apache CouchDB team strongly recommend the use of an alternative reverse proxy such as ``haproxy`` or ``nginx``, as described earlier in this section. Basic Configuration ------------------- Here's a basic excerpt for using a ``VirtualHost`` block config to use Apache as a reverse proxy for CouchDB. You need at least to configure Apache with the ``--enable-proxy --enable-proxy-http`` options and use a version equal to or higher than Apache 2.2.7 in order to use the ``nocanon`` option in the ``ProxyPass`` directive. The ``ProxyPass`` directive adds the ``X-Forwarded-For`` header needed by CouchDB, and the ``ProxyPreserveHost`` directive ensures the original client ``Host`` header is preserved. .. code-block:: apacheconf ServerAdmin webmaster@dummy-host.example.com DocumentRoot "/opt/websites/web/www/dummy" ServerName couchdb.localhost AllowEncodedSlashes On ProxyRequests Off KeepAlive Off Order deny,allow Deny from all Allow from 127.0.0.1 ProxyPass / http://localhost:5984 nocanon ProxyPassReverse / http://localhost:5984 ProxyPreserveHost On ErrorLog "logs/couchdb.localhost-error_log" CustomLog "logs/couchdb.localhost-access_log" common