Docker版RcloneでGoogleDriveの認証情報を取得・rcloneコマンド実行
GUI不使用(headless版)はこちら
TL;DR
- selenium/standalone-chromeを使ってブラウザ認証する
- コンテナ内/home/seluser/.config/rclone/rclone.confを取り出す
- rclone/rcloneで/root/.config/rclone/rclone.confにマウント
背景
- ホスト環境を汚さずrclone認証・コマンド実行したい
手順
Selenium公式イメージでChrome実行環境を立ち上げる。例の通りコンテナ起動。
docker run -d -p 4444:4444 -p 7900:7900 --shm-size="2g" --name selenium selenium/standalone-chrome:120.0.6099.109-chromedriver-120.0.6099.109-grid-4.16.1-20231219
http://localhost:7900/?autoconnect=1&resize=scale&password=secret にアクセスし、noVNCが動いていることを確認する。
まだブラウザが立ち上がっていないので何も表示されない。
docker exec -it --user=root selenium bash -c "apt update && apt install -y rclone && rclone config"
これ以降は通常のrclone configと同様に進める
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
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
1 / 1Fichier
\ "fichier"
2 / Alias for an existing remote
\ "alias"
3 / Amazon Drive
\ "amazon cloud drive"
4 / Amazon S3 Compliant Storage Provider (AWS, Alibaba, Ceph, Digital Ocean, Dreamhost, IBM COS, Minio, Tencent COS, etc)
\ "s3"
5 / Backblaze B2
\ "b2"
6 / Box
\ "box"
7 / Cache a remote
\ "cache"
8 / Citrix Sharefile
\ "sharefile"
9 / Dropbox
\ "dropbox"
10 / Encrypt/Decrypt a remote
\ "crypt"
11 / FTP Connection
\ "ftp"
12 / Google Cloud Storage (this is not Google Drive)
\ "google cloud storage"
13 / Google Drive
\ "drive"
14 / Google Photos
\ "google photos"
15 / Hubic
\ "hubic"
16 / In memory object storage system.
\ "memory"
17 / Jottacloud
\ "jottacloud"
18 / Koofr
\ "koofr"
19 / Local Disk
\ "local"
20 / Mail.ru Cloud
\ "mailru"
21 / Microsoft Azure Blob Storage
\ "azureblob"
22 / Microsoft OneDrive
\ "onedrive"
23 / OpenDrive
\ "opendrive"
24 / OpenStack Swift (Rackspace Cloud Files, Memset Memstore, OVH)
\ "swift"
25 / Pcloud
\ "pcloud"
26 / Put.io
\ "putio"
27 / SSH/SFTP Connection
\ "sftp"
28 / Sugarsync
\ "sugarsync"
29 / Transparently chunk/split large files
\ "chunker"
30 / Union merges the contents of several upstream fs
\ "union"
31 / Webdav
\ "webdav"
32 / Yandex Disk
\ "yandex"
33 / http Connection
\ "http"
34 / premiumize.me
\ "premiumizeme"
35 / seafile
\ "seafile"
Storage> 13
** See help for drive backend at: https://rclone.org/drive/ **
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 string value. Press Enter for the default ("").
client_id>
OAuth Client Secret
Leave blank normally.
Enter a string value. Press Enter for the default ("").
client_secret>
Scope that rclone should use when requesting access from drive.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
1 / Full access all files, excluding Application Data Folder.
\ "drive"
2 / Read-only access to file metadata and file contents.
\ "drive.readonly"
/ Access to files created by rclone only.
3 | These are visible in the drive website.
| File authorization is revoked when the user deauthorizes the app.
\ "drive.file"
/ Allows read and write access to the Application Data folder.
4 | This is not visible in the drive website.
\ "drive.appfolder"
/ Allows read-only access to file metadata but
5 | does not allow any access to read or download file content.
\ "drive.metadata.readonly"
scope> 1
ID of the root folder
Leave blank normally.
Fill in to access "Computers" folders (see docs), or for rclone to use
a non root folder as its starting point.
Enter a string value. Press Enter for the default ("").
root_folder_id>
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 string value. Press Enter for the default ("").
service_account_file>
Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n>
Remote config
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>
If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=***
Log in and authorize rclone for access
Waiting for code...
上記まで進むとhttp://localhost:7900のほうでブラウザが立ち上がっていることを確認できる。
初回起動はWelcomeのメッセージが出るので適宜チェックを変更してOK
通常のrclone認証の通りにログイン要求されるので、ログインしてアプリを許可する。
rclone config側のコンソールが進められる。
Got code
Configure this as a team drive?
y) Yes
n) No (default)
y/n>
--------------------
[gdrive]
scope = drive
token = {"access_token":"トークン","token_type":"Bearer","refresh_token":"リフレッシュトークン","expiry":"有効期限"}
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d>
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
上記コンソールで出力されたconfigをコピペしてもよいが、取り逃した場合はコンテナ内にファイルが保存されているのでそれを取得する。
docker cp selenium:/home/seluser/.config/rclone/rclone.conf .
上記Seleniumコンテナでも実行できるが、無駄にSeleniumが入っているので公式の純粋なRclone実行コンテナで実行する。
Seleniumコンテナを終了
docker stop selenium
rcloneコマンド実行
docker run --rm -v ./:/data:rw rclone/rclone:1.65.0 --config rclone.conf ls -l gdrive:/
11111111 file1
22222222 file2
※コマンド実行ユーザーはrootになるので、ローカルへコピーしたファイル所有者はroot:rootとなる。
失敗パターン
認証用URLのhttp://127.0.0.1:53682/...へは、ポートマッピングで53682:53682としてもホストからアクセスすることができなかったためリダイレクトされず(要因未調査)。
docker run -it --name rclone -p 53682:53682 rclone/rclone:1.65.0 config
・・・
****/**/** **:**:** NOTICE: If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=***
****/**/** **:**:** NOTICE: Log in and authorize rclone for access
****/**/** **:**:** NOTICE: Waiting for code...
コンテナ内から認証用URLへはcurlでアクセスできるようなのでレスポンスからリダイレクト先URLを取得できるものの、そのURLでアプリ許可後のページ遷移で得られるURLをコンテナ内からcurlでアクセスしても認証失敗となる(仕組み未確認)。
docker exec -it rclone sh -c "apk add curl && curl http://127.0.0.1:53682/auth?state=***"
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/community/x86_64/APKINDEX.tar.gz
(1/6) Installing brotli-libs (1.0.9-r14)
(2/6) Installing libunistring (1.1-r1)
(3/6) Installing libidn2 (2.3.4-r1)
(4/6) Installing nghttp2-libs (1.57.0-r0)
(5/6) Installing libcurl (8.5.0-r0)
(6/6) Installing curl (8.5.0-r0)
Executing busybox-1.36.1-r2.trigger
OK: 15 MiB in 26 packages
<a href="https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=***.apps.googleusercontent.com&redirect_uri=http%3A%2F%2F127.0.0.1%3A53682%2F&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&state=***">Temporary Redirect</a>.
docker exec -it rclone sh
curl http://127.0.0.1:53682/?state=***&code=***&scope=https://www.googleapis.com/auth/drive
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Failure!</title>
</head>
<body>
<h1>Failure!</h1>
<hr>
<pre style="width: 750px; white-space: pre-wrap;">
Error: Auth Error<br>
Description: No code returned by remote server<br>
</pre>
</body>
</html>
[2]+ Done curl http://127.0.0.1:53682/?state=***
[1]+ Done curl http://127.0.0.1:53682/?state=***
Error: config failed to refresh token: Error: Auth Error
Code: ""
Description: No code returned by remote server
そのためコマンドのみでの認証は諦めて、コンテナ内でGUIブラウザ実行できる環境として今回は最低限Chromeが起動できるselenium公式イメージを使用。
デスクトップ環境があるようなGUIブラウザ実行できるイメージならおそらくどれでもできるはず。
Discussion