hxger commited on
Commit
9414fef
·
verified ·
1 Parent(s): 64f4ae0

Upload 2 files

Browse files
Files changed (2) hide show
  1. Dockerfile +62 -0
  2. sync_data.sh +154 -0
Dockerfile ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM soyorins/imageflow
2
+
3
+ ENV STORAGE_TYPE="local"
4
+ ENV LOCAL_STORAGE_PATH="/app/static/images"
5
+ ENV S3_ENDPOINT=""
6
+ ENV S3_REGION=""
7
+ ENV S3_ACCESS_KEY=""
8
+ ENV S3_SECRET_KEY=""
9
+ ENV S3_BUCKET=""
10
+ ENV CUSTOM_DOMAIN=""
11
+ ENV MAX_UPLOAD_COUNT="20"
12
+ ENV IMAGE_QUALITY="80"
13
+ ENV WORKER_THREADS="4"
14
+ ENV COMPRESSION_EFFORT="6"
15
+ ENV FORCE_LOSSLESS="false"
16
+
17
+ # WebDAV备份配置
18
+ ENV WEBDAV_URL=""
19
+ ENV WEBDAV_USERNAME=""
20
+ ENV WEBDAV_PASSWORD=""
21
+ ENV WEBDAV_BACKUP_PATH=""
22
+ ENV SYNC_INTERVAL="600"
23
+
24
+ # 安装WebDAV备份所需依赖
25
+ RUN apk add --no-cache python3 py3-pip curl tar shadow
26
+
27
+ # 确保目录存在并授予合适的权限
28
+ RUN mkdir -p /app/static/images/metadata \
29
+ /app/static/images/original/landscape \
30
+ /app/static/images/original/portrait \
31
+ /app/static/images/landscape/webp \
32
+ /app/static/images/landscape/avif \
33
+ /app/static/images/portrait/webp \
34
+ /app/static/images/portrait/avif \
35
+ /app/static/images/gif
36
+
37
+ # 确保权限正确
38
+ RUN chmod -R 777 /app/static/images && \
39
+ chown -R nobody:nobody /app/static/images
40
+
41
+ RUN touch /app/.env && chmod 666 /app/.env
42
+
43
+ ENV APP_DIR="/app"
44
+ ENV APP_NAME="image"
45
+ ENV APP_SUFFIX="flow"
46
+
47
+ # 安装Python依赖
48
+ RUN pip3 install --no-cache-dir requests webdavclient3 --break-system-packages
49
+
50
+ # 复制同步脚本到容器中
51
+ COPY sync_data.sh /app/
52
+ RUN chmod +x /app/sync_data.sh
53
+
54
+ # 创建专用用户运行应用
55
+ RUN adduser -D -u 1000 appuser
56
+ RUN chown -R appuser:appuser /app
57
+
58
+ # 设置工作目录
59
+ WORKDIR /app
60
+
61
+ # 使用CMD指令启动应用
62
+ CMD ["/bin/sh", "-c", "/app/sync_data.sh & sleep 30 && $APP_DIR/$APP_NAME$APP_SUFFIX"]
sync_data.sh ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ # 检查环境变量
4
+ if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
5
+ echo "Starting without backup functionality - missing WEBDAV_URL, WEBDAV_USERNAME, or WEBDAV_PASSWORD"
6
+ exec $APP_DIR/$APP_NAME$APP_SUFFIX
7
+ exit 0
8
+ fi
9
+
10
+ # 设置备份路径
11
+ WEBDAV_BACKUP_PATH=${WEBDAV_BACKUP_PATH:-""}
12
+ FULL_WEBDAV_URL="${WEBDAV_URL}"
13
+ if [ -n "$WEBDAV_BACKUP_PATH" ]; then
14
+ FULL_WEBDAV_URL="${WEBDAV_URL}/${WEBDAV_BACKUP_PATH}"
15
+ fi
16
+
17
+ # 下载最新备份并恢复
18
+ restore_backup() {
19
+ echo "开始从 WebDAV 下载最新备份..."
20
+ python3 -c "
21
+ import sys
22
+ import os
23
+ import tarfile
24
+ import requests
25
+ import shutil
26
+ from webdav3.client import Client
27
+ options = {
28
+ 'webdav_hostname': '$FULL_WEBDAV_URL',
29
+ 'webdav_login': '$WEBDAV_USERNAME',
30
+ 'webdav_password': '$WEBDAV_PASSWORD'
31
+ }
32
+ client = Client(options)
33
+ backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('imageflow_backup_')]
34
+ if not backups:
35
+ print('没有找到备份文件')
36
+ sys.exit()
37
+ latest_backup = sorted(backups)[-1]
38
+ print(f'最新备份文件:{latest_backup}')
39
+ with requests.get(f'$FULL_WEBDAV_URL/{latest_backup}', auth=('$WEBDAV_USERNAME', '$WEBDAV_PASSWORD'), stream=True) as r:
40
+ if r.status_code == 200:
41
+ with open(f'/tmp/{latest_backup}', 'wb') as f:
42
+ for chunk in r.iter_content(chunk_size=8192):
43
+ f.write(chunk)
44
+ print(f'成功下载备份文件到 /tmp/{latest_backup}')
45
+ if os.path.exists(f'/tmp/{latest_backup}'):
46
+ # 如果images目录已存在,先尝试安全删除它
47
+ if os.path.exists('/app/static/images'):
48
+ print('尝试删除现有的images目录')
49
+ try:
50
+ # 首先尝试添加写权限
51
+ for root, dirs, files in os.walk('/app/static/images'):
52
+ os.chmod(root, 0o777)
53
+ for f in files:
54
+ os.chmod(os.path.join(root, f), 0o666)
55
+ # 然后尝试删除
56
+ shutil.rmtree('/app/static/images')
57
+ print('成功删除images目录')
58
+ except Exception as e:
59
+ print(f'删除目录时出错: {e}')
60
+ print('尝试使用系统命令删除')
61
+ # 如果Python无法删除,尝试使用系统命令
62
+ os.system('chmod -R 777 /app/static/images')
63
+ os.system('rm -rf /app/static/images')
64
+ # 验证是否删除成功
65
+ if not os.path.exists('/app/static/images'):
66
+ print('使用系统命令成功删除images目录')
67
+ else:
68
+ print('警告:无法删除现有目录,将尝试继续恢复')
69
+
70
+ # 创建新的images目录(如果不存在)
71
+ os.makedirs('/app/static/images', exist_ok=True)
72
+ os.chmod('/app/static/images', 0o777)
73
+
74
+ # 解压备份文件
75
+ with tarfile.open(f'/tmp/{latest_backup}', 'r:gz') as tar:
76
+ tar.extractall('/app/')
77
+
78
+ # 确保恢复后的目录有正确的权限
79
+ for root, dirs, files in os.walk('/app/static/images'):
80
+ os.chmod(root, 0o777)
81
+ for f in files:
82
+ os.chmod(os.path.join(root, f), 0o666)
83
+
84
+ print(f'成功从 {latest_backup} 恢复备份')
85
+ else:
86
+ print('下载的备份文件不存在')
87
+ else:
88
+ print(f'下载备份失败:{r.status_code}')
89
+ "
90
+ }
91
+
92
+ # 首次启动时下载最新备份
93
+ echo "Downloading latest backup from WebDAV..."
94
+ restore_backup
95
+
96
+ # 同步函数
97
+ sync_data() {
98
+ while true; do
99
+ echo "Starting sync process at $(date)"
100
+
101
+ if [ -d "/app/static/images" ]; then
102
+ timestamp=$(date +%Y%m%d_%H%M%S)
103
+ backup_file="imageflow_backup_${timestamp}.tar.gz"
104
+
105
+ # 备份整个images目录
106
+ cd /app
107
+ tar -czf "/tmp/${backup_file}" static/images
108
+
109
+ # 上传新备份到WebDAV
110
+ curl -u "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -T "/tmp/${backup_file}" "$FULL_WEBDAV_URL/${backup_file}"
111
+ if [ $? -eq 0 ]; then
112
+ echo "Successfully uploaded ${backup_file} to WebDAV"
113
+ else
114
+ echo "Failed to upload ${backup_file} to WebDAV"
115
+ fi
116
+
117
+ # 清理旧备份文件
118
+ python3 -c "
119
+ import sys
120
+ from webdav3.client import Client
121
+ options = {
122
+ 'webdav_hostname': '$FULL_WEBDAV_URL',
123
+ 'webdav_login': '$WEBDAV_USERNAME',
124
+ 'webdav_password': '$WEBDAV_PASSWORD'
125
+ }
126
+ client = Client(options)
127
+ backups = [file for file in client.list() if file.endswith('.tar.gz') and file.startswith('imageflow_backup_')]
128
+ backups.sort()
129
+ if len(backups) > 5:
130
+ to_delete = len(backups) - 5
131
+ for file in backups[:to_delete]:
132
+ client.clean(file)
133
+ print(f'Successfully deleted {file}.')
134
+ else:
135
+ print('Only {} backups found, no need to clean.'.format(len(backups)))
136
+ " 2>&1
137
+
138
+ rm -f "/tmp/${backup_file}"
139
+ else
140
+ echo "/app/static/images directory does not exist, waiting for next sync..."
141
+ fi
142
+
143
+ SYNC_INTERVAL=${SYNC_INTERVAL:-600}
144
+ echo "Next sync in ${SYNC_INTERVAL} seconds..."
145
+ sleep $SYNC_INTERVAL
146
+ done
147
+ }
148
+
149
+ # 启动同步进程
150
+ sync_data &
151
+
152
+ # 启动主应用
153
+ sleep 30
154
+ exec $APP_DIR/$APP_NAME$APP_SUFFIX