File size: 7,332 Bytes
6ea3bd5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
FROM node:20-bookworm-slim

ENV NODE_ENV=production \
    PORT=7860 \
    HOSTNAME=0.0.0.0 \
    NEXT_PUBLIC_STORAGE_TYPE=kvrocks \
    KVROCKS_URL=redis://127.0.0.1:6666 \
    LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so.2 \
    TZ=Asia/Shanghai

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    libjemalloc2 \
    openssl \
    ca-certificates \
    libatomic1 \
    python3 \
    python3-pip \
    python3-requests \
    curl \
    tar \
    && rm -rf /var/lib/apt/lists/*

RUN pip3 install webdavclient3 --break-system-packages && \
    rm -rf /root/.cache/pip

COPY --from=apache/kvrocks:latest /bin/kvrocks /usr/local/bin/kvrocks
COPY --from=ghcr.io/decohererk/decotv:latest /app /app

WORKDIR /app

RUN echo "import os" > /backup_utils.py && \
    echo "import sys" >> /backup_utils.py && \
    echo "import tarfile" >> /backup_utils.py && \
    echo "import shutil" >> /backup_utils.py && \
    echo "import time" >> /backup_utils.py && \
    echo "import urllib3" >> /backup_utils.py && \
    echo "from webdav3.client import Client" >> /backup_utils.py && \
    echo "import requests" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)" >> /backup_utils.py && \
    echo "webdav_url = os.environ.get('WEBDAV_URL')" >> /backup_utils.py && \
    echo "webdav_user = os.environ.get('WEBDAV_USERNAME')" >> /backup_utils.py && \
    echo "webdav_password = os.environ.get('WEBDAV_PASSWORD')" >> /backup_utils.py && \
    echo "backup_path = os.environ.get('WEBDAV_BACKUP_PATH', '')" >> /backup_utils.py && \
    echo "data_dir = '/data/kvrocks'" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "if not webdav_url or not webdav_user or not webdav_password:" >> /backup_utils.py && \
    echo "    sys.exit(0)" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "full_url = webdav_url" >> /backup_utils.py && \
    echo "if backup_path:" >> /backup_utils.py && \
    echo "    full_url = webdav_url.rstrip('/') + '/' + backup_path.strip('/')" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "options = {" >> /backup_utils.py && \
    echo "    'webdav_hostname': full_url," >> /backup_utils.py && \
    echo "    'webdav_login': webdav_user," >> /backup_utils.py && \
    echo "    'webdav_password': webdav_password," >> /backup_utils.py && \
    echo "    'disable_check_certificate_hostname_match': True" >> /backup_utils.py && \
    echo "}" >> /backup_utils.py && \
    echo "client = Client(options)" >> /backup_utils.py && \
    echo "auth_tuple = (webdav_user, webdav_password)" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "def restore():" >> /backup_utils.py && \
    echo "    try:" >> /backup_utils.py && \
    echo "        files = client.list()" >> /backup_utils.py && \
    echo "        backups = [f for f in files if f.endswith('.tar.gz') and f.startswith('decotv_backup_')]" >> /backup_utils.py && \
    echo "        if not backups:" >> /backup_utils.py && \
    echo "            return" >> /backup_utils.py && \
    echo "        latest_backup = sorted(backups)[-1]" >> /backup_utils.py && \
    echo "        local_tmp = '/tmp/' + latest_backup" >> /backup_utils.py && \
    echo "        download_url = full_url.rstrip('/') + '/' + latest_backup" >> /backup_utils.py && \
    echo "        with requests.get(download_url, auth=auth_tuple, stream=True, verify=False) as r:" >> /backup_utils.py && \
    echo "            r.raise_for_status()" >> /backup_utils.py && \
    echo "            with open(local_tmp, 'wb') as f:" >> /backup_utils.py && \
    echo "                for chunk in r.iter_content(chunk_size=8192):" >> /backup_utils.py && \
    echo "                    f.write(chunk)" >> /backup_utils.py && \
    echo "        if os.path.exists(data_dir):" >> /backup_utils.py && \
    echo "            shutil.rmtree(data_dir)" >> /backup_utils.py && \
    echo "        os.makedirs(data_dir, exist_ok=True)" >> /backup_utils.py && \
    echo "        with tarfile.open(local_tmp, 'r:gz') as tar:" >> /backup_utils.py && \
    echo "            tar.extractall(path='/data')" >> /backup_utils.py && \
    echo "        os.remove(local_tmp)" >> /backup_utils.py && \
    echo "    except Exception as e:" >> /backup_utils.py && \
    echo "        print(e)" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "def backup():" >> /backup_utils.py && \
    echo "    timestamp = time.strftime('%Y%m%d_%H%M%S')" >> /backup_utils.py && \
    echo "    filename = 'decotv_backup_' + timestamp + '.tar.gz'" >> /backup_utils.py && \
    echo "    local_path = '/tmp/' + filename" >> /backup_utils.py && \
    echo "    try:" >> /backup_utils.py && \
    echo "        with tarfile.open(local_path, 'w:gz') as tar:" >> /backup_utils.py && \
    echo "            tar.add(data_dir, arcname='kvrocks')" >> /backup_utils.py && \
    echo "        client.upload_sync(remote_path=filename, local_path=local_path)" >> /backup_utils.py && \
    echo "        os.remove(local_path)" >> /backup_utils.py && \
    echo "        files = client.list()" >> /backup_utils.py && \
    echo "        backups = [f for f in files if f.endswith('.tar.gz') and f.startswith('decotv_backup_')]" >> /backup_utils.py && \
    echo "        backups.sort()" >> /backup_utils.py && \
    echo "        if len(backups) > 5:" >> /backup_utils.py && \
    echo "            for f in backups[:-5]:" >> /backup_utils.py && \
    echo "                client.clean(f)" >> /backup_utils.py && \
    echo "    except Exception as e:" >> /backup_utils.py && \
    echo "        print(e)" >> /backup_utils.py && \
    echo "" >> /backup_utils.py && \
    echo "if __name__ == '__main__':" >> /backup_utils.py && \
    echo "    action = sys.argv[1]" >> /backup_utils.py && \
    echo "    if action == 'restore':" >> /backup_utils.py && \
    echo "        restore()" >> /backup_utils.py && \
    echo "    elif action == 'backup':" >> /backup_utils.py && \
    echo "        backup()" >> /backup_utils.py

RUN echo '#!/bin/bash' > /start.sh && \
    echo 'set -e' >> /start.sh && \
    echo 'python3 /backup_utils.py restore' >> /start.sh && \
    echo 'mkdir -p /data/kvrocks' >> /start.sh && \
    echo 'echo "bind 127.0.0.1" > /data/kvrocks.conf' >> /start.sh && \
    echo 'echo "port 6666" >> /data/kvrocks.conf' >> /start.sh && \
    echo 'echo "dir /data/kvrocks" >> /data/kvrocks.conf' >> /start.sh && \
    echo 'echo "workers 2" >> /data/kvrocks.conf' >> /start.sh && \
    echo 'echo "rocksdb.max_background_jobs 2" >> /data/kvrocks.conf' >> /start.sh && \
    echo '/usr/local/bin/kvrocks -c /data/kvrocks.conf --daemonize yes' >> /start.sh && \
    echo 'sleep 5' >> /start.sh && \
    echo '(' >> /start.sh && \
    echo '  while true; do' >> /start.sh && \
    echo '    SYNC_INTERVAL=${SYNC_INTERVAL:-600}' >> /start.sh && \
    echo '    sleep $SYNC_INTERVAL' >> /start.sh && \
    echo '    python3 /backup_utils.py backup' >> /start.sh && \
    echo '  done' >> /start.sh && \
    echo ') &' >> /start.sh && \
    echo 'cd /app' >> /start.sh && \
    echo 'node start.js' >> /start.sh && \
    chmod +x /start.sh && \
    mkdir -p /data && \
    chmod -R 777 /app /data

CMD ["/start.sh"]