GCSFuse + Docker: “Error while creating mount source path ‘/a’: mkdir /a: file exists.”

This post illustrates how you can mount a GCS bucket using GCSFuse on your host machine and expose it as a volume to a Docker container.

PROBLEM

You want to volume mount a FUSE-mounted directory to a container, for example:

When attempting to run the container…

docker run -it --rm -v /my-kfc-bucket:/home busybox

… an error occurred:

docker: Error response from daemon: error while creating
mount source path '/my-kfc-bucket': mkdir /my-kfc-bucket: 
file exists.

SOLUTION

Unmount the existing FUSE-mounted directory.

sudo umount /my-kfc-bucket

Mount it back with the following option. Because this command with -o allow_other must be executed with sudo privilege, you will need to change the root ownership to yourself (via –uid and –gid) so that you can easily read/write within the directory.

sudo gcsfuse \
  -o allow_other \
  --uid $(id -u) \
  --gid $(id -g) \
  gcs-bucket /my-kfc-bucket  

If it is successful, the output should look like this:

Start gcsfuse/0.40.0 (Go version go1.17.6) for app "" using mount point: /my-kfc-bucket
Opening GCS connection...
Mounting file system "gcs-bucket"...
File system has been successfully mounted.

Rerun the docker container.

docker run -it --rm -v /my-kfc-bucket:/home busybox

Now, you can read/write the GCS bucket’s data from the container. In this example, the GCS bucket’s data is located in /home.

GCP + Container Registry: Pushing/Pulling Images

PROBLEM

You want to push a new image to Google Container Registry (GCR) or pull an existing image from GCR.

SOLUTION

Pushing a New Image to GCR

Prepare your Dockerfile.

FROM alpine:3.7

# some content...

Create an image and tag it with a path pointing to GCR within a project.

There are several variations of GCR’s hostname (ex: gcr.io, us.gcr.io, eu.gcr.io, etc) depending on the data center’s location.

The GCR path has the following format: [HOSTNAME]/[PROJECT-ID]/[IMAGE].

docker build -t gcr.io/shitty-project/shitty-repo .

Log into GCP.

gcloud auth login

Register gcloud as a Docker credential helper.

gcloud auth configure-docker

Push the image to GCR.

docker push gcr.io/shitty-project/shitty-repo

View pushed image.

gcloud container images list-tags gcr.io/shitty-project/shitty-repo

DIGEST        TAGS    TIMESTAMP
78b36c0b456d  latest  2019-03-07T16:19:53

The repository and image can also be viewed in GCP Console.

Image in GCR

Pulling an Existing Image from GCR

Proceed with the authentication process if it is not done already.

gcloud auth login
gcloud auth configure-docker

Pull the image from GCR.

docker pull gcr.io/shitty-project/shitty-repo

Docker: Executing Startup Script When Running Container Interactively

PROBLEM

When running the Docker container interactively (ex: docker run –rm -it myimage), you want to run a startup script every time.

SOLUTION

For Ubuntu, Debian and Centos images, write the startup script to /root/.bashrc:

# UBUNTU
FROM ubuntu:latest
RUN echo "echo 'Welcome!'" >> /root/.bashrc
WORKDIR /home

# DEBIAN
FROM debian:latest
RUN echo "echo 'Welcome!'" >> /root/.bashrc
WORKDIR /home

# CENTOS
FROM centos:latest
RUN echo "echo 'Welcome!'" >> /root/.bashrc
WORKDIR /home

For Alpine image, it’s a little different because it uses Ash shell. Besides writing the startup script to /root/.profile, you also need to set that path to an environment variable called ENV:

FROM alpine:latest
ENV ENV=/root/.profile
RUN echo "echo 'Welcome!'" > $ENV
WORKDIR /home