From 5ebe562a6225b9cc5fd58756d35941204a62f7d9 Mon Sep 17 00:00:00 2001 From: ci Date: Fri, 19 Jun 2026 12:48:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=20nginx=20?= =?UTF-8?q?=E5=8F=8D=E4=BB=A3=EF=BC=8C=E5=8D=95=E5=AE=B9=E5=99=A8=20rclone?= =?UTF-8?q?=20rcd=20=E8=87=AA=E5=B8=A6=E9=9D=99=E6=80=81=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前用 nginx 做反代是从 cmd/gui/gui.go 的双端口架构沿袭下来的, 没必要——rclone rcd 的 --rc-files 参数本来就能用 http.FileServer 服务静态文件,--rc-serve 服务远端文件下载,浏览器同源访问无需 CORS、无需双端口、无需额外镜像。 - 删除 Dockerfile.webgui、docker/nginx.conf、docker/、.dockerignore (单容器用官方 rclone/rclone 镜像,不再需要构建前端镜像) - docker-compose.yml: 单服务 rclone rcd,5580 端口同时承担: * GET / 静态前端 (--rc-files=/web) * POST /* RC API(内置) * GET /:* 远端文件下载 (--rc-serve) webgui/web/ 只读挂载到 /web - README: 移除 nginx 说明,标注后续 TLS / 自定义 header 由用户 自行在前面加反代 --- .dockerignore | 38 -------------------------- Dockerfile.webgui | 13 --------- README.md | 28 +++++++++++--------- docker-compose.yml | 43 +++++++++++------------------- docker/nginx.conf | 66 ---------------------------------------------- 5 files changed, 31 insertions(+), 157 deletions(-) delete mode 100644 .dockerignore delete mode 100644 Dockerfile.webgui delete mode 100644 docker/nginx.conf diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index deca834..0000000 --- a/.dockerignore +++ /dev/null @@ -1,38 +0,0 @@ -# Keep the frontend image build context small. -# We only need: -# - webgui/web/ (the static frontend bundle) -# - docker/nginx.conf (the reverse-proxy config) -# - Dockerfile.webgui - -# VCS metadata -.git -.gitignore -.gitmodules -.github - -# The Go-side webgui command is not needed for the frontend image — -# the official rclone/rclone container handles the backend. -webgui/webgui.go -webgui/*.patch - -# Submodule source — the frontend image doesn't need rclone itself. -rclone - -# Local rclone config (contains secrets) -config/ - -# Editor / OS cruft -.idea -.vscode -.history -.devcontainer -*~ -_junk -Thumbs.db -.DS_Store -__pycache__ - -# Docs that don't belong in the runtime image -CLAUDE.md -DESIGN.md -README.md diff --git a/Dockerfile.webgui b/Dockerfile.webgui deleted file mode 100644 index 3984cec..0000000 --- a/Dockerfile.webgui +++ /dev/null @@ -1,13 +0,0 @@ -# Frontend image for the rclone webgui. -# Serves the static bundle (./webgui/web/) via nginx and reverse-proxies -# RC API calls + remote file downloads to the rclone rcd container on -# the compose network. Same-origin from the browser's perspective, so -# no CORS headaches. - -FROM nginx:1.27-alpine - -LABEL org.opencontainers.image.title="rclone-webgui-frontend" -LABEL org.opencontainers.image.description="Static frontend for the rclone webgui, served by nginx with a reverse proxy to rclone rcd." - -COPY webgui/web/ /usr/share/nginx/html/ -COPY docker/nginx.conf /etc/nginx/conf.d/default.conf diff --git a/README.md b/README.md index 205c67f..60a9237 100644 --- a/README.md +++ b/README.md @@ -13,13 +13,11 @@ ├── webgui/ # webgui 源码(在父仓库,不在 rclone 子模块里) │ ├── webgui.go # Go 子命令源码(仅当自行构建 rclone 时需要) │ ├── rclone-cmd-all-add-webgui-import.patch # 注解:把 webgui 注册进 rclone 的 cmd/all -│ └── web/ # 静态前端(nginx 服务的就是这一份) +│ └── web/ # 静态前端(rclone rcd 直接服务) │ ├── index.html │ └── assets/ -├── docker/ # nginx 反向代理配置 ├── config/rclone/ # rclone.conf 挂载点(bind mount,不提交) -├── Dockerfile.webgui # 前端镜像构建(nginx + 静态资源) -├── docker-compose.yml # rclone rcd + gui 双服务编排 +├── docker-compose.yml # 单容器 rclone rcd ├── DESIGN.md # UI 设计系统规范 ├── CLAUDE.md # Claude Code 协作指引 └── rclone/ # submodule → github.com/rclone/rclone,纯净不改动 @@ -41,23 +39,27 @@ ## 快速开始 ```bash -# 1. 拉取子模块 +# 1. 拉取子模块(rcd 流程用不到,自行构建 rclone 二进制时才需要) git clone --recurse-submodules -# 或在已克隆的仓库里: -git submodule update --init -# 2. 启动堆栈 -docker compose up -d --build +# 2. 启动堆栈(单容器,无需 build) +docker compose up -d # 3. 打开 http://localhost:5580 ``` -## 端口 +## 架构 -| 端口 | 服务 | 说明 | +只用一个 rclone rcd 容器,一个端口(5580),同时承担: + +| 职责 | URL | 配置项 | |---|---|---| -| 5580 | gui (nginx) | 浏览器入口;同源反代 RC API | -| 5572 | rclone rcd | 可直接 curl / `rclone rc` 访问 | +| 静态前端 | `GET /` | `--rc-files=/web` | +| RC API | `POST /config/*`、`/operations/*`、`/sync/*`、`/job/*` | 内置 | +| 远端文件下载 | `GET /:` | `--rc-serve` | + +浏览器同源访问 → 不需要 CORS、不需要 nginx、不需要双端口。 +要加 TLS 或自定义 header 时,**在前面套你自己的反代**即可。 ## 自行构建 rclone(可选) diff --git a/docker-compose.yml b/docker-compose.yml index be4d622..e37202e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ # Docker Compose stack for the rclone webgui. # -# Two services: -# - rclone : official rclone/rclone image running `rcd` with --rc-serve -# and --rc-no-auth. Exposed on host port 5572 so you can -# also drive it directly with curl / rclone rc if needed. -# - gui : nginx serving the embedded frontend bundle on host port -# 5580, reverse-proxying RC API + remote-file downloads -# to the rclone container. Open this in your browser. +# A single rclone rcd container does all three jobs on one port: +# - Serves the static frontend from webgui/web/ (--rc-files) +# - Serves RC API endpoints at POST /* (built-in) +# - Serves remote files at GET /: (--rc-serve) +# +# Same-origin from the browser, so no CORS / no nginx / no double ports. +# For TLS or custom headers, put a reverse proxy of your choice in front. # # rclone config lives in ./config/rclone/rclone.conf (bind-mounted). # If it doesn't exist yet, create your remotes with: @@ -14,24 +14,27 @@ # or copy an existing rclone.conf into ./config/rclone/ before starting. # # Usage: -# docker compose up -d --build # build + start +# docker compose up -d # start # open http://localhost:5580 -# docker compose logs -f gui rclone # tail logs -# docker compose down # stop +# docker compose logs -f rclone # tail logs +# docker compose down # stop services: rclone: image: rclone/rclone:latest - container_name: rclone-rcd + container_name: rclone-webgui command: - rcd - --rc-no-auth - - --rc-addr=:5572 + - --rc-addr=:8080 + - --rc-files=/web - --rc-serve - --rc-job-expire-duration=24h - --rc-job-expire-interval=1m - -vv volumes: + # Static frontend served by rclone's own http.FileServer. + - ./webgui/web:/web:ro # rclone looks for $XDG_CONFIG_HOME/rclone/rclone.conf; the # official image sets XDG_CONFIG_HOME=/config. - ./config/rclone:/config/rclone @@ -43,21 +46,7 @@ services: - XDG_CONFIG_HOME=/config - RCLONE_CACHE_DIR=/cache ports: - - "5572:5572" - expose: - - "5572" - restart: unless-stopped - - gui: - build: - context: . - dockerfile: Dockerfile.webgui - image: rclone-webgui-frontend:local - container_name: rclone-webgui - depends_on: - - rclone - ports: - - "5580:80" + - "5580:8080" restart: unless-stopped volumes: diff --git a/docker/nginx.conf b/docker/nginx.conf deleted file mode 100644 index d1cd999..0000000 --- a/docker/nginx.conf +++ /dev/null @@ -1,66 +0,0 @@ -# nginx config for the webgui frontend container. -# -# Two jobs: -# 1. Serve the SPA static bundle (HTML/CSS/JS) with SPA fallback. -# 2. Reverse-proxy RC API calls and remote-file downloads to the -# rclone rcd container on the compose network. -# -# Same-origin from the browser, so the frontend's fetch() calls hit -# this nginx and get forwarded to rclone — no CORS, no basic-auth -# popups, no embedded credentials in URLs. - -server { - listen 80; - server_name _; - - root /usr/share/nginx/html; - index index.html; - - # Uploads can be large; let rclone decide on size limits. - client_max_body_size 0; - - # Light gzip for text assets. - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_types - text/plain - text/css - application/javascript - application/json - image/svg+xml; - - # --- Static assets --- - # Anything that resolves to a real file is served from the bundle. - # Unknown paths fall through to index.html so client-side hash - # routing (#/remotes, #/browse/...) keeps working. - location / { - try_files $uri $uri/ /index.html; - } - - # --- RC API endpoints (POST JSON) --- - # rclone registers endpoints under well-known top-level prefixes. - # Match any of them and forward to rclone. - location ~ ^/(config|operations|sync|job|fs|rc|cache|vfs|subsystem|options|metrics)/ { - proxy_pass http://rclone:5572; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_request_buffering off; - } - - # --- Remote file downloads (GET) --- - # rclone rcd with --rc-serve exposes remotes at /:. - # The colon in the first path segment is the tell — static asset - # paths never have one. - location ~ ^/([^/]+): { - proxy_pass http://rclone:5572; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -}