Skip to content

Instantly share code, notes, and snippets.

@stevecohenfr
Last active April 18, 2026 09:48
Show Gist options
  • Select an option

  • Save stevecohenfr/5f10b8b8806886dc9333240eb8211d73 to your computer and use it in GitHub Desktop.

Select an option

Save stevecohenfr/5f10b8b8806886dc9333240eb8211d73 to your computer and use it in GitHub Desktop.
DMCA-Tracker Worker setup script
#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────────────────────
# DMCA Monitor — Worker Setup
#
# One-liner install:
# bash <(curl -sL https://gist.githubusercontent.com/stevecohenfr/5f10b8b8806886dc9333240eb8211d73/raw/worker-setup.sh)
#
# Re-run to update or reconfigure.
# ──────────────────────────────────────────────────────────────────────────────
set -euo pipefail
INSTALL_DIR="${DMCA_WORKER_DIR:-$HOME/dmca-worker}"
GITHUB_TOKEN="${GITHUB_TOKEN:-}"
if [[ -n "$GITHUB_TOKEN" ]]; then
REPO="https://${GITHUB_TOKEN}@github.com/stevecohenfr/DMCA-Monitor.git"
else
REPO="https://github.com/stevecohenfr/DMCA-Monitor.git"
fi
BRANCH="main"
CONF="$INSTALL_DIR/.worker.env"
SERVICE_NAME="dmca-worker"
# ── Colors ────────────────────────────────────────────────────────────────────
G='\033[0;32m'; Y='\033[1;33m'; R='\033[0;31m'; B='\033[1;34m'; N='\033[0m'
log() { printf "${G}▸${N} %s\n" "$*"; }
warn() { printf "${Y}▸${N} %s\n" "$*"; }
die() { printf "${R}✗ %s${N}\n" "$*" >&2; exit 1; }
# ── Detect OS ─────────────────────────────────────────────────────────────────
detect_os() {
if [[ "$OSTYPE" == darwin* ]]; then
OS="macos"
elif [[ -f /etc/debian_version ]]; then
OS="debian"
elif [[ -f /etc/redhat-release ]] || [[ -f /etc/centos-release ]]; then
OS="rhel"
else
OS="unknown"
fi
}
# ── Ensure git ────────────────────────────────────────────────────────────────
ensure_git() {
command -v git &>/dev/null && return
log "Installation de git..."
case "$OS" in
debian) sudo apt-get update -qq && sudo apt-get install -y -qq git ;;
rhel) sudo yum install -y -q git ;;
macos) xcode-select --install 2>/dev/null || true ;;
*) die "Installe git manuellement" ;;
esac
}
# ── Ensure Node.js 20+ ───────────────────────────────────────────────────────
ensure_node() {
if command -v node &>/dev/null; then
local v; v=$(node -v | sed 's/v//' | cut -d. -f1)
if (( v >= 20 )); then
log "Node.js $(node -v) OK"
return
fi
warn "Node.js $(node -v) trop ancien (20+ requis)"
fi
log "Installation de Node.js 20..."
case "$OS" in
debian)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y -qq nodejs
;;
rhel)
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo yum install -y -q nodejs
;;
macos)
command -v brew &>/dev/null || die "Homebrew requis — https://brew.sh"
brew install node@20
brew link --overwrite node@20 2>/dev/null || true
;;
*) die "Installe Node.js 20+ manuellement" ;;
esac
log "Node.js $(node -v) installé"
}
# ── Clone / pull ──────────────────────────────────────────────────────────────
setup_code() {
if [[ -d "$INSTALL_DIR/.git" ]]; then
log "Mise a jour du code..."
git -C "$INSTALL_DIR" fetch --depth 1 origin "$BRANCH"
git -C "$INSTALL_DIR" reset --hard "origin/$BRANCH"
else
log "Telechargement du code..."
git clone --depth 1 -b "$BRANCH" "$REPO" "$INSTALL_DIR"
fi
}
# ── npm install + Playwright ──────────────────────────────────────────────────
install_deps() {
cd "$INSTALL_DIR"
log "Installation des dependances npm..."
npm ci --loglevel=warn 2>/dev/null || npm install --loglevel=warn
log "Installation de Playwright Chromium..."
if [[ "$OS" == "debian" || "$OS" == "rhel" ]]; then
# System deps needed on headless Linux
npx playwright install --with-deps chromium 2>/dev/null || {
sudo npx playwright install-deps chromium 2>/dev/null || true
npx playwright install chromium
}
else
npx playwright install chromium
fi
}
# ── Build TypeScript ──────────────────────────────────────────────────────────
build() {
cd "$INSTALL_DIR"
log "Compilation TypeScript..."
npx tsc 2>/dev/null || true
# cpx for views (not needed by worker, but part of the build script)
npm run build 2>/dev/null || true
[[ -f "$INSTALL_DIR/public/worker/index.js" ]] || die "Build echoue — public/worker/index.js absent"
log "Build OK"
}
# ── Configuration interactive ─────────────────────────────────────────────────
configure() {
local reconfigure=false
if [[ -f "$CONF" ]]; then
set -a; source "$CONF"; set +a
if [[ -n "${WORKER_API_KEY:-}" && -n "${WORKER_APP_URL:-}" ]]; then
echo ""
log "Configuration existante :"
log " URL : $WORKER_APP_URL"
log " Key : ${WORKER_API_KEY:0:12}..."
echo ""
read -rp " Reconfigurer ? [y/N] " ans
[[ "$ans" =~ ^[Yy] ]] && reconfigure=true || return 0
else
reconfigure=true
fi
else
reconfigure=true
fi
if $reconfigure; then
echo ""
printf "${B}━━━ Configuration du worker ━━━${N}\n"
echo ""
read -rp " URL de l'app (ex: https://dmca.example.com) : " app_url
read -rp " Cle API du worker : " api_key
echo ""
[[ -n "$app_url" && -n "$api_key" ]] || die "URL et cle API requises"
# Strip trailing slash
app_url="${app_url%/}"
cat > "$CONF" <<EOF
WORKER_APP_URL=$app_url
WORKER_API_KEY=$api_key
WORKER_BATCH_SIZE=10
WORKER_POLL_INTERVAL_MS=5000
EOF
log "Configuration sauvegardee dans $CONF"
fi
}
# ── systemd service (Linux) ───────────────────────────────────────────────────
setup_systemd() {
[[ "$OS" == "debian" || "$OS" == "rhel" ]] || return 1
command -v systemctl &>/dev/null || return 1
local node_bin; node_bin=$(command -v node)
local svc="/etc/systemd/system/${SERVICE_NAME}.service"
log "Configuration du service systemd..."
sudo tee "$svc" > /dev/null <<EOF
[Unit]
Description=DMCA Monitor Crawler Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$USER
WorkingDirectory=$INSTALL_DIR
EnvironmentFile=$CONF
ExecStart=$node_bin $INSTALL_DIR/public/worker/index.js
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=$SERVICE_NAME
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable "$SERVICE_NAME" --quiet
sudo systemctl restart "$SERVICE_NAME"
return 0
}
# ── Print result ──────────────────────────────────────────────────────────────
print_done_systemd() {
echo ""
printf "${G}━━━ Worker lance via systemd ━━━${N}\n"
echo ""
echo " Commandes utiles :"
echo " sudo systemctl status $SERVICE_NAME # statut"
echo " sudo journalctl -u $SERVICE_NAME -f # logs en temps reel"
echo " sudo systemctl restart $SERVICE_NAME # redemarrer"
echo " sudo systemctl stop $SERVICE_NAME # arreter"
echo ""
echo " Pour mettre a jour :"
echo " bash $INSTALL_DIR/worker-setup.sh"
echo ""
}
print_done_foreground() {
echo ""
printf "${G}━━━ Lancement du worker ━━━${N}\n"
echo ""
echo " Ctrl+C pour arreter"
echo " Relancer : cd $INSTALL_DIR && bash worker-setup.sh"
echo ""
}
# ══════════════════════════════════════════════════════════════════════════════
# Main
# ══════════════════════════════════════════════════════════════════════════════
echo ""
echo " ╔══════════════════════════════════════╗"
echo " ║ DMCA Monitor — Worker Setup ║"
echo " ╚══════════════════════════════════════╝"
echo ""
detect_os
log "OS detecte : $OS"
ensure_git
ensure_node
setup_code
install_deps
build
configure
if setup_systemd; then
print_done_systemd
else
print_done_foreground
cd "$INSTALL_DIR"
set -a; source "$CONF"; set +a
exec node public/worker/index.js
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment