Cassandra
What is Cassandra?
Apache Cassandra is a distributed, wide-column NoSQL database built for high availability and horizontal scale across many nodes with no single point of failure. Laradock runs it via the Bitnami Cassandra image as a single-node instance for local development.
Start Cassandra
- Laradock CLI
- Docker Compose
./laradock start cassandra
docker compose up -d cassandra
compose.yml declares depends_on: php-fpm, so Docker Compose starts php-fpm automatically if it isn't already running. The container also runs privileged: true, which Cassandra's Bitnami image requires. Your data is created on first start and kept between restarts.
Stop Cassandra
Stopping just pauses the container; your data is safe:
- Laradock CLI
- Docker Compose
./laradock stop cassandra
docker compose stop cassandra
To delete the container entirely (the data on disk is still untouched, it lives under DATA_PATH_HOST/cassandra):
- Laradock CLI
- Docker Compose
./laradock remove cassandra
docker compose rm -sf cassandra
Configuration
All settings live in cassandra/defaults.env and can be overridden by adding the same line to your own .env (your .env always wins):
| Variable | Default | What it does |
|---|---|---|
CASSANDRA_VERSION | latest | Image tag from bitnami/cassandra on Docker Hub. |
CASSANDRA_TRANSPORT_PORT_NUMBER | 7000 | Inter-node cluster communication port. |
CASSANDRA_JMX_PORT_NUMBER | 7199 | JMX connections port. |
CASSANDRA_CQL_PORT_NUMBER | 9042 | Client (CQL) port, what your app/driver connects to. |
CASSANDRA_USER | cassandra | Cassandra username. |
CASSANDRA_PASSWORD_SEEDER | no | Set yes on exactly one node in a cluster to have it change default credentials at initialization. |
CASSANDRA_PASSWORD | cassandra | Password for CASSANDRA_USER. |
CASSANDRA_NUM_TOKENS | 256 | Number of tokens for the node. |
CASSANDRA_HOST | (empty) | Hostname to configure Cassandra with; resolves to the machine IP if left empty. |
CASSANDRA_CLUSTER_NAME | "My Cluster" | Cluster name. |
CASSANDRA_SEEDS | (empty) | Hosts acting as Cassandra seeds for cluster discovery. |
CASSANDRA_ENDPOINT_SNITCH | SimpleSnitch | Snitch strategy, determines which data centers/racks nodes belong to. |
CASSANDRA_ENABLE_RPC | true | Enables the Thrift RPC endpoint. |
CASSANDRA_DATACENTER | dc1 | Datacenter name (ignored under SimpleSnitch). |
CASSANDRA_RACK | rack1 | Rack name (ignored under SimpleSnitch). |
Connect with cqlsh
Open a terminal inside the Cassandra container, then start cqlsh:
- Laradock CLI
- Docker Compose
./laradock enter cassandra
cqlsh -u cassandra -p cassandra
docker compose exec cassandra bash
cqlsh -u cassandra -p cassandra
Use your own CASSANDRA_USER/CASSANDRA_PASSWORD if you changed them. From your host machine or another container, connect on CASSANDRA_CQL_PORT_NUMBER (9042 by default) at cassandra (container name) or localhost (from the host).
Check cluster status
Cassandra can take a while to become ready on first boot, and a running container doesn't mean the node has finished starting. nodetool status is the standard way to check:
- Laradock CLI
- Docker Compose
./laradock exec cassandra nodetool status
docker compose exec cassandra nodetool status
UN in the output means "Up, Normal", the node is fully joined and ready to serve queries. Anything else (UJ joining, DN down) means it's not ready yet.
Backup and restore
Cassandra stores everything under /var/lib/cassandra inside the container, which is bind-mounted straight from DATA_PATH_HOST/cassandra on your host. The simplest reliable backup is archiving that directory while the container is stopped:
- Laradock CLI
- Docker Compose
./laradock stop cassandra
tar -czf cassandra-backup.tar.gz -C "${DATA_PATH_HOST:-~/.laradock/data}/cassandra" .
./laradock start cassandra
docker compose stop cassandra
tar -czf cassandra-backup.tar.gz -C "${DATA_PATH_HOST:-~/.laradock/data}/cassandra" .
docker compose up -d cassandra
To restore, stop the container, replace the data folder with the backup, then start again:
- Laradock CLI
- Docker Compose
./laradock stop cassandra
rm -rf "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
mkdir -p "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
tar -xzf cassandra-backup.tar.gz -C "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
./laradock start cassandra
docker compose stop cassandra
rm -rf "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
mkdir -p "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
tar -xzf cassandra-backup.tar.gz -C "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
docker compose up -d cassandra
For a point-in-time backup without stopping the node, use Cassandra's own snapshot mechanism instead:
- Laradock CLI
- Docker Compose
./laradock exec cassandra nodetool snapshot -t my_backup
docker compose exec cassandra nodetool snapshot -t my_backup
This hard-links the current on-disk SSTables into a snapshots/my_backup folder inside each table's data directory (still under DATA_PATH_HOST/cassandra), which you can then tar out while the node keeps running. Clear it afterward with nodetool clearsnapshot -t my_backup so it doesn't consume extra disk space forever.
Start completely fresh (wipe all data)
To throw away everything and start Cassandra from a clean, empty state (⚠️ this permanently deletes every keyspace in this container, back up first if you need anything):
- Laradock CLI
- Docker Compose
./laradock stop cassandra
./laradock remove cassandra
rm -rf "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
./laradock start cassandra
docker compose stop cassandra
docker compose rm -sf cassandra
rm -rf "${DATA_PATH_HOST:-~/.laradock/data}/cassandra"
docker compose up -d cassandra
DATA_PATH_HOST is whatever you have set in .env (~/.laradock/data by default), so the folder above is where Cassandra's data actually lives on your machine. Deleting it and starting again re-runs first-boot initialization, so CASSANDRA_USER/CASSANDRA_PASSWORD and the rest of the config table apply fresh, exactly like a brand-new node.
Talk to this database from another Laradock project
Each Laradock project is its own isolated Docker network by default, so a second project's containers can't reach this Cassandra by container name out of the box. Easiest fix: the port is already published (CASSANDRA_CQL_PORT_NUMBER), so have the other project connect to your host machine's address instead of cassandra, for example host.docker.internal (Docker Desktop) with its CQL driver port set to this project's CASSANDRA_CQL_PORT_NUMBER. Make sure the two projects use different CASSANDRA_CQL_PORT_NUMBER (and CASSANDRA_TRANSPORT_PORT_NUMBER/CASSANDRA_JMX_PORT_NUMBER) values if they're both running at once.
Common issues
- Container won't start / permission errors. Cassandra's Bitnami image needs
privileged: true, whichcompose.ymlalready sets; if your Docker setup restricts privileged containers (some CI runners, rootless Docker), it may fail to boot. - Slow first boot. Cassandra can take longer than other databases to become ready on first start. Check
./laradock logs cassandraand confirm withnodetool status(see Check cluster status) before connecting. - Credential changes don't take effect. Credentials are set at initialization; changing
CASSANDRA_USER/CASSANDRA_PASSWORDafterward requires either a fresh start (data loss, back up first) or changing them through CQL directly. - App can't connect but the container is running. Confirm the app's driver config uses
cassandra(the container name) as the host, notlocalhost, which only works from your host machine. - Port already in use on your host. Another service is bound to
7000,7199, or9042. Change the relevantCASSANDRA_*_PORT_NUMBERin.envand restart with./laradock restart cassandra.
Need a document database instead? See CouchDB. For the full list of services, see Getting Started.