We live in a world of process isolation and tools that make utilizing it extremely simple, with apps like Docker we can perform dependency management with dependency isolation. As I am slowly becoming a fanboy of containerization, I look forward to the day when typing ps on my local workstation or remote server is nearly synonymous with commands like docker ps or kubectl get services.
Case: Cassandra development and your local workstation.
§2026 Update
This post is from 2018, and the trick still works. If anything it has aged into a standard practice: running a command line tool as a throwaway container, instead of installing it and its dependency chain on your machine, is now something most developers do without thinking about it. A few specifics have moved since I wrote this, all of them in the technique’s favor.
The image moved on. cassandra:latest is Cassandra 5.0 now, not the 3.x I was running. The official image is also multi-architecture, so it runs natively on Apple Silicon Macs, which did not exist when I wrote this on an Intel MacBook Pro. The same docker run line just works.
cqlsh itself switched to Python 3 (it wants 3.8 to 3.11 these days). That is exactly the kind of change that used to ruin an afternoon. A locally installed cqlsh from the Python 2 era would have broken, and you would have been staring at the migration instead of your actual work. Run it in the container and the image carries the right interpreter. You never touch it.
And you no longer need the full Cassandra image just to get a shell. The slim, cqlsh-only images I teased at the bottom as “a subject for another article” exist now. loivis/cqlsh is around 16MB versus the hundreds of megabytes the full server image pulls. If all you want is the shell, swap cassandra for one of those in the aliases below.
The original write-up follows, with a couple of broken commands fixed.
I use Apache Cassandra almost daily for my job. A lot of our services require this high performance, highly available database. The command line tool cqlsh is the official tool for interacting with Cassandra. cqlsh is an easy and intuitive terminal into Apache Cassandra, but it has dependencies, one of which is Python. Over the years of local development on my MacBook Pro, I have had many tools that require Python and Python libraries. Some of these tools I installed years ago require older versions of Python, or older Python libraries not able to run in newer Python versions. Python is a great language, but sooner or later you run into dependency nightmares, (see The Nine Circles of Python Dependency Hell) including missing libs, version conflicts, and the list goes on. It makes sense to resolve these issues or use a Python version manager like Ruby’s RVM if you are actively developing locally in Python. But wait, I’m not developing in Python at the moment, I just want to run cqlsh, and it is not the weekend, so I am not motivated to Google my Python version conflicts and library dependency errors because I have a ton of work to get done. Yes, my problems, likely caused by something dumb I did playing around with the questionable code I found in the far-off corners of Github.
So I’m going to ignore my confused local install of cqlsh, the broken state of my Python and the mess I made of its libraries. I’m just going to run:
docker run -it --rm cassandra cqlsh node1.example.com -u itsme -p mypassword
It’s a one time pull of the Cassandra Docker image and once done the --rm flag cleans up the stopped container.
But that’s a lot of command for me to think about when I just need my cqlsh so I add a simple alias to my .bashrc
alias cqlsh='docker run -it --rm cassandra cqlsh'
From now on I run the command cqlsh and get just that, with all its dependencies in isolation, not worried about Python versions or state of my local workstation. Just keep Docker running well, and I’m good.
The alias above is helpful for the times I just want a cqlsh terminal to issue a few commands. However, I often need to pass cql scripts into cqlsh. So I updated my alias to always mount my current directory into a /src directory in the container. All I have to remember is that the path to a local file is /src and not ./.
alias cqlsh='docker run -it --rm -v "$(pwd)":/src cassandra cqlsh'
This allows me to run commands that pass in files, like:
$ cqlsh node1.example.com 9042 -f /src/setup_some_keyspace_and_tables.cql
The Cassandra Docker image was 323MB when I first wrote this, and it has only grown with Cassandra 5.0. Run without a command it starts a fully functional Cassandra node, which is genuinely useful for testing. But if all you want is the shell, that is a lot of image to pull. You can build a slim one with Alpine Linux and only the packages you need, or just use one of the prebuilt cqlsh-only images mentioned in the 2026 update above, like loivis/cqlsh at around 16MB.