uncategorized

Mounting Google Drive on Raspberry Pi

How to use rclone, FUSE, and systemd to automatically mount your Google Drive on your Raspberry Pi.

I wrote the first version of this article in the Spring of 2019. In the meantime the world has moved on, so I figured it’s time for an update of these instructions to incorporate recent changes.

The Raspberry Pi is a great little device to run a variety of services in your home network. It saves files on a user-provided SD card or USB stick. But what if you want to store files off-device to safeguard the work that you’ve put in to set up whatever services you’re running on your Pi? What if you would like to share files between multiple Pis? Or what if you have files like your photos living in the cloud already and you’d like to easily access them from your Pi? This article shows how you can connect your Google Drive to your Raspberry Pi for all the above use cases and more.

Which Software to Use?

The first thing we have to decide is which software to use. When you look around for software to connect Google Drive to a Linux environment you run into projects with a wide range of different features and requirements. Some are better maintained than others. The one I’ve chosen here is rclone, which is actively maintained and provides a lot of functionality. In particular, with the help of the FUSE userspace filesystem layer, it allows you to mount Google Drive as part of your Linux file system, which greatly simplifies using the cloud storage from your Pi. These instructions will probably also work on most other Debian Linux based distributions with little or no change.

Rclone is much more versatile than the limited usage described in this article. It doesn’t only support Google Drive but a whole host of other cloud storage providers as well, such as Amazon Drive, Dropbox, or Microsoft OneDrive to name just a few of the larger ones. Besides allowing you to mount one of those cloud storage services into your file system, it also provides a set of CLI commands to directly manipulate files on those services. In this article, however, we won’t use them and concentrate on using rclone mount.

The installation instructions below assume that you’re logged in to your Raspberry Pi and execute all instructions there, unless otherwise noted.

Installing Rclone on Raspbian

The easiest way to install rclone is to use the pre-compiled Debian package:

1
sudo apt-get install rclone

As of this writing, the current release of Raspberry Pi OS (aka. Raspbian) is based on Debian v.11 (Bullseye). I’m writing this for a plain install of the 32-bit Raspberry Pi OS with desktop. If you have installed a different version, you will potentially have to adapt software to install, e.g. use the 64-bit versions if you are running a 64-bit OS. The version of rclone we get via apt-get is 1.53.3. However, rclone has progressed to version 1.59.2 in the meantime. To get a more up-to-date version, instead of using the apt package that comes with the default Raspberry Pi OS package repositories, we’re going to install an up-to-date rclone package from its download page:

1
2
3
4
cd /tmp
wget https://downloads.rclone.org/v1.59.2/rclone-v1.59.2-linux-arm-v7.deb
sudo apt install ./rclone-v1.59.2-linux-arm-v7.deb
rm rclone-v1.59.2-linux-arm-v7.deb

Configuring Rclone

Since the remote files we’re going to access are private to a particular user, rclone keeps configuration files separate per user. All secret access tokens necessary to interact with the cloud storage are stored in a user’s config file such that different users can’t access each other’s cloud storage. By default the config file is located in $HOME/.config/rclone/rclone.conf and should have permissions of 0600 (read-write only for file owner) to make sure your access tokens remain private.

For Google Drive there is another consideration. If you go with the default configuration, you’re using the client_id that corresponds to the rclone application. Google imposes per-client rate limits on interactions with Google Drive. This means that by using the rclone default client_id you’re competing against all other users of rclone, globally, for operation bandwidth to Google Drive. Even though the rclone authors try to mitigate this by asking Google for higher quotas, using the default is not an ideal situation. For this reason we’ll set up our own client_id with Google and avoid the stampede.

Getting a Google Drive Client ID

In a browser go to the Google Developer Console and log in with your Google account. You don’t have to do this on your Raspberry Pi. Any computer is fine.

  • On the top bar go to Project list (Select a project) → New Project
    • Fill in a Project Name: my-rclone-gdrive-access
    • Hit Create
  • Go back to the Project list (Select a project) and select the my-rclone-gdrive-access project.
  • On the left side-panel select Enable APIs & services
  • On the top select + ENABLE APIS AND SERVICES
    • In the search box search for Drive
    • Select Google Drive API
    • Hit Enable
  • On the left side-panel select OAuth consent screen
    • Select User Type: External
    • Hit Create
    • Fill in the App Name: my-rclone
    • Fill in the Support Email: <your-gmail-address>
    • Fill in Developer contact information: Email: <your-gmail-address>
    • Leave all the other fields as default on this screen
    • Hit SAVE AND CONTINUE
    • Hit ADD OR REMOVE SCOPES
    • Pick Google Drive API, ../auth/drive (which can “see, edit, create, and delete all of your Google Drive files”)
    • Hit UPDATE
    • Hit SAVE AND CONTINUE
    • Hit Test users: + ADD USERS
    • Fill in your gmail user (or any other Google user ID you’d like to use to access your Drive files with)
    • Hit ADD (twice)
    • The user you just filled in should show up in the list under User information now
    • Hit SAVE AND CONTINUE
  • Hit Credentials on the left side-panel
    • Select + CREATE CREDENTIALS on the top menu inside the main panel
    • Select OAuth client ID
    • Select Application type: Desktop
    • Set some sensible name: my rclone client
    • Hit CREATE
    • You’ll get a confirmation popup OAuth client created containing the client ID and client secret which looks like this. Copy the client ID and client secret since we’ll need it for the rclone configuration.

Setting up the Rclone Configuration

Back on the Raspberry Pi, log in as the Linux user who should be able to access the Google Drive files and run:

1
rclone config

Select the following answers:

No remotes found - make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
Enter name for new remote.
name> gdrive
Type of storage to configure. Enter a string value. Press Enter for the default (""). Choose a number from below, or type in your own value ... snip ... 18 / Google Drive \ (drive) ... snip ... Storage> 18
Option client_id. Google Application Client Id Setting your own is recommended. See https://rclone.org/drive/#making-your-own-client-id for how to create your own. If you leave this blank, it will use an internal key which is low performance. Enter a value. Press Enter to leave empty. client_id> 103XXXXXXXXXXXXXXXXXuso.apps.googleusercontent.com

This is the client ID that you saved in the earlier step. If you forgot to save it, you can always find it by going to Credentials → OAuth 2.0 Client IDs → <name-of-your-id> and the information will be presented to you again.

Option client_secret.
OAuth Client Secret.
Leave blank normally.
Enter a value. Press Enter to leave empty.
client_secret> GOCXXXXXXXXXXXXXXXXXyXc

This is the client secret that you saved in the earlier step.

Option scope.
Scope that rclone should use when requesting access from drive.
Choose a number from below, or type in your own value.
Press Enter to leave empty.
1 / Full access all files, excluding Application Data Folder.
  \ (drive)
... snip ...
scope> 1
Option service_account_file. Service Account Credentials JSON file path. Leave blank normally. Needed only if you want use SA instead of interactive login. Leading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`. Enter a value. Press Enter to leave empty. service_account_file>
Edit advanced config? (y/n) y) Yes n) No (default) y/n> n
Use auto config? * Say Y if not sure * Say N if you are working on a remote or headless machine y) Yes (default) n) No y/n> y

Google no longer offers the out-of-band (OOB) method of configuring a client, which used to be the most convenient option for this situation. A good overview can also be found in the rclone documentation. You have several options here now:

  • 1a) If you are working on your Raspberry Pi in the GUI, you’re all set. Select Yes (autoconfig) and just follow the prompts.
  • 1b) If you are logged into your headless Raspberry Pi via SSH, i.e. one that doesn’t have a display connected and no GUI, you can use SSH port forwarding to pass this authorization step.
  • 2 ) If none of the above are true, you need another desktop machine with the same version of rclone installed on which you perform a remote authorization step. In that case you need to select No in the previous question and follow the prompts.

I’m assuming here that you’re in situation 1b, i.e. logged in via SSH, and have chosen Yes (auto config) in the previous question. Rclone config continues:

NOTICE: Make sure your Redirect URL is set to "http://127.0.0.1:53682/" in your custom config.
NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=5l4XXXXXXXXX-Iw
NOTICE: Log in and authorize rclone for access
NOTICE: Waiting for code...

Rclone config is waiting for a web browser to connect to your Raspberry Pi port 53682. However, we’re assuming you’re not running a GUI with a web browser on the Raspberry Pi. We’ll use SSH port forwarding to forward that port to the host machine from which you SSH into the Raspberry Pi, assuming that you are running a full desktop with GUI there and use the web browser on that host machine. To do that, open a second SSH session from your host to your Raspberry Pi, just to forward the port. On your host type:

1
ssh -L localhost:53682:localhost:53682 <your-pi-user>@<your-pi-host>

After you log in, just leave this second terminal window alone.

Copy the URL that got printed on your screen earlier (http://127.0.0.1:53682/auth?state=5l4XXXXXXXXX-Iw) to a new browser window on your desktop machine. In the page flow that follows, select your user account (if required) and confirm that you want to give your application access to your Google Drive. Eventually you’ll get to a web page that says:

Success!
All done. Please go back to rclone.

You can close that browser window and the second terminal window that you have opened for the SSH port forwarding. In the meantime, in the first terminal window, rclone config has continued:

NOTICE: Got code
Configure this as a Shared Drive (Team Drive)? y) Yes n) No (default) y/n> n
Configuration complete. Options: - type: drive - client_id: 103XXXXXXXXXXXuso.apps.googleusercontent.com - client_secret: GOCXXXXXXXXXXXXXXyXc - scope: drive - token: {"access_token":"ya2XXXXXXXXX163","token_type":"Bearer","refresh_token":"1//06_XXXXXXXXXXXXjb8","expiry":"2022-09-21T22:42:18.157766331-07:00"} - team_drive:

This last section shown above is a copy of the information that will be put into your $HOME/.config/rclone/rclone.conf config file. If everything looks correct we’re going to accept it and exit the configuration menu.

Keep this "gdrive" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Current remotes: Name Type ==== ==== gdrive drive e) Edit existing remote n) New remote d) Delete remote r) Rename remote c) Copy remote s) Set configuration password q) Quit config e/n/d/r/c/s/q> q

You can now test that you have set up the configuration correctly with:

1
rclone ls --max-depth 1 gdrive:

This rclone command should show you all regular files in the top-level directory of your Google Drive. The next step is to test mounting Google Drive into your file system:

1
2
3
cd ~
mkdir -p mnt/gdrive
rclone mount gdrive: $HOME/mnt/gdrive

In a second terminal on your Raspberry Pi run:

1
ls -l ~/mnt/gdrive

This should again list all files in the top-level directory of your Google Drive. Since your cloud storage is now part of the regular file system, any program on you Pi can access it just like any other file. After this test stop the above rclone command in the first terminal with Ctrl-C.

Automatically Mounting Google Drive

The setup above is all that is necessary to use the rclone mount command and mount Google Drive by hand into your file system whenever you need it. However, that is a bit cumbersome. It would be better if Google drive were mounted automatically whenever the corresponding user logs in. This can be achieved with systemd, a daemon that starts and stops services when needed. Systemd operates in one of two modes, a --system mode that handles machine-wide services such as bringing up networking, and a --user mode that deals with per-user services such as starting the desktop environment and in our case we want it to mount the rclone FUSE file system for Google Drive. A good place to learn more is the archlinux wiki for per-user systemd.

Configuring Systemd

To tell systemd what to do it depends on configuration files in some standard locations. One of these locations where systemd looks for user config files is $HOME/.config/systemd/user. To have the rclone FUSE file system mounted automatically at login, create a ~/.config/systemd/user/rclone@.service file with the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=rclone: Remote FUSE filesystem for cloud storage config %i
Documentation=man:rclone(1)

[Service]
Type=notify
ExecStartPre=/bin/mkdir -p %h/mnt/%i
ExecStart= \
/usr/bin/rclone mount \
--vfs-cache-mode writes \
--vfs-cache-max-size 100M \
%i: %h/mnt/%i

[Install]
WantedBy=default.target

Note: If you’re using rclone version < 1.46, remove the --vfs-cache-max-size line, as that flag is not yet supported in earlier versions.

Here the special @ syntax in the config filename defines a service template which allows to write a single config file that can be used for multiple instantiations. Even though we wouldn’t really need a service template for our simple use case, we use it so the configuration already supports multiple mounts, e.g. if you also want to use it for other cloud storage providers as well. When using the systemd service name, which derives from the file name, you just append an instance name to @ and systemd will replace all occurrences of %i in the config file with that instance name. In our case the instance name represents the rclone remote name which we have configured in the rclone.conf file above, i.e. gdrive.

On the rclone mount command line above we use a particular set of mount options that are supported for Google Drive. A full list of options can be found in the rclone Google Drive documentation. More details on general mount options can be found in the rclone mount documentation.

Once we’ve got the config file in place we need to let systemd know about the new configuration for our gdrive rclone remote:

1
systemctl --user enable rclone@gdrive

This should install a symbolic link rclone@gdrive.service -> $HOME/.config/systemd/user/rclone@.service in ~/.config/systemd/user/default.target.wants/.

Now that systemd is aware of the new service, the next step is to turn it on:

1
systemctl --user start rclone@gdrive

Once turned on, when you list the mount directory

1
ls -l ~/mnt/gdrive

you should see the contents of your Google Drive directory again.

At this point what we have achieved works great for interactive user sessions. Every time you log in to your Raspberry Pi as the user for which you have set up Google Drive, it is mounted automatically into the file system which gives you access to the contents of your cloud storage.

Starting User-Systemd at Boot Time

For some use cases, mounting at user login time is still not quite enough. For example on my system I run an RStudio Server, which is a web IDE for the R programming language. The RStudio Server web interface first presents a login page to authenticate the user. Once it has checked the user’s credentials it starts an rsession for them. However, starting an rsession with the UID of the authenticated user doesn’t constitute a login or session for that user. Thus no systemd user session is started and the actions that would mount the cloud storage are not performed, so the RStudio IDE doesn’t have access to the cloud storage directory of the user.

There is a solution to this problem though. We can instruct systemd to start a user session at boot time instead of login time with the following command:

1
loginctl enable-linger $USER

Now, whenever our Raspberry Pi boots, a systemd user session is started immediately for that user, mounting the configured Google Drive and enabling use cases like RStudio Server mentioned above.

If you’ve followed the setup to here, congratulations! You’ve got your Raspberry Pi connected to your Google Drive and can easily access files from your cloud storage from any program running on your Pi just by accessing files under $HOME/mnt/gdrive.