Also at Deasil Works · txn2 · Plexara
Profiles GitHub · X · LinkedIn
Theme Light · Auto · Dark
Professional notes by Craig Johnston
long-form, short-form, working drafts · since 2008
VOL. XIX · MMXXVI
81 NOTES IN PRINT
FOLIO II 01 MAR 2018 · 3 MIN · SHORT-FORM

Don't Install cqlsh

Containers as utility applications

Diagram · folio ii
sequenceDiagram
    autonumber
    actor U as Developer
    participant T as Terminal
    participant DK as Docker engine
    participant CQL as cqlsh container
    participant CASS as Cassandra cluster

    U->>T: docker run --rm cassandra:3 cqlsh
    T->>DK: pull image (cached)
    DK->>CQL: run cqlsh entrypoint
    CQL->>CASS: connect on 9042
    CASS-->>CQL: protocol handshake
    CQL-->>U: cqlsh prompt

    U->>CQL: SELECT * FROM ks.users LIMIT 10
    CQL->>CASS: CQL query
    CASS-->>CQL: result set
    CQL-->>U: rows

    U->>CQL: exit
    CQL-->>T: container removed

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.

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, will 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 have to remember is that that 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 is 323MB, and when run without a command will start up a fully functional Cassandra node, which is useful for testing. However, if this is not something you need, then a 323MB image is a bit overkill. You can always make a small Docker image using [Alpine Linux], adding only the packages you need. However, that is a subject of another article I suppose.

← back to all notes