detv / Dockerfile
winhex168's picture
Update Dockerfile
6ea3bd5 verified
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"]