Spaces:
Running
Running
Update Dockerfile
Browse files- Dockerfile +134 -21
Dockerfile
CHANGED
|
@@ -11,36 +11,149 @@ ENV NODE_ENV=production
|
|
| 11 |
|
| 12 |
# ๐ ่ฎพ็ฝฎๆฐๅฏ็
|
| 13 |
ENV INITIAL_PASSWORD=Amd3dnow!
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
EXPOSE 7860
|
| 15 |
|
| 16 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
CMD \
|
| 18 |
-
# 1.
|
| 19 |
-
echo "===
|
| 20 |
-
echo "---
|
| 21 |
-
ls -
|
| 22 |
-
echo "---
|
| 23 |
-
ls -
|
| 24 |
-
echo "
|
|
|
|
|
|
|
| 25 |
\
|
| 26 |
-
# 2. ๅผๆบๆขๅคๆฐๆฎ
|
| 27 |
if [ -f /data/omni_storage.sqlite ]; then \
|
| 28 |
-
mkdir -p /root/.omniroute &&
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
if [ -f /data/omni_settings.json ]; then \
|
| 31 |
-
mkdir -p /root/.omniroute &&
|
| 32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
\
|
| 34 |
-
# 3. ๅๅฐ
|
| 35 |
(while true; do \
|
| 36 |
sleep 60; \
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
| 43 |
done) & \
|
| 44 |
\
|
| 45 |
-
# 4.
|
|
|
|
|
|
|
|
|
|
| 46 |
PORT=7860 omniroute
|
|
|
|
| 11 |
|
| 12 |
# ๐ ่ฎพ็ฝฎๆฐๅฏ็
|
| 13 |
ENV INITIAL_PASSWORD=Amd3dnow!
|
| 14 |
+
|
| 15 |
+
# ๐ ไธ่ฝฝๆฅๅฃ็่ฎฟ้ฎไปค็๏ผๅจ HF Space Settings โ Variables ้่ฆ็่ฟไธชๅผ๏ผ๏ผ
|
| 16 |
+
ENV DOWNLOAD_TOKEN=change_me_please
|
| 17 |
+
|
| 18 |
EXPOSE 7860
|
| 19 |
|
| 20 |
+
# ๅๅ
ฅไธ่ฝฝๆๅก่ๆฌ๏ผ็บฏ Node.js๏ผๆ ้้ขๅคไพ่ต๏ผ
|
| 21 |
+
RUN cat > /app/download_server.js << 'EOF'
|
| 22 |
+
const http = require('http');
|
| 23 |
+
const fs = require('fs');
|
| 24 |
+
const path = require('path');
|
| 25 |
+
const { execSync } = require('child_process');
|
| 26 |
+
|
| 27 |
+
const PORT = 7861;
|
| 28 |
+
const TOKEN = process.env.DOWNLOAD_TOKEN || 'change_me_please';
|
| 29 |
+
|
| 30 |
+
// ๅ
่ฎธไธ่ฝฝ็ๅฎๅ
จ็ฎๅฝ็ฝๅๅ
|
| 31 |
+
const ALLOWED_DIRS = ['/data', '/root/.omniroute'];
|
| 32 |
+
|
| 33 |
+
function safeResolvePath(filename) {
|
| 34 |
+
// ๅชๅ
่ฎธ็บฏๆไปถๅ๏ผๆ็ปไปปไฝ่ทฏๅพๅ้็ฌฆ๏ผ้ฒ่ทฏๅพ็ฉฟ่ถ๏ผ
|
| 35 |
+
if (!filename || filename.includes('/') || filename.includes('\\') || filename.includes('..')) {
|
| 36 |
+
return null;
|
| 37 |
+
}
|
| 38 |
+
// ไพๆฌกๅจ็ฝๅๅ็ฎๅฝไธญๆฅๆพๆไปถ
|
| 39 |
+
for (const dir of ALLOWED_DIRS) {
|
| 40 |
+
const fullPath = path.join(dir, filename);
|
| 41 |
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
| 42 |
+
return fullPath;
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
return null;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
const server = http.createServer((req, res) => {
|
| 49 |
+
const url = new URL(req.url, `http://localhost:${PORT}`);
|
| 50 |
+
const token = url.searchParams.get('token') || '';
|
| 51 |
+
const route = url.pathname;
|
| 52 |
+
|
| 53 |
+
// โโ ็ปไธ้ดๆ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 54 |
+
// ไฝฟ็จ้ๅญ็ฌฆๆฏ่พ้ฒๆญขๆถๅบๆปๅป
|
| 55 |
+
const tokenValid =
|
| 56 |
+
token.length === TOKEN.length &&
|
| 57 |
+
token.split('').every((c, i) => c === TOKEN[i]);
|
| 58 |
+
|
| 59 |
+
if (!tokenValid) {
|
| 60 |
+
res.writeHead(403, { 'Content-Type': 'application/json' });
|
| 61 |
+
res.end(JSON.stringify({ error: 'Forbidden: invalid token' }));
|
| 62 |
+
return;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// โโ GET /list โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 66 |
+
if (route === '/list') {
|
| 67 |
+
const result = {};
|
| 68 |
+
for (const dir of ALLOWED_DIRS) {
|
| 69 |
+
try {
|
| 70 |
+
result[dir] = fs.readdirSync(dir).map(name => {
|
| 71 |
+
const stat = fs.statSync(path.join(dir, name));
|
| 72 |
+
return { name, size: stat.size, mtime: stat.mtime };
|
| 73 |
+
});
|
| 74 |
+
} catch (_) {
|
| 75 |
+
result[dir] = `directory not found`;
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
| 79 |
+
res.end(JSON.stringify(result, null, 2));
|
| 80 |
+
return;
|
| 81 |
+
}
|
| 82 |
+
|
| 83 |
+
// โโ GET /download?token=...&file=omni_storage.sqlite โโโโโโ
|
| 84 |
+
if (route === '/download') {
|
| 85 |
+
const filename = url.searchParams.get('file') || '';
|
| 86 |
+
const fullPath = safeResolvePath(filename);
|
| 87 |
+
|
| 88 |
+
if (!fullPath) {
|
| 89 |
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
| 90 |
+
res.end(JSON.stringify({ error: `File not found: ${filename}` }));
|
| 91 |
+
return;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
const stat = fs.statSync(fullPath);
|
| 95 |
+
res.writeHead(200, {
|
| 96 |
+
'Content-Type': 'application/octet-stream',
|
| 97 |
+
'Content-Disposition': `attachment; filename="${filename}"`,
|
| 98 |
+
'Content-Length': stat.size,
|
| 99 |
+
});
|
| 100 |
+
fs.createReadStream(fullPath).pipe(res);
|
| 101 |
+
console.log(`[download] ${fullPath} (${stat.size} bytes)`);
|
| 102 |
+
return;
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
// โโ 404 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 106 |
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
| 107 |
+
res.end(JSON.stringify({ error: 'Unknown route', routes: ['/list', '/download'] }));
|
| 108 |
+
});
|
| 109 |
+
|
| 110 |
+
server.listen(PORT, '0.0.0.0', () => {
|
| 111 |
+
console.log(`[download-server] listening on port ${PORT}`);
|
| 112 |
+
console.log(`[download-server] routes: /list /download?file=<filename>`);
|
| 113 |
+
});
|
| 114 |
+
EOF
|
| 115 |
+
|
| 116 |
CMD \
|
| 117 |
+
# โโ 1. ๅฏๅจ่ฏๆญๆฅๅฟ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ \
|
| 118 |
+
echo "=== ๅญๅจ่ฏๆญๅผๅง ===" && \
|
| 119 |
+
echo "--- /data ็ฎๅฝ ---" && \
|
| 120 |
+
ls -lah /data 2>&1 || echo "/data ็ฎๅฝไธๅญๅจ" && \
|
| 121 |
+
echo "--- /root/.omniroute ็ฎๅฝ ---" && \
|
| 122 |
+
ls -lah /root/.omniroute 2>&1 || echo "OmniRoute ็ฎๅฝไธๅญๅจ" && \
|
| 123 |
+
echo "--- ็ฃ็ๆ่ฝฝๆ
ๅต ---" && \
|
| 124 |
+
df -h && \
|
| 125 |
+
echo "=== ๅญๅจ่ฏๆญ็ปๆ ===" && \
|
| 126 |
\
|
| 127 |
+
# โโ 2. ๅผๆบไปๆไน
ๅๅญๅจๆขๅคๆฐๆฎ โโโโโโโโโโโโโโโโโโโโโโโโโโโ \
|
| 128 |
if [ -f /data/omni_storage.sqlite ]; then \
|
| 129 |
+
mkdir -p /root/.omniroute && \
|
| 130 |
+
cp /data/omni_storage.sqlite /root/.omniroute/storage.sqlite && \
|
| 131 |
+
echo "โ
ๆขๅค storage.sqlite ๆๅ"; \
|
| 132 |
+
else \
|
| 133 |
+
echo "โ ๏ธ /data/omni_storage.sqlite ไธๅญๅจ๏ผ่ทณ่ฟๆขๅค"; \
|
| 134 |
+
fi && \
|
| 135 |
if [ -f /data/omni_settings.json ]; then \
|
| 136 |
+
mkdir -p /root/.omniroute && \
|
| 137 |
+
cp /data/omni_settings.json /root/.omniroute/settings.json && \
|
| 138 |
+
echo "โ
ๆขๅค settings.json ๆๅ"; \
|
| 139 |
+
else \
|
| 140 |
+
echo "โ ๏ธ /data/omni_settings.json ไธๅญๅจ๏ผ่ทณ่ฟๆขๅค"; \
|
| 141 |
+
fi && \
|
| 142 |
\
|
| 143 |
+
# โโ 3. ๅๅฐ๏ผๆฏ 60 ็งๆๆฐๆฎๅคไปฝๅฐ /data โโโโโโโโโโโโโโโโโโโ \
|
| 144 |
(while true; do \
|
| 145 |
sleep 60; \
|
| 146 |
+
mkdir -p /data; \
|
| 147 |
+
[ -f /root/.omniroute/storage.sqlite ] && \
|
| 148 |
+
cp /root/.omniroute/storage.sqlite /data/omni_storage.sqlite && \
|
| 149 |
+
echo "๐พ [backup] storage.sqlite โ /data"; \
|
| 150 |
+
[ -f /root/.omniroute/settings.json ] && \
|
| 151 |
+
cp /root/.omniroute/settings.json /data/omni_settings.json && \
|
| 152 |
+
echo "๐พ [backup] settings.json โ /data"; \
|
| 153 |
done) & \
|
| 154 |
\
|
| 155 |
+
# โโ 4. ๅๅฐ๏ผๅฏๅจไธ่ฝฝๆๅก๏ผ7861 ็ซฏๅฃ๏ผโโโโโโโโโโโโโโโโโโโโโ \
|
| 156 |
+
node /app/download_server.js & \
|
| 157 |
+
\
|
| 158 |
+
# โโ 5. ๅๅฐ๏ผๅฏๅจไธป็จๅบ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ \
|
| 159 |
PORT=7860 omniroute
|