4.6. Reverse Proxies¶
4.6.1. 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 montioring 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:
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
4.6.2. Reverse proxying with nginx¶
4.6.2.1. Basic Configuration¶
Here’s a basic excerpt from an nginx config file in
<nginx config directory>/sites-available/default
. This will proxy all
requests from http://domain.com/...
to http://localhost:5984/...
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.
4.6.2.2. 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
.
location /couchdb {
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;
}
4.6.2.3. Authentication with nginx as a reverse proxy¶
Here’s a sample config setting with basic authentication enabled, placing
CouchDB in the /couchdb
subdirectory:
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). For a better solution, see Proxy Authentication.
4.6.2.4. SSL with nginx¶
In order to enable SSL, just enable the nginx SSL module, and add another proxy header:
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.
4.6.3. Reverse Proxying with Caddy¶
4.6.3.1. Basic configuration¶
Here’s a basic excerpt from a Caddyfile in
/<path>/<to>/<site>/Caddyfile
. This will proxy all
requests from http(s)://domain.com/...
to http://localhost:5984/...
domain.com {
import /path/to/other/config.caddy # logging, error handling etc.
proxy / localhost:5984 {
transparent
}
}
Note
The transparent
preset in the proxy
directive is shorthand for:
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Proto {scheme}
Note that, because Caddy is https-by-default, you must explicitly include the
http://
protocol in the site address if you do NOT want Caddy
to automatically acquire and install an SSL certificate and begin accepting
https
connections on port 443.
4.6.3.2. Reverse proxying CouchDB in a subdirectory with Caddy¶
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
.
domain.com {
import /path/to/other/config.caddy # logging, error handling etc.
proxy /couchdb localhost:5984 {
transparent
without /couchdb
}
}
4.6.3.3. Reverse proxying + load balancing for CouchDB clusters¶
Here’s a basic excerpt from a Caddyfile in
/<path>/<to>/<site>/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.
domain.com {
import /path/to/other/config.caddy # logging, error handling etc.
proxy / http://localhost:15984 http://localhost:25984 http://localhost:35984 {
policy round_robin
health_check /_up
health_check_duration 5s
try_interval 500ms
keepalive 0
transparent
}
}
4.6.3.4. Authentication with Caddy as a reverse proxy¶
Here’s a sample config setting with basic authentication enabled, placing
CouchDB in the /couchdb
subdirectory:
domain.com {
import /path/to/other/config.caddy # logging, error handling etc.
basicauth /couchdb couch_username couchdb_password
proxy /couchdb localhost:5984 {
transparent
header_upstream -Authorization
without /couchdb
}
}
For security reasons, using a plaintext password in the Caddyfile
is not
advisable. One solution is to define Caddy-process environment variables e.g.
COUCH_PW=couchdb_password
and using placeholders in the Caddyfile
instead, e.g. {$COUCH_PW}
.
This setup leans entirely on Caddy performing authorization, and forwarding requests to CouchDB with no authentication (with CouchDB in Admin Party mode). For a better solution, see Proxy Authentication.
4.6.3.5. SSL/TLS with Caddy¶
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 LetsEncrypt certificate authority.
domain.com {
import /path/to/other/config.caddy # logging, error handling etc.
proxy / localhost:5984 {
transparent
header_upstream 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.
4.6.4. 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.
4.6.4.1. 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.
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "/opt/websites/web/www/dummy"
ServerName couchdb.localhost
AllowEncodedSlashes On
ProxyRequests Off
KeepAlive Off
<Proxy *>
Order deny,allow
Deny from all
Allow from 127.0.0.1
</Proxy>
ProxyPass / http://localhost:5984 nocanon
ProxyPassReverse / http://localhost:5984
ProxyPreserveHost On
ErrorLog "logs/couchdb.localhost-error_log"
CustomLog "logs/couchdb.localhost-access_log" common
</VirtualHost>