Docker Repice for "gcsfuse" (Google Cloud Storage FUSE)

What's gcsfuse ?

from: https://cloud.google.com/storage/docs/gcs-fuse

Cloud Storage FUSE is an open source FUSE adapter that allows you to mount Google Cloud Storage buckets as file systems on Linux or OS X systems.

gcsfuse main repository: https://github.com/GoogleCloudPlatform/gcsfuse

Dockerize it

This is the product of many hours of my trail-and-error.

In the Dockerfile:

FROM debian:latest

RUN apt-get update  
RUN apt-get install -y curl lsb-release

RUN export GCSFUSE_REPO=gcsfuse-`lsb_release -c -s` \  
    && echo "deb http://packages.cloud.google.com/apt $GCSFUSE_REPO main" | tee /etc/apt/sources.list.d/gcsfuse.list \
    && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

RUN apt-get update  
RUN apt-get install -y gcsfuse

# need to run command with given user_id
RUN apt-get install -y sudo

# set running environments
ENV GOOGLE_APPLICATION_CREDENTIALS /credential.json  
ENV BUCKET_NAME undefined-bucket-name  
ENV UID 1  
ENV DATA_DIR /mnt

COPY entrypoint.sh /  
ENTRYPOINT ["sh", "/entrypoint.sh"]  

In the entrypoint.sh:

# just in case ...
chown -R ${UID}:${UID} ${DATA_DIR} 

# run with given user
exec sudo -u "#${UID}" gcsfuse --foreground --key-file=${GOOGLE_APPLICATION_CREDENTIALS} ${BUCKET_NAME} ${DATA_DIR}  

You may build it using: docker build -t gcsfuse .

The run command:

BUCKET_NAME=<your_bucket_name> \  
UID=${UID} \  
docker run -it --rm --privileged \  
  -v /etc/passwd:/etc/passwd:ro \
  -v <path_to_credentials>:/credential.json:ro \
  -v <your_mount_path>:/mnt:shared \
  gcsfuse

Note: :shared is crucial here ... it allows late-mouting in the container be visible to the host filesystem, without it, the host will not see anything as a result that the mounting point is being replaced by the newer one, and thus becoming obsolete.

Note2: the credential.json is the Service Account Key obtained from google cloud' api manager (https://console.cloud.google.com/apis/credentials) in the form of json file.

Note3: --privileged mode is there on purpose, without which fusemount wouldn't work.

Note4: /etc/passwd:/etc/passwd:ro is there becasue we want to mount with YOU as the owner. In this case, you have to run commands (in entrypoint.sh) using your privileges, however, it won't succeed without a proper /etc/passwd file that in which has your username inscribed.

Note5: if you run the container in detached mode, the only clean way to stop the container is to kill it using kill -S SIGINT not by stop.

Okay, you're asking for a docker-compose recipe:

version: '2'

services:  
    gcsfuse:
        build: .
        environment: 
            - BUCKET_NAME=<your-bucket-name-here>
            - UID=<your-user-id-here>
        volumes:
            - ./credential.json:/credential.json:ro
            - ./mnt:/mnt:shared
            - /etc/passwd:/etc/passwd:ro
        privileged: true

At your disposal, run docker-compose up

Warning: there is a problem when stopping docker-compose using ctrl+c or down, it will forget to unmount the drive first ! In that case, you have to manually sudo umount <path> on the host by yourself. docker-compose kill -s SIGINT might be the only CLEAN way of stopping the docker-compose.

Konpat Preechakul

Read more posts by this author.