Some checks failed
Gitea Actions Official-website / deploy-dev (push) Failing after 3s
416 lines
12 KiB
Markdown
416 lines
12 KiB
Markdown
# 图片迁移脚本 (Image Migration Script)
|
||
|
||
从本地目录或SSH服务器迁移图片到远程SSH服务器,保持相对路径结构一致。
|
||
|
||
## 功能特性
|
||
|
||
- ✅ **灵活的源支持**:支持本地目录(`local`)和SSH服务器(`ssh`)作为源
|
||
- ✅ **远程目标**:通过SSH迁移到远程服务器
|
||
- ✅ **路径保持**:在目标服务器上保持相同的相对路径和文件名
|
||
- ✅ **配置灵活**:支持配置文件和命令行参数
|
||
- ✅ **目录自动创建**:递归创建目标目录结构
|
||
- ✅ **重复文件处理**:默认跳过已存在文件,支持覆盖选项
|
||
- ✅ **进度统计**:显示详细的传输进度和统计信息
|
||
- ✅ **错误处理**:完善的连接管理和错误处理
|
||
|
||
## 环境要求
|
||
|
||
- Python 3.6+
|
||
- paramiko 库(用于SSH连接)
|
||
|
||
## 快速开始
|
||
|
||
### 1. 安装依赖
|
||
|
||
```bash
|
||
cd /var/www/html/orico-official-website/scripts
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. 创建配置文件
|
||
|
||
```bash
|
||
# 创建示例配置文件
|
||
python image_migrate.py --create-config config.json
|
||
|
||
# 编辑配置文件,填写真实的服务器信息
|
||
vim config.json
|
||
```
|
||
|
||
### 3. 准备图片路径列表
|
||
|
||
创建一个文本文件(如 `images.txt`),每行一个相对路径:
|
||
|
||
```
|
||
uploads/products/2024/01/product1.jpg
|
||
uploads/products/2024/01/product2.jpg
|
||
assets/images/logo.png
|
||
```
|
||
|
||
### 4. 执行迁移
|
||
|
||
#### 从本地目录迁移到远程服务器(最常用)
|
||
|
||
```bash
|
||
# 使用配置文件迁移(源为本地目录)
|
||
python image_migrate.py --config config.json --input images.txt
|
||
|
||
# 或直接指定参数迁移(源为本地目录)
|
||
python image_migrate.py \
|
||
--source-type local --source-dir /path/to/local/images \
|
||
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \
|
||
--input images.txt --verbose
|
||
```
|
||
|
||
#### 从SSH服务器迁移到另一个SSH服务器
|
||
|
||
```bash
|
||
# 使用配置文件迁移(源为SSH服务器)
|
||
python image_migrate.py --config config.json --input images.txt
|
||
|
||
# 或直接指定参数迁移(源为SSH服务器)
|
||
python image_migrate.py \
|
||
--source-type ssh --source-host src.example.com --source-user user1 --source-dir /var/www/images \
|
||
--target-host dst.example.com --target-user user2 --target-dir /home/user/images \
|
||
--input images.txt --verbose
|
||
```
|
||
|
||
## 配置文件格式
|
||
|
||
配置文件为JSON格式,支持两种源类型配置:
|
||
|
||
### 本地目录作为源(推荐)
|
||
|
||
```json
|
||
{
|
||
"source": {
|
||
"type": "local",
|
||
"base_dir": "/path/to/local/images"
|
||
},
|
||
"target": {
|
||
"type": "ssh",
|
||
"base_dir": "/var/www/html/images",
|
||
"ssh": {
|
||
"host": "target-server.example.com",
|
||
"port": 22,
|
||
"username": "username",
|
||
"password": "your_password_here",
|
||
"key_file": "/path/to/private/key"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### SSH服务器作为源
|
||
|
||
```json
|
||
{
|
||
"source": {
|
||
"type": "ssh",
|
||
"base_dir": "/var/www/html/images",
|
||
"ssh": {
|
||
"host": "source-server.example.com",
|
||
"port": 22,
|
||
"username": "username",
|
||
"password": "your_password_here",
|
||
"key_file": "/path/to/private/key"
|
||
}
|
||
},
|
||
"target": {
|
||
"type": "ssh",
|
||
"base_dir": "/var/www/html/images",
|
||
"ssh": {
|
||
"host": "target-server.example.com",
|
||
"port": 22,
|
||
"username": "username",
|
||
"password": "your_password_here",
|
||
"key_file": "/path/to/private/key"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**注意:**
|
||
|
||
- `type`:可以是 `"local"`(本地目录)或 `"ssh"`(SSH服务器)
|
||
- `base_dir`:图片的基础目录,图片的相对路径将相对于这个目录
|
||
- 对于SSH类型,需要提供`ssh`配置部分
|
||
- `password` 和 `key_file` 二选一即可
|
||
- 目标服务器**必须**是SSH类型
|
||
|
||
## 命令行参数
|
||
|
||
### 主要选项
|
||
|
||
| 参数 | 说明 |
|
||
| ---------------------- | ---------------------- |
|
||
| `--config FILE` | 使用配置文件 |
|
||
| `--create-config FILE` | 创建示例配置文件 |
|
||
| `--input FILE` | 包含图片路径列表的文件 |
|
||
| `--verbose`, `-v` | 显示详细输出 |
|
||
| `--overwrite` | 覆盖已存在的文件 |
|
||
|
||
### 源服务器参数(可覆盖配置文件)
|
||
|
||
| 参数 | 说明 |
|
||
| ------------------------ | ------------------------------------------------------------ |
|
||
| `--source-type TYPE` | 源类型: `local`(本地目录) 或 `ssh`(SSH服务器),默认: `local` |
|
||
| `--source-dir DIR` | **必需** 源服务器图片基础目录 |
|
||
| `--source-host HOST` | 源服务器地址(仅SSH类型需要) |
|
||
| `--source-port PORT` | 源服务器端口(仅SSH类型,默认: 22) |
|
||
| `--source-user USER` | 源服务器用户名(仅SSH类型需要) |
|
||
| `--source-password PASS` | 源服务器密码(仅SSH类型需要) |
|
||
| `--source-key FILE` | 源服务器私钥文件路径(仅SSH类型需要) |
|
||
|
||
### 目标服务器参数(可覆盖配置文件)
|
||
|
||
| 参数 | 说明 |
|
||
| ------------------------ | ------------------------------------ |
|
||
| `--target-host HOST` | **必需** 目标服务器地址(必须是SSH) |
|
||
| `--target-port PORT` | 目标服务器端口(默认: 22) |
|
||
| `--target-user USER` | **必需** 目标服务器用户名 |
|
||
| `--target-password PASS` | 目标服务器密码 |
|
||
| `--target-key FILE` | 目标服务器私钥文件路径 |
|
||
| `--target-dir DIR` | **必需** 目标服务器图片基础目录 |
|
||
|
||
## 使用示例
|
||
|
||
### 示例1:从本地目录迁移到远程服务器(推荐)
|
||
|
||
```bash
|
||
# 1. 创建配置文件
|
||
python image_migrate.py --create-config myconfig.json
|
||
|
||
# 2. 编辑配置文件
|
||
# 将 source.type 设置为 "local"
|
||
# 设置 source.base_dir 为本地目录路径
|
||
# 填写目标服务器的SSH信息
|
||
|
||
# 3. 创建图片路径文件
|
||
echo "uploads/test.jpg" > images.txt
|
||
echo "assets/logo.png" >> images.txt
|
||
|
||
# 4. 执行迁移
|
||
python image_migrate.py --config myconfig.json --input images.txt
|
||
```
|
||
|
||
### 示例2:直接从命令行迁移本地图片
|
||
|
||
```bash
|
||
python image_migrate.py \
|
||
--source-type local \
|
||
--source-dir /home/user/my_website/images \
|
||
--target-host 192.168.1.200 \
|
||
--target-user deploy \
|
||
--target-key ~/.ssh/id_rsa \
|
||
--target-dir /var/www/html/images \
|
||
--input images.txt \
|
||
--verbose
|
||
```
|
||
|
||
### 示例3:从SSH服务器迁移到另一个SSH服务器
|
||
|
||
```bash
|
||
python image_migrate.py \
|
||
--source-type ssh \
|
||
--source-host old-server.example.com \
|
||
--source-user admin \
|
||
--source-key ~/.ssh/id_rsa \
|
||
--source-dir /var/www/images \
|
||
--target-host new-server.example.com \
|
||
--target-user deploy \
|
||
--target-dir /home/deploy/images \
|
||
--input images.txt \
|
||
--overwrite
|
||
```
|
||
|
||
### 示例4:直接从命令行指定图片路径
|
||
|
||
```bash
|
||
python image_migrate.py --config config.json \
|
||
"uploads/product1.jpg" \
|
||
"uploads/product2.jpg" \
|
||
"assets/logo.png"
|
||
```
|
||
|
||
### 示例5:批量迁移数据库导出的图片路径
|
||
|
||
```bash
|
||
# 从数据库导出图片路径(假设每行一个路径)
|
||
mysql -e "SELECT image_path FROM products" --skip-column-names > products.txt
|
||
|
||
# 清理路径(如果需要)
|
||
sed -i 's/^\.\///' products.txt
|
||
|
||
# 迁移图片
|
||
python image_migrate.py --config config.json --input products.txt --verbose
|
||
```
|
||
|
||
## 图片路径格式
|
||
|
||
图片路径应为**相对路径**,相对于配置文件中指定的 `base_dir`:
|
||
|
||
```
|
||
# 正确示例(相对路径)
|
||
uploads/products/2024/01/product1.jpg
|
||
assets/images/logo.png
|
||
|
||
# 错误示例(绝对路径)
|
||
/var/www/html/images/uploads/product1.jpg # 错误!应该使用相对路径
|
||
|
||
# 在目标服务器上,文件将保存为:
|
||
# 目标 base_dir + 相对路径
|
||
```
|
||
|
||
## 工作流程
|
||
|
||
1. **连接建立**:连接到目标SSH服务器(源为本地时不需要连接)
|
||
2. **路径处理**:为每个图片构建完整源路径和目标路径
|
||
3. **目录创建**:在目标服务器上创建必要的目录结构
|
||
4. **文件检查**:检查源文件是否存在,目标文件是否已存在(跳过)
|
||
5. **文件传输**:通过本地临时文件传输(源→本地临时文件→目标)
|
||
6. **统计报告**:显示传输结果和统计信息
|
||
|
||
## 故障排除
|
||
|
||
### 常见问题
|
||
|
||
#### 1. 连接失败
|
||
|
||
```
|
||
错误: 连接失败: [Errno 111] Connection refused
|
||
```
|
||
|
||
- 检查目标服务器地址和端口
|
||
- 确认SSH服务正在运行
|
||
- 检查防火墙设置
|
||
|
||
#### 2. 认证失败
|
||
|
||
```
|
||
错误: Authentication failed.
|
||
```
|
||
|
||
- 确认用户名和密码正确
|
||
- 检查SSH密钥权限(chmod 600 ~/.ssh/id_rsa)
|
||
- 确认密钥已添加到目标服务器的 authorized_keys
|
||
|
||
#### 3. 源文件不存在
|
||
|
||
```
|
||
错误: 源文件不存在: /path/to/local/images/uploads/test.jpg
|
||
```
|
||
|
||
- 确认相对路径正确
|
||
- 确认源基础目录正确
|
||
- 使用 `--verbose` 查看完整路径
|
||
|
||
#### 4. 权限不足
|
||
|
||
```
|
||
错误: Permission denied
|
||
```
|
||
|
||
- 确认用户有读取源文件的权限(本地文件)
|
||
- 确认用户有写入目标目录的权限
|
||
|
||
#### 5. 目录创建失败
|
||
|
||
```
|
||
错误: 无法创建目标目录: /var/www/html/images/uploads
|
||
```
|
||
|
||
- 检查目标目录的写入权限
|
||
- 确认目标服务器磁盘空间充足
|
||
|
||
### 调试技巧
|
||
|
||
1. **使用详细模式**:添加 `--verbose` 参数查看详细信息
|
||
2. **测试连接**:手动SSH连接测试目标服务器是否可达
|
||
3. **检查路径**:在源目录上确认文件存在
|
||
4. **查看日志**:脚本会显示详细的错误信息
|
||
|
||
## 性能优化
|
||
|
||
### 大文件传输
|
||
|
||
- 脚本使用流式传输,适用于大文件
|
||
- 临时文件存储在系统临时目录,传输完成后自动清理
|
||
|
||
### 批量传输
|
||
|
||
- 对于大量文件,建议分批处理
|
||
- 可以使用多个图片路径文件,分别执行迁移
|
||
|
||
### 网络优化
|
||
|
||
- 确保到目标服务器的网络连接稳定
|
||
- 考虑使用内网传输以提高速度
|
||
|
||
## 安全注意事项
|
||
|
||
1. **认证方式**:建议使用SSH密钥认证而非密码
|
||
2. **权限控制**:配置文件建议设置权限 `chmod 600 config.json`
|
||
3. **最小权限**:使用具有最小必要权限的账户执行迁移
|
||
4. **本地文件安全**:确保本地目录不包含敏感信息
|
||
5. **临时文件清理**:脚本会自动清理临时传输文件
|
||
|
||
## 扩展和定制
|
||
|
||
### 修改脚本
|
||
|
||
- 可以在 `ImageMigrator` 类中添加额外的功能
|
||
- 支持断点续传、并行传输等高级功能
|
||
|
||
### 集成到工作流
|
||
|
||
- 可以与其他脚本结合使用
|
||
- 可以作为CI/CD流程的一部分
|
||
|
||
### 添加进度条
|
||
|
||
```python
|
||
# 可选:安装 tqdm 库
|
||
pip install tqdm
|
||
|
||
# 在脚本中添加进度条显示
|
||
```
|
||
|
||
## 文件结构
|
||
|
||
```
|
||
scripts/
|
||
├── image_migrate.py # 主脚本
|
||
├── image_migrate_backup.py # 原始版本备份
|
||
├── requirements.txt # Python依赖
|
||
├── README.md # 本文档
|
||
└── examples/ # 示例文件
|
||
├── config.example.json # 配置文件示例
|
||
└── images.example.txt # 图片路径示例
|
||
```
|
||
|
||
## 版本更新
|
||
|
||
### v2.0 更新
|
||
|
||
- ✅ 新增本地目录(`local`)作为源的支持
|
||
- ✅ 默认源类型改为`local`
|
||
- ✅ 简化配置文件结构
|
||
- ✅ 改进错误处理和临时文件管理
|
||
|
||
## 许可证
|
||
|
||
本脚本根据项目需要自由使用和修改。
|
||
|
||
## 支持
|
||
|
||
如有问题,请:
|
||
|
||
1. 检查本文档的故障排除部分
|
||
2. 使用 `--verbose` 参数获取详细信息
|
||
3. 确认服务器配置正确
|
||
|
||
---
|
||
|
||
**提示**:首次使用前,建议在测试服务器上进行小规模测试。
|