Share .netrc with your devcontainers

I do almost all my development inside devcontainers these days. (I take the term “devcontainer” from VS Code’s .devcontainer/devcontainer.json. I think it’s a useful term, and I’ve adopted it into my vernacular for the general case of “development-specific container”)

Some developer service clients, such as Heroku’s CLI tools, store their sensitive API keys in a ~/.netrc file. This is a semi-standardized (or at least conventionalized) file used by a number of UNIX utilities.

If you’re doing your development in a container, files like ~/.netrc can pose some problems, or at least prompt some considerations.

  • You don’t want to have to log in to Heroku (or whatever) every time you spin up or rebuild a devcontainer.
  • Even though you’re not using them for production deploys (right??), you may still want to push devcontainer images to a repository for the convenience of your teammates or CI. You don’t want to be capturing sensitive login info in an image that’s proliferating to other machines and potential public.
  • You may have a standard set of dotfiles that you fetch into your devcontainers (VSCode has a wonderful feature for this), but you probably keep your dotfiles in a public git repo. Not the sort of place you want to be putting API keys.
  • There are lots of good reasons not to bind your entire home directory into a Docker container.

If you’re using docker-compose, you can use something like the following to bind your host `~/.netrc` into your dev container’s home directory at runtime:

services:
  app:
    # ...
    volumes:
      - type: bind
        source: ${HOME}${USERPROFILE}/.netrc
        target: /root/.netrc
        # ...

Now you can log in to Heroku (or whatever) once, and reuse that login anytime you rebuild this container, as well as in any other containers you configure this way.

Note the use of trying both HOME and USERPROFILE to keep things host platform-neutral. One of the perks of using devcontainers is that you can develop on any host OS!

This example also makes the assumption that /root is the user home directory inside the devcontainer. I tend to stick with the root (admin) user inside devcontainers, rather than defining a separate unprivileged account. All the considerations that would normally push me to use unprivileged user accounts are taken care of by the fact that I’m running inside an isolated container.

(Don’t use docker-compose for your devcontainers? Consider adding it—even for an app that doesn’t depend on any other services! Just as Dockerfile is a great way to document your app’s dependencies and runtime expectations as versioned code, docker-compose.yml is a great way to document how to start your devcontainer as versioned code.)

Danger, Will Robinson!

Now, there’s one thing you need to be careful of when using this configuration: make sure ~/.netrc exists before you start your devcontainer. The reason is that if it doesn’t already exist, Docker will create it… as a directory. Oops.

So just be sure to touch ~/.netrc before you spin up your devcontainer, and you’ll be fine.

Comments are closed.