Post

Vibe Coding with Devcontainers in the CLI

I’ve been a “terminal jockey” for many years, and just can’t stand the experience of a complicated user interface. The sheer simplicity of writing and editing code in Vim (and more recently, Neovim) allows me to focus on the design and logic of the applications I’m developing. There’s no IntelliSense or Copilot suggestions interfering with my flow – and aside from choosing a color theme, there’s literally zero visual complexity. It’s just me and my code.

Due to this personal preference, I’ve largely skipped past the hype surrounding Visual Studio Code (VSCode) and it’s LLM-integrated forks like Cursor and Windsurf. Having said that, during my recent “staycation” I decided to look into leveraging devcontainer functionality in my terminal. I wanted to properly segment LLM coding tools from the rest of my filesystem for… reasons 😅 And while I had previously heard of devcontainers in VSCode, I wanted something simple that I could run in my terminal – preferably without a lot of complexity.

In this post I’ll share some of the tooling and scripts I discovered while on this journey, along with a few tips-and-tricks for spinning up your own devcontainer in the command line interface (CLI) of your choosing. Finally, I’ll share a fork of Dreadnode’s Paperstack app where I vibe coded support for the Claude API – along with a few other minor improvements.

But first, a bit of humor

The "It's a Peaceful Life" meme from Rogue One

Choosing a container runtime

The common tool people reference when working with containers is Docker, which infamously pissed off their user base with their Docker Desktop per-seat subscription pricing announcement back in 2022.

More recently, Apple announced their own container tool for running Linux containers as lightweight virtual machines on Apple Silicon. And while I might be a self-proclaimed “terminal jockey”, I’m not that much of a bleeding-edge user that I’m ready to play with it just yet.

That said, I’m personally using OrbStack thanks to my friend Natalie’s recommendation. The desktop app has a simple UI/UX, is free for personal use, and Just Works ™️. Moreover, it provides uncomplicated command line capabilities – and I honestly can’t ask for much more than that from my tools 🥰 Anyway, all of the guidance provided in this post works seamlessly on a macOS system running OrbStack.

Setting up your devcontainer

While reading more about devcontainers (thank you, Microsoft) I stumbled upon their CLI tooling on GitHub, which supports installing, building, and running devcontainers in your CLI from a configuration file. Since you already need npm to install Claude Code in your terminal, it makes sense to install devcontainer as well:

1
npm install -g @devcontainers/cli

Now that you’ve got devcontainer installed, it’s helpful to have a reference devcontainer.json to work from – and thankfully Anthropic has shipped a reference devcontainer with their claude-code GitHub repository, which can be found in the .devcontainer folder.

To make life a little easier (and to avoid having to remember devcontainer commands), I also wrote a quick Bash script to handle spinning-up new containers before creating a symlink for it in /usr/local/bin.

1
2
3
#!/bin/bash
devcontainer up --workspace-folder . && \
devcontainer exec --workspace-folder . bash

At this point, all I need to do is copy over the .devcontainer directory, along with the Script and scripts directories from my local claude-code checkout into whatever repo I want to work with in order to spin up a devcontainer and start “vibe coding” with claude 🤪

A minor critique of Anthropic’s devcontainer

I shared the devcontainer Dockerfile mentioned above with Natalie for a sanity check, as she’s my go-to guru on all-things-container security. She shared a couple of 🚩 red flags 🚩 with me that are worth mentioning here, but weren’t a “show stopper” for my use case.

🚩 No. 1: Claude Code is given full control of the host’s network stack if you run the container with --network=host. Don’t do this and you should be fine.

🚩 No. 2: While it’s good that the container is not running as root, Claude Code is still given sudo access within the container – which is likely required to modify the iptables settings using the included scripts, but otherwise feels unnecessary if you’re just writing software.

Natalie also mentioned that the implementation looks like it was intended to run inside of a GitHub Codespace or a Gitpod, which would naturally limit any negative side effects from these red flags. If your goal is filesystem isolation – and you’re not YOLOing container network settings – then you should be good to go.

Modifying Paperstack

One of the practices I picked up from joining Trail of Bits has been reading academic research in order to better understand what’s taking place at the bleeding-edge of ML/AI security. This is where Dreadnode’s Paperstack app comes into the picture; it’s an arXiv search tool intended to run inside a GitHub Action that categorizes and summarizes papers using OpenAI before writing the details out to a Notion database.

With a working devcontainer to isolate my filesystem from the LLM, I went about vibe coding my own fork of Paperstack in order to add support for the Claude API with a --use-claude command. In the process I also added support for a .env file to store credentials locally, and included a --max-papers command that intelligently modifies the number of papers it searches for in order to discover unique papers to add to the Notion database.

A Screenshot of a Notion database listing MLAI security research papers names, summaries, focus, arXiv links, authors, etc.

Observations from vibe coded apps

Generally speaking, vibe coding enterprise-grade software is reckless – and is likely to create a number of security (and privacy) issues in the process. It has been known to introduce design flaws which lead to authentication and authorization issues in multi-user applications, among other concerns.

Having said that – for small, encapsulated, hobbyist projects that can run locally (like Paperstack), it’s generally safe to experiment with vibe coding. The only real concern is potentially messing up your filesystem in the process, which hopefully this post has helped you mitigate.

A final bit of humor if you made it this far

Here’s what happened when I searched Google for vim.

A screenshot of searching Google for "vim" and receiving the suggestion "Did you mean: emacs"

Seriously, Google? Although if you search for emacs it suggests “Did you mean: vim” – so I guess all is fair in love and terminal-editor-holy-war 😆 Well played 👏


If you found this post interesting, useful, or even amusing, I invite you to support my content through Patreon — and thank you once again for stopping by 😊 While I consider my next blog post, you can git checkout my human-centric weekly newsletter, or other (usually off-topic) content I’m reading over at Instapaper.

Until next time, remember to git commit && stay classy!

Cheers,

Keith

This post is licensed under CC BY 4.0 by the author.