I wanted to run Google Cloud’s gcloud commandline tool in a Docker container and, modulo security flaws in Docker for Mac, not expose my entire home directory to it. A wrapper script got me most of the way there:

#!/bin/sh
docker run --interactive --tty --user 1000 \
	--volume "$HOME/.gcloud:/config/dotgcloud" \
	--env "CLOUDSDK_CONFIG=/config/dotgcloud" \
	google/cloud-sdk \
	gcloud "$@"

With this in place, I can create the required directory and go through the login process:

$ mkdir -m700 $HOME/.gcloud
$ gcloud auth login
... login process

gcloud includes a subcommand that modifies $HOME/.docker/config.json to use an authentication helper for Google Container Registry; this allows access to my private container repositories. After running this config step, my Docker config looked like this (reformatted slightly for brevity):

{
  "experimental": "disabled", "stackOrchestrator": "swarm", "auths": {},
  "credHelpers": {
    "us.gcr.io": "gcloud", "eu.gcr.io": "gcloud",
    "asia.gcr.io": "gcloud", "staging-k8s.gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud", "gcr.io": "gcloud"
  },
  "credsStore": "desktop"
}

The wrapper script:

#!/bin/sh
docker run --interactive --tty --user 1000 \
	--volume "$HOME/.gcloud:/config/dotgcloud" \
	--volume "$HOME/.docker:/root/.docker" \
	--env "CLOUDSDK_CONFIG=/config/dotgcloud" \
	google/cloud-sdk \
	gcloud auth configure-docker "$@"

Finally, a wrapper script for the actual credential helper. This script must be named docker-credential-gcloud. Also note the lack of --tty. This one is not intended for interactive use:

#!/bin/sh
docker run --interactive --user 1000 \
	--volume "$HOME/.gcloud:/config/dotgcloud" \
	--env "CLOUDSDK_CONFIG=/config/dotgcloud" \
	google/cloud-sdk \
	/usr/lib/google-cloud-sdk/bin/docker-credential-gcloud "$@"

A key goal of this exercise was to avoid exposing my home directory where not strictly necessary. I have achieved this, though of course this does mean that gcloud commands that operate on local files won’t work. The only example of those that I actually use is gsutil, for which the below wrapper — which exposes only the current directory to the Docker container — is sufficient:

#!/bin/sh
docker run --interactive --tty --user 1000 \
	--volume "$HOME/.gcloud:/config/dotgcloud" \
	--volume "`pwd`:/host" \
	--workdir /host \
	--env "CLOUDSDK_CONFIG=/config/dotgcloud" \
	google/cloud-sdk \
	gsutil "$@"

With these wrappers included in $PATH, I can now interact with Google Cloud in the ways that I need to.