Add arch_install.sh

This commit is contained in:
RomanNum3ral 2026-04-01 17:24:08 +00:00
parent aa1152f321
commit 238ff2d05c
1 changed files with 309 additions and 0 deletions

309
arch_install.sh Normal file
View File

@ -0,0 +1,309 @@
#!/usr/bin/env bash
#
# Arch Linux installer for:
# - R + RStudio Server (via AUR rstudio-server-bin)
# - JupyterHub + JupyterLab (native install, not TLJH)
#
# What it does:
# - installs system dependencies
# - installs and enables UFW
# - creates an admin UNIX account
# - installs R and RStudio Server
# - installs JupyterHub into /opt/jupyterhub
# - configures JupyterHub as a systemd service
#
# Run as root:
# sudo bash install_jhub_rstudio_arch.sh
#
set -Eeuo pipefail
# -----------------------------
# Configuration: EDIT THESE
# -----------------------------
ADMIN_USER="your_admin_user"
ADMIN_PASSWORD="your_admin_password"
JUPYTERHUB_PORT="8000"
RSTUDIO_PORT="8787"
JUPYTERHUB_VENV="/opt/jupyterhub"
JUPYTERHUB_CONFIG_DIR="/etc/jupyterhub"
JUPYTERHUB_CONFIG_FILE="${JUPYTERHUB_CONFIG_DIR}/jupyterhub_config.py"
JUPYTERHUB_SERVICE_FILE="/etc/systemd/system/jupyterhub.service"
USE_UFW="yes"
INSTALL_PARU="yes"
# -----------------------------
log() {
printf "\n\033[1;36m==> %s\033[0m\n" "$*"
}
warn() {
printf "\n\033[1;33m[WARN]\033[0m %s\n" "$*"
}
err() {
printf "\n\033[1;31m[ERROR]\033[0m %s\n" "$*" >&2
}
require_root() {
if [[ "${EUID}" -ne 0 ]]; then
err "Run this script as root (sudo)."
exit 1
fi
}
detect_real_user() {
if [[ -n "${SUDO_USER:-}" && "${SUDO_USER}" != "root" ]]; then
REAL_USER="${SUDO_USER}"
else
REAL_USER="$(logname 2>/dev/null || true)"
if [[ -z "${REAL_USER}" || "${REAL_USER}" == "root" ]]; then
err "Could not determine the non-root user that should build AUR packages."
err "Run with: sudo bash $0 from your normal user session."
exit 1
fi
fi
REAL_HOME="$(getent passwd "${REAL_USER}" | cut -d: -f6)"
if [[ -z "${REAL_HOME}" || ! -d "${REAL_HOME}" ]]; then
err "Could not determine home directory for ${REAL_USER}."
exit 1
fi
}
install_base_packages() {
log "Updating pacman and installing base packages"
pacman -Syu --noconfirm
pacman -S --needed --noconfirm \
base-devel \
git \
curl \
wget \
sudo \
ufw \
nginx \
python \
python-pip \
python-virtualenv \
nodejs \
npm \
sqlite \
pam \
shadow \
which \
r \
gcc-fortran
}
configure_firewall() {
if [[ "${USE_UFW}" != "yes" ]]; then
warn "Skipping UFW configuration"
return
fi
log "Configuring UFW firewall"
systemctl enable --now ufw
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow "${JUPYTERHUB_PORT}"/tcp
ufw allow "${RSTUDIO_PORT}"/tcp
ufw --force enable
}
create_admin_user() {
log "Creating admin system user if needed"
if ! id "${ADMIN_USER}" >/dev/null 2>&1; then
useradd -m -s /bin/bash "${ADMIN_USER}"
echo "${ADMIN_USER}:${ADMIN_PASSWORD}" | chpasswd
usermod -aG wheel "${ADMIN_USER}"
log "Created user ${ADMIN_USER}"
else
warn "User ${ADMIN_USER} already exists; updating password"
echo "${ADMIN_USER}:${ADMIN_PASSWORD}" | chpasswd
usermod -aG wheel "${ADMIN_USER}" || true
fi
}
install_paru() {
if command -v paru >/dev/null 2>&1; then
log "paru already installed"
return
fi
if [[ "${INSTALL_PARU}" != "yes" ]]; then
err "paru is not installed and INSTALL_PARU=no"
exit 1
fi
log "Installing paru AUR helper as ${REAL_USER}"
local build_dir="${REAL_HOME}/paru-build"
rm -rf "${build_dir}"
sudo -u "${REAL_USER}" bash -lc "
set -Eeuo pipefail
cd '${REAL_HOME}'
git clone https://aur.archlinux.org/paru.git '${build_dir}'
cd '${build_dir}'
makepkg -si --noconfirm
"
rm -rf "${build_dir}"
}
install_rstudio_server() {
log "Installing RStudio Server from AUR (rstudio-server-bin)"
sudo -u "${REAL_USER}" bash -lc "
set -Eeuo pipefail
paru -S --needed --noconfirm rstudio-server-bin
"
mkdir -p /etc/rstudio
if ! grep -q '^rsession-which-r=' /etc/rstudio/rserver.conf 2>/dev/null; then
echo 'rsession-which-r=/usr/bin/R' >> /etc/rstudio/rserver.conf
else
sed -i 's|^rsession-which-r=.*|rsession-which-r=/usr/bin/R|' /etc/rstudio/rserver.conf
fi
mkdir -p /var/lib/rstudio-server
chown -R root:root /var/lib/rstudio-server
# Some installs need an explicit PAM service file present
if [[ ! -e /etc/pam.d/rstudio ]]; then
cat >/etc/pam.d/rstudio <<'EOF'
auth include system-login
account include system-login
password include system-login
session include system-login
EOF
fi
systemctl enable --now rstudio-server
}
install_jupyterhub() {
log "Installing JupyterHub in virtual environment"
mkdir -p "${JUPYTERHUB_VENV}"
python -m venv "${JUPYTERHUB_VENV}"
"${JUPYTERHUB_VENV}/bin/pip" install --upgrade pip wheel setuptools
"${JUPYTERHUB_VENV}/bin/pip" install \
jupyterhub \
jupyterlab \
notebook
npm install -g configurable-http-proxy
}
configure_jupyterhub() {
log "Configuring JupyterHub"
mkdir -p "${JUPYTERHUB_CONFIG_DIR}"
cat >"${JUPYTERHUB_CONFIG_FILE}" <<EOF
c = get_config()
c.JupyterHub.bind_url = 'http://0.0.0.0:${JUPYTERHUB_PORT}'
c.JupyterHub.hub_ip = '127.0.0.1'
c.JupyterHub.spawner_class = 'jupyterhub.spawner.LocalProcessSpawner'
c.Authenticator.admin_users = {'${ADMIN_USER}'}
c.JupyterHub.admin_access = True
c.Spawner.default_url = '/lab'
# Use system users + PAM authentication
c.JupyterHub.authenticator_class = 'jupyterhub.auth.PAMAuthenticator'
# Keep runtime state in standard locations
c.JupyterHub.cookie_secret_file = '${JUPYTERHUB_CONFIG_DIR}/jupyterhub_cookie_secret'
c.JupyterHub.db_url = 'sqlite:///${JUPYTERHUB_CONFIG_DIR}/jupyterhub.sqlite'
c.ConfigurableHTTPProxy.command = 'configurable-http-proxy'
EOF
if [[ ! -f "${JUPYTERHUB_CONFIG_DIR}/jupyterhub_cookie_secret" ]]; then
umask 077
head -c 32 /dev/urandom > "${JUPYTERHUB_CONFIG_DIR}/jupyterhub_cookie_secret"
fi
chmod 600 "${JUPYTERHUB_CONFIG_DIR}/jupyterhub_cookie_secret"
cat >"${JUPYTERHUB_SERVICE_FILE}" <<EOF
[Unit]
Description=JupyterHub
After=network.target
[Service]
Type=simple
ExecStart=${JUPYTERHUB_VENV}/bin/jupyterhub -f ${JUPYTERHUB_CONFIG_FILE}
WorkingDirectory=${JUPYTERHUB_CONFIG_DIR}
Restart=always
RestartSec=10
User=root
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now jupyterhub
}
verify_services() {
log "Verifying services"
systemctl --no-pager --full status rstudio-server || true
systemctl --no-pager --full status jupyterhub || true
systemctl --no-pager --full status ufw || true
ss -tulpn | grep -E ":(${JUPYTERHUB_PORT}|${RSTUDIO_PORT}|80|443)\b" || true
}
print_summary() {
local server_ip
server_ip="$(hostname -I | awk '{print $1}')"
echo
echo "=========================================================="
echo "✅ Installation Summary"
echo "=========================================================="
echo "JupyterHub is installed and running at:"
echo " http://${server_ip}:${JUPYTERHUB_PORT}/"
echo
echo "RStudio Server is installed and running at:"
echo " http://${server_ip}:${RSTUDIO_PORT}/"
echo
echo "Login user:"
echo " ${ADMIN_USER}"
echo
echo "Important notes:"
echo " - JupyterHub on this script is a native Arch install, not TLJH."
echo " - RStudio Server was installed from the AUR package rstudio-server-bin."
echo " - The same UNIX account (${ADMIN_USER}) works for both services."
echo "=========================================================="
}
main() {
require_root
detect_real_user
install_base_packages
configure_firewall
create_admin_user
install_paru
install_rstudio_server
install_jupyterhub
configure_jupyterhub
verify_services
print_summary
}
main "$@"