136 lines
3.7 KiB
Bash
Executable File
136 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
APP_USER="${PYTORRENT_USER:-pytorrent}"
|
|
APP_DIR="${PYTORRENT_APP_DIR:-/opt/pytorrent}"
|
|
SERVICE_NAME="${PYTORRENT_SERVICE_NAME:-pytorrent}"
|
|
PYTHON_BIN="${PYTHON_BIN:-python3}"
|
|
PYTORRENT_HOST_VALUE="${PYTORRENT_HOST:-0.0.0.0}"
|
|
PYTORRENT_PORT_VALUE="${PYTORRENT_PORT:-8090}"
|
|
PYTORRENT_LOG_DIR_VALUE="${PYTORRENT_LOG_DIR:-/data/logs}"
|
|
PYTORRENT_LOG_RETENTION_HOURS_VALUE="${PYTORRENT_LOG_RETENTION_HOURS:-24}"
|
|
PKG_MANAGER="$(command -v dnf || command -v yum || true)"
|
|
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|
echo "Run as root: sudo $0" >&2
|
|
exit 1
|
|
fi
|
|
if [[ -z "${PKG_MANAGER}" ]]; then
|
|
echo "dnf or yum is required." >&2
|
|
exit 1
|
|
fi
|
|
|
|
"${PKG_MANAGER}" install -y \
|
|
ca-certificates \
|
|
curl \
|
|
git \
|
|
rsync \
|
|
gcc \
|
|
python3 \
|
|
python3-devel \
|
|
python3-pip
|
|
|
|
if ! id -u "${APP_USER}" >/dev/null 2>&1; then
|
|
useradd \
|
|
--system \
|
|
--create-home \
|
|
--home-dir "/var/lib/${APP_USER}" \
|
|
--shell /sbin/nologin \
|
|
"${APP_USER}"
|
|
fi
|
|
|
|
mkdir -p "${APP_DIR}"
|
|
|
|
rsync -a --delete \
|
|
--exclude '.git' \
|
|
--exclude 'venv' \
|
|
--exclude '__pycache__' \
|
|
--exclude '*.pyc' \
|
|
./ "${APP_DIR}/"
|
|
|
|
cd "${APP_DIR}"
|
|
|
|
"${PYTHON_BIN}" -m venv venv
|
|
venv/bin/pip install --upgrade pip wheel
|
|
venv/bin/pip install -r requirements.txt
|
|
|
|
mkdir -p data instance logs data/logs
|
|
chown -R "${APP_USER}:${APP_USER}" "${APP_DIR}" "/var/lib/${APP_USER}"
|
|
|
|
|
|
upsert_env_value() {
|
|
local key="$1"
|
|
local value="$2"
|
|
local file="${3:-.env}"
|
|
touch "${file}"
|
|
if grep -qE "^${key}=" "${file}"; then
|
|
sed -i "s|^${key}=.*|${key}=${value}|" "${file}"
|
|
else
|
|
printf '%s=%s\n' "${key}" "${value}" >> "${file}"
|
|
fi
|
|
}
|
|
|
|
if [[ ! -f .env && -f .env.example ]]; then
|
|
cp .env.example .env
|
|
python3 - .env <<'PY'
|
|
from pathlib import Path
|
|
import secrets
|
|
import sys
|
|
path = Path(sys.argv[1])
|
|
text = path.read_text()
|
|
if "PYTORRENT_SECRET_KEY=change-me" in text:
|
|
text = text.replace("PYTORRENT_SECRET_KEY=change-me", "PYTORRENT_SECRET_KEY=" + secrets.token_urlsafe(48))
|
|
path.write_text(text)
|
|
PY
|
|
chown "${APP_USER}:${APP_USER}" .env
|
|
fi
|
|
|
|
# Keep systemd service config aligned with installer overrides.
|
|
upsert_env_value "PYTORRENT_HOST" "${PYTORRENT_HOST_VALUE}" .env
|
|
upsert_env_value "PYTORRENT_PORT" "${PYTORRENT_PORT_VALUE}" .env
|
|
upsert_env_value "PYTORRENT_LOG_DIR" "${PYTORRENT_LOG_DIR_VALUE}" .env
|
|
upsert_env_value "PYTORRENT_LOG_RETENTION_HOURS" "${PYTORRENT_LOG_RETENTION_HOURS_VALUE}" .env
|
|
mkdir -p "${PYTORRENT_LOG_DIR_VALUE}"
|
|
chown -R "${APP_USER}:${APP_USER}" "${PYTORRENT_LOG_DIR_VALUE}" || true
|
|
chown "${APP_USER}:${APP_USER}" .env
|
|
|
|
if [[ -f scripts/download_frontend_libs.py ]]; then
|
|
sudo -u "${APP_USER}" "${APP_DIR}/venv/bin/python" scripts/download_frontend_libs.py || true
|
|
fi
|
|
|
|
if [[ -f scripts/download_geoip.sh ]]; then
|
|
sudo -u "${APP_USER}" bash scripts/download_geoip.sh || true
|
|
fi
|
|
|
|
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<SERVICE
|
|
[Unit]
|
|
Description=pyTorrent Web UI
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=${APP_USER}
|
|
Group=${APP_USER}
|
|
WorkingDirectory=${APP_DIR}
|
|
Environment="PYTHONUNBUFFERED=1"
|
|
EnvironmentFile=${APP_DIR}/.env
|
|
ExecStart=${APP_DIR}/venv/bin/gunicorn -c ${APP_DIR}/gunicorn.conf.py --worker-class gthread --workers 1 --threads 32 --bind \${PYTORRENT_HOST}:\${PYTORRENT_PORT} --access-logfile - --error-logfile - wsgi:app
|
|
Restart=always
|
|
RestartSec=3
|
|
KillSignal=SIGINT
|
|
TimeoutStopSec=20
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
SERVICE
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable "${SERVICE_NAME}"
|
|
systemctl restart "${SERVICE_NAME}"
|
|
systemctl status "${SERVICE_NAME}" --no-pager --lines=20 || true
|
|
|
|
echo "pyTorrent installed in ${APP_DIR}. Service: ${SERVICE_NAME}."
|