shell / Dockerfile
soxogvv's picture
Update Dockerfile
4a7b658 verified
# ── Base image ────────────────────────────────────────────────────────────────
FROM node:20-slim
# ── System dependencies ───────────────────────────────────────────────────────
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python3-venv \
make \
g++ \
wget \
curl \
git \
neofetch \
mediainfo \
screen \
nano \
rsync \
&& rm -rf /var/lib/apt/lists/*
# ── Install bore ──────────────────────────────────────────────────────────────
RUN wget -q "https://github.com/ekzhang/bore/releases/download/v0.5.0/bore-v0.5.0-x86_64-unknown-linux-musl.tar.gz" \
-O /tmp/bore.tar.gz && \
tar -xzf /tmp/bore.tar.gz -C /usr/local/bin bore && \
chmod +x /usr/local/bin/bore && \
rm /tmp/bore.tar.gz
# ── Pin a stable machine-id ───────────────────────────────────────────────────
RUN echo "d8904b4d338adf83688caac869f64c0b" > /etc/machine-id && \
mkdir -p /var/lib/dbus && \
echo "d8904b4d338adf83688caac869f64c0b" > /var/lib/dbus/machine-id
USER root
# ── Set HOME and PATH ─────────────────────────────────────────────────────────
ENV HOME=/root \
PATH="/root/venv/bin:/usr/local/bin:${PATH}" \
VIRTUAL_ENV=/root/venv \
PIP_NO_CACHE_DIR=1 \
HOSTNAME=kanha
# ── Install shellular globally ────────────────────────────────────────────────
RUN npm install -g --prefix /usr/local shellular
# ── Create Python venv ────────────────────────────────────────────────────────
RUN python3 -m venv /root/venv && \
/root/venv/bin/pip install --upgrade pip && \
/root/venv/bin/pip install huggingface_hub && \
rm -f /root/venv/lib/python*/EXTERNALLY-MANAGED
# ── Shell config ──────────────────────────────────────────────────────────────
RUN echo 'export PS1="\u@kanha:\w\$ "' >> /root/.bashrc && \
echo 'cd /data' >> /root/.bashrc && \
echo 'cd /data' >> /root/.bash_profile
# ── Force pip/python β†’ always use /root/venv ─────────────────────────────────
RUN printf '%s\n' \
'#!/bin/sh' \
'exec /root/venv/bin/pip "$@"' \
> /usr/local/bin/pip && chmod +x /usr/local/bin/pip && \
\
printf '%s\n' \
'#!/bin/sh' \
'exec /root/venv/bin/pip3 "$@"' \
> /usr/local/bin/pip3 && chmod +x /usr/local/bin/pip3 && \
\
printf '%s\n' \
'#!/bin/sh' \
'exec /root/venv/bin/python "$@"' \
> /usr/local/bin/python && chmod +x /usr/local/bin/python && \
\
printf '%s\n' \
'#!/bin/sh' \
'exec /root/venv/bin/python3 "$@"' \
> /usr/local/bin/python3 && chmod +x /usr/local/bin/python3
# ── apt/apt-get wrapper β†’ saves to apt.txt ───────────────────────────────────
RUN printf '%s\n' \
'#!/bin/sh' \
'APT_FILE="/data/apt.txt"' \
'REAL_BIN="$1"' \
'shift' \
'if [ "$1" = "install" ]; then' \
' shift' \
' "$REAL_BIN" install "$@"' \
' STATUS=$?' \
' if [ $STATUS -eq 0 ]; then' \
' touch "$APT_FILE"' \
' for arg in "$@"; do' \
' case "$arg" in -*) continue ;; esac' \
' if ! grep -qx "$arg" "$APT_FILE"; then' \
' echo "$arg" >> "$APT_FILE"' \
' echo "βœ“ $arg saved to apt.txt"' \
' fi' \
' done' \
' fi' \
' exit $STATUS' \
'fi' \
'"$REAL_BIN" "$@"' \
> /usr/local/bin/_apt_wrapper && chmod +x /usr/local/bin/_apt_wrapper
RUN printf '%s\n' \
'#!/bin/sh' \
'exec /usr/local/bin/_apt_wrapper /usr/bin/apt "$@"' \
> /usr/local/bin/apt && chmod +x /usr/local/bin/apt
RUN printf '%s\n' \
'#!/bin/sh' \
'exec /usr/local/bin/_apt_wrapper /usr/bin/apt-get "$@"' \
> /usr/local/bin/apt-get && chmod +x /usr/local/bin/apt-get
# ── Ensure /data exists ───────────────────────────────────────────────────────
RUN mkdir -p /data
# ── App ───────────────────────────────────────────────────────────────────────
COPY package*.json /root/app/
RUN cd /root/app && npm install --omit=dev
COPY . /root/app/
# ── Entrypoint ────────────────────────────────────────────────────────────────
RUN printf '%s\n' \
'#!/bin/sh' \
'set -e' \
'' \
'mkdir -p /data/persist' \
'' \
'# ── Step 1: RESTORE β€” /data/persist β†’ /root/ ────────────────────────' \
'# /root/ is always the real live directory' \
'# On restart container is fresh so restore from backup' \
'if [ -d "/data/persist/venv" ] && [ ! -L "/data/persist/venv" ]; then' \
' echo "β–Ά Restoring venv from backup..."' \
' rsync -a --ignore-existing /data/persist/venv/ /root/venv/ 2>/dev/null || true' \
'else' \
' echo "β–Ά No venv backup found, using image default"' \
'fi' \
'if [ -d "/data/persist/cache" ] && [ ! -L "/data/persist/cache" ]; then' \
' echo "β–Ά Restoring cache from backup..."' \
' rsync -a --ignore-existing /data/persist/cache/ /root/.cache/ 2>/dev/null || true' \
'fi' \
'' \
'# ── Step 2: Fix pip ──────────────────────────────────────────────────' \
'rm -f /root/venv/lib/python*/EXTERNALLY-MANAGED' \
'' \
'# ── Step 3: WIPE old backup, recreate fresh from /root/ ─────────────' \
'# Deleting old backup is safe because we already restored to /root/' \
'# Fresh copy from /root/ always has correct permissions' \
'echo "β–Ά Rebuilding backup from /root/venv..."' \
'rm -rf /data/persist/venv' \
'rm -rf /data/persist/cache' \
'cp -a /root/venv /data/persist/venv' \
'cp -a /root/.cache /data/persist/cache 2>/dev/null || true' \
'echo "β–Ά Backup done"' \
'' \
'# ── Step 4: Background sync every 60s ───────────────────────────────' \
'# Catches any pip installs or changes while server is running' \
'# /root/ β†’ /data/persist/ only, never the other way' \
'(' \
' while true; do' \
' sleep 60' \
' rsync -a --delete /root/venv/ /data/persist/venv/ 2>/dev/null' \
' rsync -a --delete /root/.cache/ /data/persist/cache/ 2>/dev/null' \
' done' \
') &' \
'' \
'# ── Step 5: apt.txt reinstall ────────────────────────────────────────' \
'APT_FILE="/data/apt.txt"' \
'if [ ! -f "$APT_FILE" ]; then touch "$APT_FILE"; fi' \
'if [ -s "$APT_FILE" ]; then' \
' echo "β–Ά Installing packages from apt.txt..."' \
' /usr/bin/apt-get update -qq' \
' while IFS= read -r pkg || [ -n "$pkg" ]; do' \
' pkg=$(echo "$pkg" | tr -d "[:space:]")' \
' [ -z "$pkg" ] && continue' \
' [ "${pkg#\#}" != "$pkg" ] && continue' \
' /usr/bin/apt-get install -y --no-install-recommends "$pkg" \' \
' && echo "βœ“ $pkg" \' \
' || echo "WARNING: Failed to install $pkg"' \
' done < "$APT_FILE"' \
' rm -rf /var/lib/apt/lists/*' \
'fi' \
'' \
'exec "$@"' \
> /usr/local/bin/docker-entrypoint.sh && \
chmod +x /usr/local/bin/docker-entrypoint.sh
# ── Runtime ───────────────────────────────────────────────────────────────────
WORKDIR /data
EXPOSE 7860
ENV PORT=7860
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["node", "/root/app/app.js"]