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"] |