How to Install CouchDB 3.5 on Rocky Linux 10.2: Docker, Source Build & Production Setup

how to install couchdb on rocky linux 10

Apache CouchDB is a document-oriented NoSQL database that stores data as JSON documents, exposes everything over a plain HTTP API, and is built around multi-master replication — which makes it a strong fit for offline-first applications and distributed deployments. Installing it on Rocky Linux 10.2 comes with one significant catch that most tutorials skip: there is no official CouchDB RPM for EL10. This guide explains why, then covers the two methods that actually work.

Table of Contents

  1. The EL10 Packaging Gap (Read This First)
  2. Prerequisites
  3. Installation Method Comparison
  4. Architecture Overview
  5. Method A — Docker (Recommended)
  6. Method B — Build from Source
  7. Configure firewalld
  8. SELinux Considerations
  9. Nginx Reverse Proxy with SSL
  10. Verifying the Installation
  11. Basic CRUD with the HTTP API
  12. Backup and Restore
  13. Troubleshooting
  14. FAQ
  15. Related Articles

The EL10 Packaging Gap (Read This First)

The Apache CouchDB project publishes convenience binary packages for CentOS/RHEL 7, 8, and 9 only — EL10 is not on the supported list. Two problems block the obvious workaround of pointing the EL9 repository at a Rocky Linux 10 host:

  1. The CouchDB repo definition resolves $releasever to 10, and no el10 directory exists in the artifact repository.
  2. Even with the path hardcoded to 9, the EL9 CouchDB package depends on mozjs78 (SpiderMonkey 78), which is installed from EPEL 9. Rocky Linux 10 ships a much newer SpiderMonkey, and mozjs78 is not available in EPEL 10.
ApproachWorks on Rocky Linux 10.2?Notes
Official yum repo (couchdb.repo)❌ NoNo el10 path published
EL9 repo with hardcoded baseurl❌ NoFails on the mozjs78 dependency
Docker container✅ YesOfficially maintained image, recommended
Build from source✅ YesWorks but requires Erlang + SpiderMonkey toolchain
Snap package⚠️ PartialRequires snapd + EPEL; uncommon on RHEL-family servers

Check the CouchDB installation docs before deploying — once the project publishes an el10 path, the native RPM route becomes the simpler option and this section becomes obsolete.

Prerequisites

  • A Rocky Linux 10.2 server with at least 2 GB RAM and 10 GB free disk space
  • A non-root user with sudo privileges
  • For Method A: Docker installed — see the Docker on Rocky Linux 10 with SELinux guide
  • A domain name pointed at the server (for the Nginx + SSL section)

Installation Method Comparison

MethodSetup ComplexityUpdate PathIsolationBest For
Docker (Method A)Lowdocker compose pull && up -dFull container isolationProduction and development on EL10 — the practical default
Source build (Method B)HighManual rebuild per releaseShares host runtimeHosts where containers aren’t permitted, or custom build flags are required

Architecture Overview

Method A — Docker (Recommended)

The official couchdb image is maintained by the CouchDB project and is the most reliable path on Rocky Linux 10.

1. Create the Compose file:

mkdir -p ~/couchdb && cd ~/couchdb
nano docker-compose.yml
services:
  couchdb:
    image: couchdb:3.5
    container_name: couchdb
    restart: always
    ports:
      - "127.0.0.1:5984:5984"
    environment:
      COUCHDB_USER: admin
      COUCHDB_PASSWORD: change_me_to_a_strong_password
    volumes:
      - couchdb_data:/opt/couchdb/data
      - couchdb_config:/opt/couchdb/etc/local.d

volumes:
  couchdb_data:
  couchdb_config:

2. Start the container:

docker compose up -d
docker compose logs -f couchdb

COUCHDB_USER and COUCHDB_PASSWORD are mandatory. CouchDB 3.0+ refuses to run without an admin user configured — the old “admin party” mode was removed in the 3.x series.

3. Initialize the system databases:

A fresh single-node install needs its internal databases created once:

curl -X PUT http://admin:change_me_to_a_strong_password@127.0.0.1:5984/_users
curl -X PUT http://admin:change_me_to_a_strong_password@127.0.0.1:5984/_replicator

Alternatively, set COUCHDB_SINGLE_NODE=true in the environment block to have the container handle this automatically on first boot.

Note on bind mounts and SELinux: the Compose file above uses named volumes, which avoid SELinux labeling issues entirely. If host bind mounts are preferred instead, append :Z to each mount (./data:/opt/couchdb/data:Z) so Docker applies the correct SELinux context — otherwise the container will hit permission-denied errors on an Enforcing host.

Method B — Build from Source

Use this only when containers aren’t an option. The build requires the Erlang/OTP and SpiderMonkey toolchain.

1. Enable CRB and EPEL:

sudo dnf config-manager --set-enabled crb
sudo dnf install -y epel-release
sudo dnf update -y

2. Install build dependencies:

sudo dnf install -y autoconf autoconf-archive automake \
    gcc-c++ libtool libicu-devel help2man perl-Test-Harness \
    erlang erlang-erts erlang-asn1 erlang-eunit \
    erlang-os_mon erlang-xmerl erlang-erl_interface \
    mozjs128-devel python3-sphinx

CouchDB 3.5 supports Erlang/OTP 26, 27, and 28, and SpiderMonkey versions up to 128 — match the --spidermonkey-version flag below to whichever mozjs*-devel package the system actually resolved.

3. Download and build:

cd /usr/local/src
sudo curl -LO https://downloads.apache.org/couchdb/source/3.5.0/apache-couchdb-3.5.0.tar.gz
sudo tar -xzf apache-couchdb-3.5.0.tar.gz
cd apache-couchdb-3.5.0

sudo ./configure --spidermonkey-version 128 --disable-docs
sudo make release

4. Create the couchdb user and install the release:

sudo useradd --system --shell /bin/bash --home-dir /opt/couchdb couchdb
sudo cp -R rel/couchdb /opt/
sudo chown -R couchdb:couchdb /opt/couchdb
sudo find /opt/couchdb -type d -exec chmod 0770 {} \;
sudo chmod 0644 /opt/couchdb/etc/*

5. Create the admin user before first start (CouchDB 3.x will not run without one):

sudo tee -a /opt/couchdb/etc/local.ini << ‘EOF’

admin = your_strong_password_here
EOF

sudo tee -a /opt/couchdb/etc/local.ini << 'EOF'

[admins]

admin = your_strong_password_here EOF

CouchDB hashes this password on first startup and replaces the plaintext value in the file.

6. Create a systemd unit — CouchDB no longer ships daemonization scripts, so the unit has to be written manually:

sudo nano /etc/systemd/system/couchdb.service
[Unit]
Description=Apache CouchDB
After=network.target

[Service]
Type=simple
User=couchdb
Group=couchdb
ExecStart=/opt/couchdb/bin/couchdb
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=couchdb
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now couchdb
sudo systemctl status couchdb

Configure firewalld

CouchDB should never be exposed directly to the internet. Keep 5984 bound to localhost and expose only the Nginx ports:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
PortProtocolExposurePurpose
80tcpPublicHTTP → HTTPS redirect, Certbot ACME challenge
443tcpPublicHTTPS traffic to Nginx
5984tcpLocalhost onlyCouchDB HTTP API + Fauxton UI
4369tcpCluster nodes onlyErlang port mapper (clustered deployments only)

SELinux Considerations

Rocky Linux 10.2 runs SELinux in Enforcing mode by default. Two things matter here:

For the Docker method — use named volumes (as in the Compose file above), or append :Z to bind mounts so Docker relabels them with the correct container context.

For the Nginx reverse proxy — Nginx cannot open an outbound connection to CouchDB until this boolean is set:

sudo setsebool -P httpd_can_network_connect 1

Check for denials if anything fails to start after a configuration change:

sudo ausearch -m avc -ts recent

Nginx Reverse Proxy with SSL

sudo dnf install -y nginx
sudo systemctl enable --now nginx
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx
sudo nano /etc/nginx/conf.d/couchdb.conf
server {
    listen 80;
    server_name couchdb.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:5984;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
        client_max_body_size 64M;
    }
}
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d couchdb.yourdomain.com

proxy_buffering off matters for CouchDB’s continuous _changes feed, which streams responses — buffering would break long-polling replication clients.

Verifying the Installation

curl http://admin:yourpassword@127.0.0.1:5984/

A JSON response including a couchdb welcome field and the version number confirms the server is running. Then check cluster/setup health:

curl http://admin:yourpassword@127.0.0.1:5984/_up

The Fauxton web interface is available at /_utils — through the reverse proxy that becomes https://couchdb.yourdomain.com/_utils.

Basic CRUD with the HTTP API

Everything in CouchDB is an HTTP call, which makes it easy to verify from the shell:

export CDB="http://admin:yourpassword@127.0.0.1:5984"

# Create a database
curl -X PUT $CDB/testdb

# Insert a document
curl -X POST $CDB/testdb \
  -H "Content-Type: application/json" \
  -d '{"name":"sample","qty":10}'

# Read all documents
curl $CDB/testdb/_all_docs?include_docs=true

# Delete the database
curl -X DELETE $CDB/testdb

Updating a document requires its current _rev value — CouchDB uses MVCC, so every write must reference the revision it’s replacing.

Backup and Restore

CouchDB stores each database as a single .couch file, so a filesystem-level backup of the data directory works when the service is stopped:

# Docker method — back up the named volume
docker compose stop couchdb
docker run --rm -v couchdb_couchdb_data:/data -v /backup:/backup \
  alpine tar czf /backup/couchdb-$(date +%F).tar.gz -C /data .
docker compose start couchdb

For live backups without downtime, use CouchDB’s replication API to replicate to a second instance, or couchbackup for a logical per-database dump. Replication is generally the better production answer since it’s built into the database rather than bolted on.

Troubleshooting

SymptomLikely CauseFix
dnf install couchdb fails with “No match for argument”No EL10 package published — the core packaging gapUse Method A (Docker) or Method B (source build)
Repo added but fails with “Cannot download repodata”$releasever resolving to 10, no such pathSame as above — the EL10 path does not exist
Source build fails on mozjs78 not foundRocky Linux 10 ships a newer SpiderMonkeyInstall mozjs128-devel and pass --spidermonkey-version 128
CouchDB refuses to start, logs mention no admin configuredCouchDB 3.x requires an admin user before first startSet COUCHDB_USER/COUCHDB_PASSWORD (Docker) or add an [admins] entry to local.ini (source)
Container hits permission denied on its data directorySELinux context missing on a bind mountUse named volumes, or append :Z to the bind mount
Nginx returns 502 Bad GatewaySELinux blocking Nginx’s outbound connectionsudo setsebool -P httpd_can_network_connect 1
Replication or _changes feed stalls behind the proxyNginx buffering the streaming responseSet proxy_buffering off in the location block
Fauxton loads but API calls return 401Credentials not being passed, or admin not createdVerify with curl http://admin:pass@127.0.0.1:5984/_up

FAQ

Is there an official CouchDB RPM package for Rocky Linux 10?
No. As of this writing the Apache CouchDB convenience binary repository publishes packages for CentOS/RHEL 7, 8 and 9 only. The EL9 package also depends on mozjs78, which is not available in Rocky Linux 10 repositories, so pointing the EL9 repo at an EL10 host will fail on the SpiderMonkey dependency. Docker is the practical deployment method on Rocky Linux 10.

Why must a CouchDB admin user be created before first start?
CouchDB 3.0 and later will not run without an admin user. Starting the server with no admin configured leaves it in “admin party” mode, which the 3.x series removed. With Docker this is handled by passing COUCHDB_USER and COUCHDB_PASSWORD environment variables at container creation.

What ports does CouchDB use?
CouchDB listens on port 5984 for the HTTP API and the Fauxton web interface. A clustered deployment additionally uses 5986 for the node-local API on older versions, 4369 for the Erlang port mapper daemon, and a configurable range for inter-node Erlang distribution traffic.

(Visited 2 times, 1 visits today)

You may also like