From 33fa09045beb4b6c43e5034687574c123ffe5e13 Mon Sep 17 00:00:00 2001 From: Peifan Li Date: Fri, 26 Dec 2025 13:55:38 -0500 Subject: [PATCH] chore: Update docker-compose files and configurations --- .../src/services/cloudStorage/cloudScanner.ts | 2 +- docker-compose.host-network.yml | 54 ++++++ docker-compose.yml | 16 ++ documents/en/docker-guide.md | 45 ++++- documents/zh/docker-guide.md | 183 ++++++++++-------- frontend/entrypoint.sh | 36 +++- frontend/nginx.conf | 11 +- 7 files changed, 243 insertions(+), 104 deletions(-) create mode 100644 docker-compose.host-network.yml diff --git a/backend/src/services/cloudStorage/cloudScanner.ts b/backend/src/services/cloudStorage/cloudScanner.ts index a38a9b4..91f2b7d 100644 --- a/backend/src/services/cloudStorage/cloudScanner.ts +++ b/backend/src/services/cloudStorage/cloudScanner.ts @@ -509,7 +509,7 @@ export async function scanCloudFiles( // Clear cache for the new files // Use relative paths (relative to upload root) for cache keys clearSignedUrlCache(relativeVideoPath, "video"); - + // Only clear thumbnail cache if thumbnail was successfully generated if (thumbnailGenerated && relativeThumbnailPath) { // For thumbnail cache, use the directory path diff --git a/docker-compose.host-network.yml b/docker-compose.host-network.yml new file mode 100644 index 0000000..916c2bb --- /dev/null +++ b/docker-compose.host-network.yml @@ -0,0 +1,54 @@ +version: '3.8' + +# Example configuration for systems where bridge network cannot access internet +# (e.g., OpenWrt/iStoreOS on arm64) +# +# Usage: docker compose -f docker-compose.host-network.yml up -d +# +# This configuration uses host network mode for the backend to allow internet access, +# while keeping the frontend on bridge network with proper nginx configuration. + +services: + backend: + image: franklioxygen/mytube:backend-latest + pull_policy: always + container_name: mytube-backend + network_mode: host + volumes: + - /share/CACHEDEV2_DATA/Medias/MyTube/uploads:/app/uploads + - /share/CACHEDEV2_DATA/Medias/MyTube/data:/app/data + environment: + - PORT=5551 + restart: unless-stopped + # Note: In host mode, the container uses the host's network stack directly + # The backend will be accessible at localhost:5551 on the host + + frontend: + image: franklioxygen/mytube:frontend-latest + pull_policy: always + container_name: mytube-frontend + ports: + - "5556:5556" + environment: + - VITE_API_URL=/api + - VITE_BACKEND_URL= + # Configure nginx to use localhost:5551 to reach backend in host mode + - NGINX_BACKEND_URL=http://localhost:5551 + # Alternative: if backend is on a different host, use: + # - NGINX_BACKEND_URL=http://:5551 + # - API_HOST= + # - API_PORT=5551 + depends_on: + - backend + restart: unless-stopped + networks: + - mytube-network + +volumes: + backend-data: + driver: local + +networks: + mytube-network: + driver: bridge + diff --git a/docker-compose.yml b/docker-compose.yml index 79fd590..9b9148d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,10 @@ services: restart: unless-stopped networks: - mytube-network + # For OpenWrt/iStoreOS systems where bridge network cannot access internet, + # uncomment the following lines to use host network mode: + # network_mode: host + # Then set NGINX_BACKEND_URL=http://localhost:5551 for frontend service frontend: image: franklioxygen/mytube:frontend-latest @@ -29,11 +33,16 @@ services: # you can override these values using a .env file with: # - API_HOST=your-ip-or-hostname # - API_PORT=5551 + # For host network mode (when backend uses network_mode: host), set: + # - NGINX_BACKEND_URL=http://localhost:5551 depends_on: - backend restart: unless-stopped networks: - mytube-network + # If backend uses host network mode, uncomment the following: + # network_mode: host + # And remove the ports mapping above volumes: backend-data: @@ -42,3 +51,10 @@ volumes: networks: mytube-network: driver: bridge + # DNS configuration to help with network connectivity issues on OpenWrt/iStoreOS + # If you still have issues accessing internet from containers, try: + # 1. Add your router's DNS servers: dns: [8.8.8.8, 8.8.4.4] + # 2. Or use host network mode for backend (see comments above) + driver_opts: + com.docker.network.bridge.enable_ip_masquerade: "true" + com.docker.network.bridge.enable_icc: "true" diff --git a/documents/en/docker-guide.md b/documents/en/docker-guide.md index 0e867c5..94040f0 100644 --- a/documents/en/docker-guide.md +++ b/documents/en/docker-guide.md @@ -22,9 +22,9 @@ cd mytube-deploy Create a file named `docker-compose.yml` inside your folder and paste the following content. -**Note:** This version uses standard relative paths (`./data`, `./uploads`) instead of the QNAP-specific paths found in the original repository. +**Note:** This version uses standard relative paths (`./data`, `./uploads`) instead of the QNAP-specific paths found in the original repository. -``` +```yaml version: '3.8' services: @@ -35,6 +35,8 @@ services: restart: unless-stopped ports: - "5551:5551" + networks: + - mytube-network environment: - PORT=5551 # Optional: Set a custom upload directory inside container if needed @@ -42,8 +44,10 @@ services: volumes: - ./uploads:/app/uploads - ./data:/app/data - networks: - - mytube-network + # For OpenWrt/iStoreOS systems where bridge network cannot access internet, + # uncomment the following lines to use host network mode: + # network_mode: host + # Then set NGINX_BACKEND_URL=http://localhost:5551 for frontend service frontend: image: franklioxygen/mytube:frontend-latest @@ -52,19 +56,31 @@ services: restart: unless-stopped ports: - "5556:5556" + depends_on: + - backend + networks: + - mytube-network environment: # Internal Docker networking URLs (Browser -> Frontend -> Backend) # In most setups, these defaults work fine. - VITE_API_URL=/api - VITE_BACKEND_URL= - depends_on: - - backend - networks: - - mytube-network + # For host network mode (when backend uses network_mode: host), set: + # - NGINX_BACKEND_URL=http://localhost:5551 + # If backend uses host network mode, uncomment the following: + # network_mode: host + # And remove the ports mapping above networks: mytube-network: driver: bridge + # DNS configuration to help with network connectivity issues on OpenWrt/iStoreOS + # If you still have issues accessing internet from containers, try: + # 1. Add your router's DNS servers: dns: [8.8.8.8, 8.8.4.4] + # 2. Or use host network mode for backend (see comments above) + driver_opts: + com.docker.network.bridge.enable_ip_masquerade: "true" + com.docker.network.bridge.enable_icc: "true" ``` ### 3. Start the Application @@ -107,6 +123,7 @@ You can customize the deployment by adding a `.env` file or modifying the `en |`VITE_API_URL`|Frontend|API endpoint path|`/api`| |`API_HOST`|Frontend|**Advanced:** Force a specific backend IP|_(Auto-detected)_| |`API_PORT`|Frontend|**Advanced:** Force a specific backend Port|`5551`| +|`NGINX_BACKEND_URL`|Frontend|**Advanced:** Override Nginx backend upstream URL|`http://backend:5551`| ## 🛠️ Advanced Networking (Remote/NAS Deployment) @@ -190,4 +207,14 @@ If you prefer to build the images yourself (e.g., to modify code), follow these ``` docker rm -f mytube-backend mytube-frontend docker-compose up -d - ``` \ No newline at end of file + ``` + +### 4. Connection Refused / No Internet (OpenWrt/iStoreOS) + +- **Cause:** Docker bridge network compatibility issues on some router OS versions. +- **Fix:** We added `driver_opts` to the default network configuration to address this. If issues persist: + 1. Edit `docker-compose.yml`. + 2. Uncomment `network_mode: host` for both `backend` and `frontend`. + 3. Remove (or comment out) the `ports` and `networks` sections for both services. + 4. Set `NGINX_BACKEND_URL=http://localhost:5551` in the `frontend` environment variables. + 5. Restart containers: `docker-compose up -d` \ No newline at end of file diff --git a/documents/zh/docker-guide.md b/documents/zh/docker-guide.md index f48451b..aa988ef 100644 --- a/documents/zh/docker-guide.md +++ b/documents/zh/docker-guide.md @@ -1,9 +1,8 @@ # MyTube Docker 部署指南 -本指南提供了使用 Docker 和 Docker Compose 部署 [MyTube](https://github.com/franklioxygen/MyTube "null") 的详细步骤。此设置适用于标准环境(Linux, macOS, Windows),并针对通用用途修改了原本专用于 QNAP 的配置。 +本指南提供了使用 Docker 和 Docker Compose 部署  [MyTube](https://github.com/franklioxygen/MyTube "null")  的详细步骤。此设置适用于标准环境(Linux, macOS, Windows),并针对通用用途修改了原本专用于 QNAP 的配置。 -> [!NOTE] -> **多架构支持:** 官方镜像支持 **amd64** (x86_64) 和 **arm64** (Apple Silicon, Raspberry Pi 等) 架构。Docker 会自动为您的系统拉取极其正确的镜像。 +> [!NOTE] > **多架构支持:** 官方镜像支持 **amd64** (x86_64) 和 **arm64** (Apple Silicon, Raspberry Pi 等) 架构。Docker 会自动为您的系统拉取正确的镜像。 ## 🚀 快速开始 (使用预构建镜像) @@ -18,14 +17,14 @@ mkdir mytube-deploy cd mytube-deploy ``` -### 2. 创建 `docker-compose.yml` 文件 +### 2. 创建  `docker-compose.yml`  文件 -在文件夹中创建一个名为 `docker-compose.yml` 的文件,并粘贴以下内容。 +在文件夹中创建一个名为  `docker-compose.yml`  的文件,并粘贴以下内容。 -**注意:** 此版本使用标准的相对路径(`./data`, `./uploads`),而不是原始仓库中特定于 QNAP 的路径。 +**注意:** 此版本使用标准的相对路径(`./data`, `./uploads`),而不是原始仓库中特定于 QNAP 的路径。 -``` -version: '3.8' +```yaml +version: "3.8" services: backend: @@ -35,6 +34,8 @@ services: restart: unless-stopped ports: - "5551:5551" + networks: + - mytube-network environment: - PORT=5551 # 可选:如果需要,在容器内设置自定义上传目录 @@ -42,8 +43,10 @@ services: volumes: - ./uploads:/app/uploads - ./data:/app/data - networks: - - mytube-network + # 对于 bridge 网络无法访问互联网的 OpenWrt/iStoreOS 系统, + # 请取消注释以下行以使用主机网络模式: + # network_mode: host + # 然后为前端服务设置 NGINX_BACKEND_URL=http://localhost:5551 frontend: image: franklioxygen/mytube:frontend-latest @@ -52,19 +55,31 @@ services: restart: unless-stopped ports: - "5556:5556" + depends_on: + - backend + networks: + - mytube-network environment: # 内部 Docker 网络 URL(浏览器 -> 前端 -> 后端) # 在大多数设置中,这些默认值都可以正常工作。 - VITE_API_URL=/api - VITE_BACKEND_URL= - depends_on: - - backend - networks: - - mytube-network + # 对于主机网络模式(当后端使用 network_mode: host 时),设置: + # - NGINX_BACKEND_URL=http://localhost:5551 + # 如果后端使用主机网络模式,取消注释以下行: + # network_mode: host + # 并删除上面的 ports 映射 networks: mytube-network: driver: bridge + # DNS 配置以帮助解决 OpenWrt/iStoreOS 上的网络连接问题 + # 如果您仍然遇到容器无法访问互联网的问题,请尝试: + # 1. 添加路由器的 DNS 服务器:dns: [8.8.8.8, 8.8.4.4] + # 2. 或者为后端使用主机网络模式(见上文注释) + driver_opts: + com.docker.network.bridge.enable_ip_masquerade: "true" + com.docker.network.bridge.enable_icc: "true" ``` ### 3. 启动应用 @@ -80,33 +95,30 @@ docker-compose up -d 容器运行后,请在浏览器中访问应用程序: - **前端 UI:** `http://localhost:5556` - - **后端 API:** `http://localhost:5551` - ## ⚙️ 配置与数据持久化 ### 卷 (数据存储) -上面的 `docker-compose.yml` 在当前目录中创建了两个文件夹来持久保存数据: +上面的  `docker-compose.yml`  在当前目录中创建了两个文件夹来持久保存数据: - `./uploads`: 存储下载的视频和缩略图。 - - `./data`: 存储 SQLite 数据库和日志。 - -**重要提示:** 如果您移动 `docker-compose.yml` 文件,必须同时移动这些文件夹以保留您的数据。 +**重要提示:**  如果您移动  `docker-compose.yml`  文件,必须同时移动这些文件夹以保留您的数据。 ### 环境变量 -您可以通过添加 `.env` 文件或修改 `docker-compose.yml` 中的 `environment` 部分来自定义部署。 +您可以通过添加  `.env`  文件或修改  `docker-compose.yml`  中的  `environment`  部分来自定义部署。 -|变量|服务|描述|默认值| -|---|---|---|---| -|`PORT`|Backend|后端内部监听端口|`5551`| -|`VITE_API_URL`|Frontend|API 端点路径|`/api`| -|`API_HOST`|Frontend|**高级:** 强制指定后端 IP|_(自动检测)_| -|`API_PORT`|Frontend|**高级:** 强制指定后端端口|`5551`| +| 变量 | 服务 | 描述 | 默认值 | +| ------------------- | -------- | ----------------------------------- | --------------------- | +| `PORT` | Backend | 后端内部监听端口 | `5551` | +| `VITE_API_URL` | Frontend | API 端点路径 | `/api` | +| `API_HOST` | Frontend | **高级:**  强制指定后端 IP | _(自动检测)_ | +| `API_PORT` | Frontend | **高级:**  强制指定后端端口 | `5551` | +| `NGINX_BACKEND_URL` | Frontend | **高级:**  覆盖 Nginx 后端上游 URL | `http://backend:5551` | ## 🛠️ 高级网络 (远程/NAS 部署) @@ -114,80 +126,81 @@ docker-compose up -d 但是,如果您遇到连接问题(前端无法连接到后端),您可能需要明确告诉前端 API 的位置。 -1. 在与 `docker-compose.yml` 相同的目录中创建一个 `.env` 文件: - - ``` - API_HOST=192.168.1.100 # 替换为您的服务器局域网/公网 IP - API_PORT=5551 - ``` - +1. 在与  `docker-compose.yml`  相同的目录中创建一个  `.env`  文件: + + ``` + API_HOST=192.168.1.100 # 替换为您的服务器局域网/公网 IP + API_PORT=5551 + ``` + 2. 重启容器: - - ``` - docker-compose down - docker-compose up -d - ``` - + + ``` + docker-compose down + docker-compose up -d + ``` ## 🏗️ 从源码构建 (可选) 如果您更喜欢自己构建镜像(例如,为了修改代码),请按照以下步骤操作: 1. **克隆仓库:** - - ``` - git clone https://github.com/franklioxygen/MyTube.git - cd MyTube - ``` - -2. **构建并运行:** 您可以使用相同的 `docker-compose.yml` 结构,但将 `image: ...` 替换为 `build: ...`。 - - 修改 `docker-compose.yml`: - - ```yaml - services: - backend: - build: ./backend - # ... 其他设置 - frontend: - build: ./frontend - # ... 其他设置 - ``` - + + ``` + git clone https://github.com/franklioxygen/MyTube.git + cd MyTube + ``` + +2. **构建并运行:**  您可以使用相同的  `docker-compose.yml`  结构,但将  `image: ...`  替换为  `build: ...`。 + + 修改  `docker-compose.yml`: + + ```yaml + services: + backend: + build: ./backend + # ... 其他设置 + frontend: + build: ./frontend + # ... 其他设置 + ``` + 3. **启动:** - - ``` - docker-compose up -d --build - ``` - + + ``` + docker-compose up -d --build + ``` ## ❓ 故障排除 (Troubleshooting) ### 1. "Network Error" 或 API 连接失败 -- **原因:** 浏览器无法访问后端 API。 - -- **解决方法:** 确保端口 `5551` 在您的防火墙上已打开。如果在远程服务器上运行,请尝试按照“高级网络”部分的说明在 `.env` 文件中设置 `API_HOST`。 - +- **原因:**  浏览器无法访问后端 API。 +- **解决方法:**  确保端口  `5551`  在您的防火墙上已打开。如果在远程服务器上运行,请尝试按照“高级网络”部分的说明在  `.env`  文件中设置  `API_HOST`。 -### 2. `./uploads` 权限被拒绝 (Permission Denied) +### 2. `./uploads`  权限被拒绝 (Permission Denied) - **原因:** Docker 容器用户没有主机目录的写入权限。 - -- **解决方法:** 调整主机上的权限: - - ``` - chmod -R 777 ./uploads ./data - ``` - +- **解决方法:**  调整主机上的权限: + ``` + chmod -R 777 ./uploads ./data + ``` ### 3. 容器名称冲突 (Container Name Conflicts) -- **原因:** 您有另一个 MyTube 实例正在运行,或者旧容器未被删除。 - -- **解决方法:** 在启动前删除旧容器: - - ``` - docker rm -f mytube-backend mytube-frontend - docker-compose up -d - ``` \ No newline at end of file +- **原因:**  您有另一个 MyTube 实例正在运行,或者旧容器未被删除。 +- **解决方法:**  在启动前删除旧容器: + ``` + docker rm -f mytube-backend mytube-frontend + docker-compose up -d + ``` + +### 4. 连接被拒绝 / 无法连接互联网 (OpenWrt/iStoreOS) + +- **原因:** 某些路由器系统上的 Docker bridge 网络兼容性问题。 +- **解决方法:** 我们已在默认网络配置中添加了 `driver_opts` 以解决此问题。如果问题仍然存在: + 1. 编辑 `docker-compose.yml`。 + 2. 为 `backend` 和 `frontend` 取消注释 `network_mode: host`。 + 3. 删除(或注释掉)两个服务的 `ports` 和 `networks` 部分。 + 4. 在 `frontend` 环境变量中设置 `NGINX_BACKEND_URL=http://localhost:5551`。 + 5. 重启容器:`docker-compose up -d` diff --git a/frontend/entrypoint.sh b/frontend/entrypoint.sh index 616d62c..5bb3a85 100644 --- a/frontend/entrypoint.sh +++ b/frontend/entrypoint.sh @@ -5,21 +5,47 @@ set -e DEFAULT_API_URL="http://localhost:5551/api" DEFAULT_BACKEND_URL="http://localhost:5551" -# Runtime values from docker-compose environment variables +# Determine backend URL for nginx configuration +# Priority: NGINX_BACKEND_URL > API_HOST > VITE_BACKEND_URL > default (backend:5551) +if [ ! -z "$NGINX_BACKEND_URL" ]; then + # Direct override for nginx backend URL (useful for host network mode) + NGINX_BACKEND="${NGINX_BACKEND_URL}" + echo "Using NGINX_BACKEND_URL: $NGINX_BACKEND" +elif [ ! -z "$API_HOST" ]; then + # Custom host configuration + API_PORT="${API_PORT:-5551}" + NGINX_BACKEND="http://${API_HOST}:${API_PORT}" + echo "Using custom host configuration: $API_HOST:$API_PORT" +elif [ ! -z "$VITE_BACKEND_URL" ]; then + # Use VITE_BACKEND_URL if provided + NGINX_BACKEND="${VITE_BACKEND_URL}" + echo "Using VITE_BACKEND_URL: $NGINX_BACKEND" +else + # Default: use service name for bridge network + NGINX_BACKEND="http://backend:5551" + echo "Using default backend service name: backend:5551" +fi + +# Runtime values from docker-compose environment variables for JavaScript DOCKER_API_URL="${VITE_API_URL-http://backend:5551/api}" DOCKER_BACKEND_URL="${VITE_BACKEND_URL-http://backend:5551}" -# If API_HOST is provided, override with custom host configuration +# If API_HOST is provided, override JavaScript URLs if [ ! -z "$API_HOST" ]; then API_PORT="${API_PORT:-5551}" DOCKER_API_URL="http://${API_HOST}:${API_PORT}/api" DOCKER_BACKEND_URL="http://${API_HOST}:${API_PORT}" - echo "Using custom host configuration: $API_HOST:$API_PORT" fi echo "Configuring frontend with the following settings:" -echo "API URL: $DOCKER_API_URL" -echo "Backend URL: $DOCKER_BACKEND_URL" +echo "API URL (JS): $DOCKER_API_URL" +echo "Backend URL (JS): $DOCKER_BACKEND_URL" +echo "Backend URL (Nginx): $NGINX_BACKEND" + +# Replace backend URL placeholder in nginx.conf +ESCAPED_NGINX_BACKEND=$(echo $NGINX_BACKEND | sed 's/\//\\\//g') +sed -i "s/__BACKEND_URL__/$ESCAPED_NGINX_BACKEND/g" /etc/nginx/conf.d/default.conf +echo "Updated nginx.conf with backend URL: $NGINX_BACKEND" # Replace environment variables in the JavaScript files # We need to escape special characters for sed diff --git a/frontend/nginx.conf b/frontend/nginx.conf index cb8b933..0f1503c 100644 --- a/frontend/nginx.conf +++ b/frontend/nginx.conf @@ -10,8 +10,11 @@ server { try_files $uri $uri/ /index.html; } + # Backend URL placeholder - will be replaced by entrypoint.sh at runtime + # Default: http://backend:5551 (for bridge network) + # Can be overridden via NGINX_BACKEND_URL environment variable location /api { - proxy_pass http://backend:5551/api; + proxy_pass __BACKEND_URL__/api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -23,7 +26,7 @@ server { } location ^~ /videos { - proxy_pass http://backend:5551/videos; + proxy_pass __BACKEND_URL__/videos; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -31,7 +34,7 @@ server { } location ^~ /images { - proxy_pass http://backend:5551/images; + proxy_pass __BACKEND_URL__/images; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -39,7 +42,7 @@ server { } location ^~ /subtitles { - proxy_pass http://backend:5551/subtitles; + proxy_pass __BACKEND_URL__/subtitles; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;