mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 16:07:01 +08:00
Checkpoint before follow-up message
Co-authored-by: jxxghp <jxxghp@live.cn>
This commit is contained in:
+86
-1
@@ -1,3 +1,88 @@
|
|||||||
# Ignore git
|
# Git
|
||||||
.github
|
.github
|
||||||
.git
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
docs/
|
||||||
|
README.md
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.pylintrc
|
||||||
|
*.pyc
|
||||||
|
__pycache__/
|
||||||
|
*.pyo
|
||||||
|
*.pyd
|
||||||
|
.Python
|
||||||
|
*.so
|
||||||
|
.pytest_cache/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.hypothesis/
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
venv/
|
||||||
|
env/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
|
||||||
|
# Database
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
|
||||||
|
# Config files that should be mounted
|
||||||
|
config/
|
||||||
|
database/
|
||||||
|
|
||||||
|
# Test files
|
||||||
|
tests/
|
||||||
|
test_*
|
||||||
|
*_test.py
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.egg-info/
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Other
|
||||||
|
app.ico
|
||||||
|
frozen.spec
|
||||||
@@ -0,0 +1,221 @@
|
|||||||
|
# Docker 构建和启动逻辑优化
|
||||||
|
|
||||||
|
## 优化概述
|
||||||
|
|
||||||
|
本次优化主要解决了以下问题:
|
||||||
|
|
||||||
|
1. **统一使用虚拟pip环境**:避免pip包在多个地方存在
|
||||||
|
2. **优化依赖管理**:使用pip-tools进行依赖锁定
|
||||||
|
3. **减少重复安装**:在构建时安装依赖,运行时只更新变化的部分
|
||||||
|
4. **提升构建速度**:优化.dockerignore文件
|
||||||
|
5. **简化部署**:提供docker-compose配置
|
||||||
|
|
||||||
|
## 主要改进
|
||||||
|
|
||||||
|
### 1. 虚拟环境管理
|
||||||
|
|
||||||
|
- **虚拟环境路径**:`/opt/venv`
|
||||||
|
- **环境变量**:`VENV_PATH=/opt/venv`
|
||||||
|
- **PATH设置**:自动将虚拟环境bin目录添加到PATH
|
||||||
|
|
||||||
|
### 2. 依赖管理优化
|
||||||
|
|
||||||
|
#### 构建阶段
|
||||||
|
```dockerfile
|
||||||
|
# 创建虚拟环境
|
||||||
|
RUN python3 -m venv ${VENV_PATH} \
|
||||||
|
&& ${VENV_PATH}/bin/pip install --upgrade pip \
|
||||||
|
&& ${VENV_PATH}/bin/pip install Cython pip-tools
|
||||||
|
|
||||||
|
# 安装依赖到虚拟环境
|
||||||
|
RUN ${VENV_PATH}/bin/pip-compile requirements.in \
|
||||||
|
&& ${VENV_PATH}/bin/pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 运行时更新
|
||||||
|
- 只在依赖文件发生变化时才重新安装
|
||||||
|
- 自动备份和恢复机制
|
||||||
|
- 使用虚拟环境中的pip进行安装
|
||||||
|
|
||||||
|
### 3. 文件结构优化
|
||||||
|
|
||||||
|
#### .dockerignore 优化
|
||||||
|
排除不必要的文件,减少构建上下文大小:
|
||||||
|
- 开发文件(.pyc, __pycache__, .pytest_cache等)
|
||||||
|
- 文档文件
|
||||||
|
- IDE配置文件
|
||||||
|
- 临时文件
|
||||||
|
- 测试文件
|
||||||
|
|
||||||
|
#### requirements.txt 优化
|
||||||
|
- 使用具体版本号锁定依赖
|
||||||
|
- 包含平台特定依赖
|
||||||
|
- 自动生成注释说明
|
||||||
|
|
||||||
|
### 4. 启动脚本优化
|
||||||
|
|
||||||
|
#### entrypoint.sh 改进
|
||||||
|
- 设置虚拟环境PATH
|
||||||
|
- 使用虚拟环境中的Python启动应用
|
||||||
|
- 正确设置虚拟环境权限
|
||||||
|
|
||||||
|
#### update.sh 改进
|
||||||
|
- 使用虚拟环境中的pip
|
||||||
|
- 智能依赖更新:只在变化时更新
|
||||||
|
- 备份和恢复机制
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 1. 简单部署(推荐)
|
||||||
|
|
||||||
|
使用SQLite数据库,适合个人使用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建配置目录
|
||||||
|
mkdir -p config
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
docker-compose -f docker-compose.simple.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 完整部署
|
||||||
|
|
||||||
|
使用PostgreSQL和Redis,适合生产环境:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建配置目录
|
||||||
|
mkdir -p config
|
||||||
|
|
||||||
|
# 启动所有服务
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 自定义配置
|
||||||
|
|
||||||
|
创建 `config/app.env` 文件:
|
||||||
|
|
||||||
|
```env
|
||||||
|
# 代理设置
|
||||||
|
PIP_PROXY='https://pypi.tuna.tsinghua.edu.cn/simple'
|
||||||
|
GITHUB_PROXY='https://ghproxy.com/'
|
||||||
|
|
||||||
|
# 数据库设置
|
||||||
|
DB_TYPE='postgresql'
|
||||||
|
DB_POSTGRESQL_HOST='postgres'
|
||||||
|
DB_POSTGRESQL_DATABASE='moviepilot'
|
||||||
|
DB_POSTGRESQL_USERNAME='moviepilot'
|
||||||
|
DB_POSTGRESQL_PASSWORD='moviepilot'
|
||||||
|
|
||||||
|
# SSL设置
|
||||||
|
ENABLE_SSL='true'
|
||||||
|
SSL_DOMAIN='your.domain.com'
|
||||||
|
```
|
||||||
|
|
||||||
|
## 环境变量说明
|
||||||
|
|
||||||
|
### 基础配置
|
||||||
|
- `PUID`: 用户ID(默认:1000)
|
||||||
|
- `PGID`: 组ID(默认:1000)
|
||||||
|
- `UMASK`: 文件权限掩码(默认:022)
|
||||||
|
- `CONFIG_DIR`: 配置目录(默认:/config)
|
||||||
|
|
||||||
|
### 代理设置
|
||||||
|
- `PIP_PROXY`: pip代理地址
|
||||||
|
- `GITHUB_PROXY`: GitHub代理地址
|
||||||
|
- `PROXY_HOST`: 全局代理地址
|
||||||
|
- `GITHUB_TOKEN`: GitHub访问令牌
|
||||||
|
|
||||||
|
### 数据库设置
|
||||||
|
- `DB_TYPE`: 数据库类型(sqlite/postgresql)
|
||||||
|
- `DB_POSTGRESQL_HOST`: PostgreSQL主机
|
||||||
|
- `DB_POSTGRESQL_PORT`: PostgreSQL端口
|
||||||
|
- `DB_POSTGRESQL_DATABASE`: 数据库名
|
||||||
|
- `DB_POSTGRESQL_USERNAME`: 用户名
|
||||||
|
- `DB_POSTGRESQL_PASSWORD`: 密码
|
||||||
|
|
||||||
|
### SSL设置
|
||||||
|
- `ENABLE_SSL`: 是否启用SSL
|
||||||
|
- `SSL_DOMAIN`: SSL域名
|
||||||
|
|
||||||
|
### 更新设置
|
||||||
|
- `MOVIEPILOT_AUTO_UPDATE`: 自动更新模式(false/release/dev)
|
||||||
|
|
||||||
|
## 性能优化
|
||||||
|
|
||||||
|
### 构建优化
|
||||||
|
1. **多阶段构建**:减少最终镜像大小
|
||||||
|
2. **依赖缓存**:利用Docker层缓存
|
||||||
|
3. **最小化上下文**:优化.dockerignore
|
||||||
|
|
||||||
|
### 运行时优化
|
||||||
|
1. **虚拟环境**:隔离依赖,避免冲突
|
||||||
|
2. **智能更新**:只在必要时更新依赖
|
||||||
|
3. **健康检查**:确保服务正常运行
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
1. **权限问题**
|
||||||
|
```bash
|
||||||
|
# 修改目录权限
|
||||||
|
sudo chown -R 1000:1000 config/
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **依赖安装失败**
|
||||||
|
```bash
|
||||||
|
# 检查网络连接
|
||||||
|
docker exec moviepilot curl -I https://pypi.org
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker logs moviepilot
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **虚拟环境问题**
|
||||||
|
```bash
|
||||||
|
# 进入容器检查虚拟环境
|
||||||
|
docker exec -it moviepilot bash
|
||||||
|
ls -la /opt/venv/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 日志查看
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看应用日志
|
||||||
|
docker logs moviepilot
|
||||||
|
|
||||||
|
# 实时查看日志
|
||||||
|
docker logs -f moviepilot
|
||||||
|
|
||||||
|
# 查看特定时间段的日志
|
||||||
|
docker logs --since="2024-01-01T00:00:00" moviepilot
|
||||||
|
```
|
||||||
|
|
||||||
|
## 更新和维护
|
||||||
|
|
||||||
|
### 更新依赖
|
||||||
|
```bash
|
||||||
|
# 重新构建镜像
|
||||||
|
docker-compose build --no-cache
|
||||||
|
|
||||||
|
# 重启服务
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### 备份配置
|
||||||
|
```bash
|
||||||
|
# 备份配置目录
|
||||||
|
tar -czf moviepilot_config_backup.tar.gz config/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 清理资源
|
||||||
|
```bash
|
||||||
|
# 清理未使用的镜像
|
||||||
|
docker image prune -f
|
||||||
|
|
||||||
|
# 清理未使用的卷
|
||||||
|
docker volume prune -f
|
||||||
|
|
||||||
|
# 清理未使用的网络
|
||||||
|
docker network prune -f
|
||||||
|
```
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# MoviePilot Docker 构建脚本
|
||||||
|
# 使用方法: ./build.sh [选项]
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# 默认值
|
||||||
|
IMAGE_NAME="moviepilot"
|
||||||
|
TAG="latest"
|
||||||
|
DOCKERFILE="docker/Dockerfile"
|
||||||
|
BUILD_CONTEXT="."
|
||||||
|
NO_CACHE=false
|
||||||
|
PUSH=false
|
||||||
|
PLATFORM=""
|
||||||
|
|
||||||
|
# 帮助信息
|
||||||
|
show_help() {
|
||||||
|
echo "MoviePilot Docker 构建脚本"
|
||||||
|
echo ""
|
||||||
|
echo "使用方法: $0 [选项]"
|
||||||
|
echo ""
|
||||||
|
echo "选项:"
|
||||||
|
echo " -n, --name NAME 镜像名称 (默认: moviepilot)"
|
||||||
|
echo " -t, --tag TAG 镜像标签 (默认: latest)"
|
||||||
|
echo " -f, --file FILE Dockerfile路径 (默认: docker/Dockerfile)"
|
||||||
|
echo " -c, --context DIR 构建上下文目录 (默认: .)"
|
||||||
|
echo " --no-cache 不使用缓存构建"
|
||||||
|
echo " --push 构建后推送到镜像仓库"
|
||||||
|
echo " --platform PLATFORM 指定目标平台 (例如: linux/amd64,linux/arm64)"
|
||||||
|
echo " -h, --help 显示此帮助信息"
|
||||||
|
echo ""
|
||||||
|
echo "示例:"
|
||||||
|
echo " $0 # 使用默认设置构建"
|
||||||
|
echo " $0 -n myapp -t v1.0 # 指定镜像名称和标签"
|
||||||
|
echo " $0 --no-cache --platform linux/amd64 # 不使用缓存,指定平台"
|
||||||
|
echo " $0 --push # 构建并推送镜像"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 解析命令行参数
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-n|--name)
|
||||||
|
IMAGE_NAME="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-t|--tag)
|
||||||
|
TAG="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-f|--file)
|
||||||
|
DOCKERFILE="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-c|--context)
|
||||||
|
BUILD_CONTEXT="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--no-cache)
|
||||||
|
NO_CACHE=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--push)
|
||||||
|
PUSH=true
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--platform)
|
||||||
|
PLATFORM="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}错误: 未知选项 $1${NC}"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# 检查Docker是否安装
|
||||||
|
if ! command -v docker &> /dev/null; then
|
||||||
|
echo -e "${RED}错误: Docker 未安装${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查Dockerfile是否存在
|
||||||
|
if [[ ! -f "$DOCKERFILE" ]]; then
|
||||||
|
echo -e "${RED}错误: Dockerfile 不存在: $DOCKERFILE${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查构建上下文是否存在
|
||||||
|
if [[ ! -d "$BUILD_CONTEXT" ]]; then
|
||||||
|
echo -e "${RED}错误: 构建上下文目录不存在: $BUILD_CONTEXT${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 构建命令
|
||||||
|
BUILD_CMD="docker build"
|
||||||
|
|
||||||
|
# 添加平台参数
|
||||||
|
if [[ -n "$PLATFORM" ]]; then
|
||||||
|
BUILD_CMD="$BUILD_CMD --platform $PLATFORM"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 添加缓存参数
|
||||||
|
if [[ "$NO_CACHE" == true ]]; then
|
||||||
|
BUILD_CMD="$BUILD_CMD --no-cache"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 添加文件参数
|
||||||
|
BUILD_CMD="$BUILD_CMD -f $DOCKERFILE"
|
||||||
|
|
||||||
|
# 添加标签参数
|
||||||
|
BUILD_CMD="$BUILD_CMD -t $IMAGE_NAME:$TAG"
|
||||||
|
|
||||||
|
# 添加构建上下文
|
||||||
|
BUILD_CMD="$BUILD_CMD $BUILD_CONTEXT"
|
||||||
|
|
||||||
|
# 显示构建信息
|
||||||
|
echo -e "${GREEN}开始构建 MoviePilot Docker 镜像${NC}"
|
||||||
|
echo "镜像名称: $IMAGE_NAME:$TAG"
|
||||||
|
echo "Dockerfile: $DOCKERFILE"
|
||||||
|
echo "构建上下文: $BUILD_CONTEXT"
|
||||||
|
if [[ -n "$PLATFORM" ]]; then
|
||||||
|
echo "目标平台: $PLATFORM"
|
||||||
|
fi
|
||||||
|
if [[ "$NO_CACHE" == true ]]; then
|
||||||
|
echo "缓存: 禁用"
|
||||||
|
else
|
||||||
|
echo "缓存: 启用"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 执行构建
|
||||||
|
echo -e "${YELLOW}执行构建命令: $BUILD_CMD${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if eval $BUILD_CMD; then
|
||||||
|
echo -e "${GREEN}构建成功!${NC}"
|
||||||
|
|
||||||
|
# 显示镜像信息
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}镜像信息:${NC}"
|
||||||
|
docker images "$IMAGE_NAME:$TAG"
|
||||||
|
|
||||||
|
# 如果指定了推送,则推送镜像
|
||||||
|
if [[ "$PUSH" == true ]]; then
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}推送镜像到仓库...${NC}"
|
||||||
|
if docker push "$IMAGE_NAME:$TAG"; then
|
||||||
|
echo -e "${GREEN}推送成功!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}推送失败!${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}构建完成!${NC}"
|
||||||
|
echo "运行命令: docker run -d -p 3000:3000 -v ./config:/config $IMAGE_NAME:$TAG"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo -e "${RED}构建失败!${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
moviepilot:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
container_name: moviepilot
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- ./config:/config
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- UMASK=022
|
||||||
|
- CONFIG_DIR=/config
|
||||||
|
- MOVIEPILOT_AUTO_UPDATE=release
|
||||||
|
# 可选:代理设置
|
||||||
|
# - PIP_PROXY=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
# - GITHUB_PROXY=https://ghproxy.com/
|
||||||
|
# - PROXY_HOST=http://proxy:7890
|
||||||
|
# - GITHUB_TOKEN=your_github_token
|
||||||
|
# 可选:SSL设置
|
||||||
|
# - ENABLE_SSL=true
|
||||||
|
# - SSL_DOMAIN=your.domain.com
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/system/version"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
moviepilot:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
container_name: moviepilot
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
volumes:
|
||||||
|
- ./config:/config
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
environment:
|
||||||
|
- PUID=1000
|
||||||
|
- PGID=1000
|
||||||
|
- UMASK=022
|
||||||
|
- CONFIG_DIR=/config
|
||||||
|
- MOVIEPILOT_AUTO_UPDATE=release
|
||||||
|
# 可选:代理设置
|
||||||
|
# - PIP_PROXY=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
# - GITHUB_PROXY=https://ghproxy.com/
|
||||||
|
# - PROXY_HOST=http://proxy:7890
|
||||||
|
# - GITHUB_TOKEN=your_github_token
|
||||||
|
# 可选:数据库设置
|
||||||
|
# - DB_TYPE=postgresql
|
||||||
|
# - DB_POSTGRESQL_HOST=postgres
|
||||||
|
# - DB_POSTGRESQL_PORT=5432
|
||||||
|
# - DB_POSTGRESQL_DATABASE=moviepilot
|
||||||
|
# - DB_POSTGRESQL_USERNAME=moviepilot
|
||||||
|
# - DB_POSTGRESQL_PASSWORD=moviepilot
|
||||||
|
# 可选:SSL设置
|
||||||
|
# - ENABLE_SSL=true
|
||||||
|
# - SSL_DOMAIN=your.domain.com
|
||||||
|
networks:
|
||||||
|
- moviepilot_network
|
||||||
|
depends_on:
|
||||||
|
- postgres
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/system/version"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: moviepilot_postgres
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=moviepilot
|
||||||
|
- POSTGRES_USER=moviepilot
|
||||||
|
- POSTGRES_PASSWORD=moviepilot
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- moviepilot_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U moviepilot -d moviepilot"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: moviepilot_redis
|
||||||
|
restart: unless-stopped
|
||||||
|
command: redis-server --appendonly yes
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
networks:
|
||||||
|
- moviepilot_network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
redis_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
moviepilot_network:
|
||||||
|
driver: bridge
|
||||||
+19
-7
@@ -7,8 +7,11 @@ ENV LANG="C.UTF-8" \
|
|||||||
DISPLAY=:987 \
|
DISPLAY=:987 \
|
||||||
PUID=0 \
|
PUID=0 \
|
||||||
PGID=0 \
|
PGID=0 \
|
||||||
UMASK=000
|
UMASK=000 \
|
||||||
|
VENV_PATH="/opt/venv"
|
||||||
WORKDIR "/app"
|
WORKDIR "/app"
|
||||||
|
|
||||||
|
# 安装系统依赖
|
||||||
RUN apt-get update -y \
|
RUN apt-get update -y \
|
||||||
&& apt-get upgrade -y \
|
&& apt-get upgrade -y \
|
||||||
&& apt-get -y install \
|
&& apt-get -y install \
|
||||||
@@ -28,6 +31,7 @@ RUN apt-get update -y \
|
|||||||
rsync \
|
rsync \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
nano \
|
nano \
|
||||||
|
build-essential \
|
||||||
&& dpkg-reconfigure --frontend noninteractive tzdata \
|
&& dpkg-reconfigure --frontend noninteractive tzdata \
|
||||||
&& \
|
&& \
|
||||||
if [ "$(uname -m)" = "x86_64" ]; \
|
if [ "$(uname -m)" = "x86_64" ]; \
|
||||||
@@ -43,13 +47,16 @@ RUN apt-get update -y \
|
|||||||
/moviepilot/.cache \
|
/moviepilot/.cache \
|
||||||
/var/lib/apt/lists/* \
|
/var/lib/apt/lists/* \
|
||||||
/var/tmp/*
|
/var/tmp/*
|
||||||
|
|
||||||
|
# 创建虚拟环境
|
||||||
|
RUN python3 -m venv ${VENV_PATH} \
|
||||||
|
&& ${VENV_PATH}/bin/pip install --upgrade pip \
|
||||||
|
&& ${VENV_PATH}/bin/pip install Cython pip-tools
|
||||||
|
|
||||||
|
# 复制依赖文件并安装到虚拟环境
|
||||||
COPY ../requirements.in requirements.in
|
COPY ../requirements.in requirements.in
|
||||||
RUN apt-get update -y \
|
RUN ${VENV_PATH}/bin/pip-compile requirements.in \
|
||||||
&& apt-get install -y build-essential \
|
&& ${VENV_PATH}/bin/pip install -r requirements.txt \
|
||||||
&& pip install --upgrade pip \
|
|
||||||
&& pip install Cython pip-tools \
|
|
||||||
&& pip-compile requirements.in \
|
|
||||||
&& pip install -r requirements.txt \
|
|
||||||
&& playwright install-deps chromium \
|
&& playwright install-deps chromium \
|
||||||
&& apt-get remove -y build-essential \
|
&& apt-get remove -y build-essential \
|
||||||
&& apt-get autoremove -y \
|
&& apt-get autoremove -y \
|
||||||
@@ -59,7 +66,11 @@ RUN apt-get update -y \
|
|||||||
/moviepilot/.cache \
|
/moviepilot/.cache \
|
||||||
/var/lib/apt/lists/* \
|
/var/lib/apt/lists/* \
|
||||||
/var/tmp/*
|
/var/tmp/*
|
||||||
|
|
||||||
|
# 复制应用代码
|
||||||
COPY .. .
|
COPY .. .
|
||||||
|
|
||||||
|
# 配置nginx和其他文件
|
||||||
RUN cp -f /app/docker/nginx.common.conf /etc/nginx/common.conf \
|
RUN cp -f /app/docker/nginx.common.conf /etc/nginx/common.conf \
|
||||||
&& cp -f /app/docker/nginx.template.conf /etc/nginx/nginx.template.conf \
|
&& cp -f /app/docker/nginx.template.conf /etc/nginx/nginx.template.conf \
|
||||||
&& cp -f /app/docker/update.sh /usr/local/bin/mp_update.sh \
|
&& cp -f /app/docker/update.sh /usr/local/bin/mp_update.sh \
|
||||||
@@ -84,6 +95,7 @@ RUN cp -f /app/docker/nginx.common.conf /etc/nginx/common.conf \
|
|||||||
&& curl -sL "https://github.com/jxxghp/MoviePilot-Resources/archive/refs/heads/main.zip" | busybox unzip -d /tmp - \
|
&& curl -sL "https://github.com/jxxghp/MoviePilot-Resources/archive/refs/heads/main.zip" | busybox unzip -d /tmp - \
|
||||||
&& mv -f /tmp/MoviePilot-Resources-main/resources.v2/* /app/app/helper/ \
|
&& mv -f /tmp/MoviePilot-Resources-main/resources.v2/* /app/app/helper/ \
|
||||||
&& rm -rf /tmp/*
|
&& rm -rf /tmp/*
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
VOLUME [ "${CONFIG_DIR}" ]
|
VOLUME [ "${CONFIG_DIR}" ]
|
||||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ function WARN() {
|
|||||||
echo -e "${WARN} ${1}"
|
echo -e "${WARN} ${1}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 设置虚拟环境路径
|
||||||
|
VENV_PATH="${VENV_PATH:-/opt/venv}"
|
||||||
|
export PATH="${VENV_PATH}/bin:$PATH"
|
||||||
|
|
||||||
# 校正设置目录
|
# 校正设置目录
|
||||||
CONFIG_DIR="${CONFIG_DIR:-/config}"
|
CONFIG_DIR="${CONFIG_DIR:-/config}"
|
||||||
|
|
||||||
@@ -222,7 +226,8 @@ chown -R moviepilot:moviepilot \
|
|||||||
/public \
|
/public \
|
||||||
"${CONFIG_DIR}" \
|
"${CONFIG_DIR}" \
|
||||||
/var/lib/nginx \
|
/var/lib/nginx \
|
||||||
/var/log/nginx
|
/var/log/nginx \
|
||||||
|
"${VENV_PATH}"
|
||||||
chown moviepilot:moviepilot /etc/hosts /tmp
|
chown moviepilot:moviepilot /etc/hosts /tmp
|
||||||
|
|
||||||
# 下载浏览器内核
|
# 下载浏览器内核
|
||||||
@@ -270,4 +275,4 @@ fi
|
|||||||
|
|
||||||
# 启动后端服务
|
# 启动后端服务
|
||||||
INFO "→ 启动后端服务..."
|
INFO "→ 启动后端服务..."
|
||||||
exec dumb-init gosu moviepilot:moviepilot python3 app/main.py
|
exec dumb-init gosu moviepilot:moviepilot ${VENV_PATH}/bin/python3 app/main.py
|
||||||
|
|||||||
+37
-12
@@ -20,6 +20,10 @@ function WARN() {
|
|||||||
echo -e "${WARN} ${1}"
|
echo -e "${WARN} ${1}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 设置虚拟环境路径
|
||||||
|
VENV_PATH="${VENV_PATH:-/opt/venv}"
|
||||||
|
export PATH="${VENV_PATH}/bin:$PATH"
|
||||||
|
|
||||||
# 下载及解压
|
# 下载及解压
|
||||||
function download_and_unzip() {
|
function download_and_unzip() {
|
||||||
local retries=0
|
local retries=0
|
||||||
@@ -54,16 +58,36 @@ function install_backend_and_download_resources() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
INFO "后端程序下载成功"
|
INFO "后端程序下载成功"
|
||||||
INFO "→ 正在安装依赖..."
|
|
||||||
if ! pip install ${PIP_OPTIONS} --upgrade --root-user-action=ignore pip > /dev/null; then
|
# 检查依赖是否有变化
|
||||||
ERROR "pip 更新失败,请重新拉取镜像"
|
INFO "→ 检查依赖变化..."
|
||||||
return 1
|
if [ -f "${TMP_PATH}/App/requirements.in" ]; then
|
||||||
|
if ! cmp -s /app/requirements.in "${TMP_PATH}/App/requirements.in"; then
|
||||||
|
INFO "检测到依赖变化,正在更新虚拟环境..."
|
||||||
|
# 备份当前requirements.txt
|
||||||
|
cp /app/requirements.txt /tmp/requirements.txt.backup
|
||||||
|
# 复制新的requirements.in
|
||||||
|
cp "${TMP_PATH}/App/requirements.in" /app/requirements.in
|
||||||
|
# 重新编译依赖
|
||||||
|
if ! ${VENV_PATH}/bin/pip-compile /app/requirements.in; then
|
||||||
|
ERROR "依赖编译失败,恢复原依赖"
|
||||||
|
cp /tmp/requirements.txt.backup /app/requirements.txt
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# 安装新依赖
|
||||||
|
if ! ${VENV_PATH}/bin/pip install ${PIP_OPTIONS} --root-user-action=ignore -r /app/requirements.txt; then
|
||||||
|
ERROR "依赖安装失败,恢复原依赖"
|
||||||
|
cp /tmp/requirements.txt.backup /app/requirements.txt
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
INFO "依赖更新成功"
|
||||||
|
else
|
||||||
|
INFO "依赖无变化,跳过依赖更新"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
WARN "未找到requirements.in文件,跳过依赖检查"
|
||||||
fi
|
fi
|
||||||
if ! pip install ${PIP_OPTIONS} --root-user-action=ignore -r ${TMP_PATH}/App/requirements.txt > /dev/null; then
|
|
||||||
ERROR "依赖安装失败,请重新拉取镜像"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
INFO "依赖安装成功"
|
|
||||||
# 如果是"heads/v2.zip",则查找v2开头的最新版本号
|
# 如果是"heads/v2.zip",则查找v2开头的最新版本号
|
||||||
if [[ "${1}" == "heads/v2.zip" ]]; then
|
if [[ "${1}" == "heads/v2.zip" ]]; then
|
||||||
INFO "→ 正在获取前端最新版本号..."
|
INFO "→ 正在获取前端最新版本号..."
|
||||||
@@ -98,6 +122,7 @@ function install_backend_and_download_resources() {
|
|||||||
rm -rf /plugins
|
rm -rf /plugins
|
||||||
mkdir -p /plugins
|
mkdir -p /plugins
|
||||||
cp -a /app/app/plugins/* /plugins/
|
cp -a /app/app/plugins/* /plugins/
|
||||||
|
cp -a /app/app/plugins/* /plugins/
|
||||||
rm -f /plugins/__init__.py
|
rm -f /plugins/__init__.py
|
||||||
# 备份站点资源
|
# 备份站点资源
|
||||||
INFO "→ 正在备份站点资源目录..."
|
INFO "→ 正在备份站点资源目录..."
|
||||||
@@ -134,11 +159,11 @@ function install_backend_and_download_resources() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function test_connectivity_pip() {
|
function test_connectivity_pip() {
|
||||||
pip uninstall -y pip-hello-world > /dev/null 2>&1
|
${VENV_PATH}/bin/pip uninstall -y pip-hello-world > /dev/null 2>&1
|
||||||
case "$1" in
|
case "$1" in
|
||||||
0)
|
0)
|
||||||
if [[ -n "${PIP_PROXY}" ]]; then
|
if [[ -n "${PIP_PROXY}" ]]; then
|
||||||
if pip install -i ${PIP_PROXY} pip-hello-world > /dev/null 2>&1; then
|
if ${VENV_PATH}/bin/pip install -i ${PIP_PROXY} pip-hello-world > /dev/null 2>&1; then
|
||||||
PIP_OPTIONS="-i ${PIP_PROXY}"
|
PIP_OPTIONS="-i ${PIP_PROXY}"
|
||||||
PIP_LOG="镜像代理模式"
|
PIP_LOG="镜像代理模式"
|
||||||
return 0
|
return 0
|
||||||
@@ -148,7 +173,7 @@ function test_connectivity_pip() {
|
|||||||
;;
|
;;
|
||||||
1)
|
1)
|
||||||
if [[ -n "${PROXY_HOST}" ]]; then
|
if [[ -n "${PROXY_HOST}" ]]; then
|
||||||
if pip install --proxy=${PROXY_HOST} pip-hello-world > /dev/null 2>&1; then
|
if ${VENV_PATH}/bin/pip install --proxy=${PROXY_HOST} pip-hello-world > /dev/null 2>&1; then
|
||||||
PIP_OPTIONS="--proxy=${PROXY_HOST}"
|
PIP_OPTIONS="--proxy=${PROXY_HOST}"
|
||||||
PIP_LOG="全局代理模式"
|
PIP_LOG="全局代理模式"
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
+86
-1
@@ -1 +1,86 @@
|
|||||||
-r requirements.in
|
# This file is auto-generated from requirements.in
|
||||||
|
# To update, run: pip-compile requirements.in
|
||||||
|
|
||||||
|
Cython==3.1.2
|
||||||
|
pydantic==1.10.22
|
||||||
|
SQLAlchemy==2.0.41
|
||||||
|
uvicorn==0.34.3
|
||||||
|
fastapi==0.115.14
|
||||||
|
passlib==1.7.4
|
||||||
|
PyJWT==2.10.1
|
||||||
|
python-multipart==0.0.9
|
||||||
|
aiofiles==24.1.0
|
||||||
|
aioshutil==1.5
|
||||||
|
alembic==1.16.2
|
||||||
|
bcrypt==4.0.1
|
||||||
|
regex==2024.11.6
|
||||||
|
cn2an==0.5.19
|
||||||
|
dateparser==1.2.2
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
zhconv==1.4.3
|
||||||
|
anitopy==2.1.1
|
||||||
|
requests[socks]==2.32.4
|
||||||
|
urllib3==2.5.0
|
||||||
|
lxml==6.0.0
|
||||||
|
pyquery==2.0.1
|
||||||
|
ruamel.yaml==0.18.14
|
||||||
|
APScheduler==3.11.0
|
||||||
|
cryptography==45.0.4
|
||||||
|
pytz==2025.2
|
||||||
|
pycryptodome==3.23.0
|
||||||
|
qbittorrent-api==2025.5.0
|
||||||
|
plexapi==4.17.0
|
||||||
|
transmission-rpc==4.3.0
|
||||||
|
Jinja2==3.1.6
|
||||||
|
pyparsing==3.2.3
|
||||||
|
func_timeout==4.3.5
|
||||||
|
bs4==0.0.2
|
||||||
|
beautifulsoup4==4.13.4
|
||||||
|
pillow==11.2.1
|
||||||
|
pillow-avif-plugin==1.5.2
|
||||||
|
pyTelegramBotAPI==4.27.0
|
||||||
|
playwright==1.53.0
|
||||||
|
cf_clearance==0.31.0
|
||||||
|
torrentool==1.2.0
|
||||||
|
slack-bolt==1.23.0
|
||||||
|
slack-sdk==3.35.0
|
||||||
|
chardet==5.2.0
|
||||||
|
starlette==0.46.2
|
||||||
|
PyVirtualDisplay==3.0
|
||||||
|
psutil==7.0.0
|
||||||
|
python-dotenv==1.1.1
|
||||||
|
python-hosts==1.1.2
|
||||||
|
watchdog==6.0.0
|
||||||
|
cacheout==0.16.0
|
||||||
|
click==8.2.1
|
||||||
|
requests-cache==1.2.1
|
||||||
|
parse==1.20.2
|
||||||
|
docker==7.1.0
|
||||||
|
cachetools==6.1.0
|
||||||
|
fast-bencode==1.1.7
|
||||||
|
pystray==0.19.5
|
||||||
|
pyotp==2.9.0
|
||||||
|
Pinyin2Hanzi==0.1.1
|
||||||
|
pywebpush==2.0.3
|
||||||
|
aiopathlib==0.6.0
|
||||||
|
asynctempfile==0.5.0
|
||||||
|
aiosqlite==0.21.0
|
||||||
|
psycopg2-binary==2.9.10
|
||||||
|
asyncpg==0.30.0
|
||||||
|
jieba==0.42.1
|
||||||
|
rsa==4.9
|
||||||
|
redis==6.2.0
|
||||||
|
packaging==25.0
|
||||||
|
oss2==2.19.1
|
||||||
|
tqdm==4.67.1
|
||||||
|
setuptools==78.1.0
|
||||||
|
pympler==1.1
|
||||||
|
smbprotocol==1.15.0
|
||||||
|
setproctitle==1.3.6
|
||||||
|
httpx[socks]==0.28.1
|
||||||
|
prometheus-client==0.22.1
|
||||||
|
prometheus-fastapi-instrumentator==7.1.0
|
||||||
|
|
||||||
|
# Platform-specific dependencies
|
||||||
|
pywin32==310; platform_system == "Windows"
|
||||||
|
async_timeout==5.0.1; python_full_version < "3.11.3"
|
||||||
Reference in New Issue
Block a user