#!/bin/sh # Installs or updates Pingo on a server (a VPS, a machine at home): # curl -fsSL https://pingoai.app/install.sh | sh # # What it does, and nothing else: checks for Node.js 24 or newer, downloads Pingo's server # (checked against its SHA-256), installs its packages with npm, and, where systemd is there # and this can use it, sets Pingo up as a service that starts with the machine. Run as root, # it makes a user named "pingo" and installs for that user: the agents run commands as # whoever runs Pingo, and that should not be root. Your data lives in ~/.pingo-server of # that user and is never touched by an update. # # PINGO_DIR: where the program goes (default: ~/pingo). PINGO_NO_SERVICE=1: no service. set -e VERSION="0.2.29" SHA256="780d65229b93fb9ce689a4e95922304c67c6cd6f87738e8a14e2d34c390ef2be" BASE="${PINGO_BASE:-https://pingoai.app}" case "${LANG:-}${LC_ALL:-}" in *pt*) PT=1 ;; *) PT= ;; esac say() { if [ -n "$PT" ]; then echo "$1"; else echo "$2"; fi; } fail() { say "$1" "$2" >&2; exit 1; } have() { command -v "$1" >/dev/null 2>&1; } for tool in curl tar; do have "$tool" || fail "Falta o $tool neste servidor." "This server is missing $tool."; done if ! have node || [ "$(node -p 'Number(process.versions.node.split(".")[0])' 2>/dev/null || echo 0)" -lt 24 ]; then say "O Pingo precisa do Node.js 24 ou mais novo. Em Ubuntu ou Debian, instale com:" "Pingo needs Node.js 24 or newer. On Ubuntu or Debian, install it with:" echo " curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - && sudo apt-get install -y nodejs" say "Depois rode este instalador de novo." "Then run this installer again." exit 1 fi have npm || fail "Falta o npm (vem com o Node.js)." "npm is missing (it comes with Node.js)." # As root: a user of Pingo's own, and the rest of this script as that user. if [ "$(id -u)" = 0 ] && [ -z "${PINGO_AS_ROOT:-}" ]; then have useradd || fail "Rode como um usuário comum, não como root." "Run this as a regular user, not as root." id pingo >/dev/null 2>&1 || useradd --create-home --shell /bin/bash pingo say "Instalando para o usuário 'pingo' (os agentes não devem rodar como root)…" "Installing for the user 'pingo' (agents should not run as root)…" SELF=$(mktemp) curl -fsSL "$BASE/install.sh" -o "$SELF" chmod 644 "$SELF" su - pingo -c "PINGO_BASE='$BASE' PINGO_NO_SERVICE=1 sh '$SELF'" rm -f "$SELF" HOME_DIR=$(getent passwd pingo | cut -d: -f6) RUN_USER=pingo DIR="$HOME_DIR/pingo" else RUN_USER=$(id -un) DIR="${PINGO_DIR:-$HOME/pingo}" TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT say "Baixando o Pingo $VERSION…" "Downloading Pingo $VERSION…" curl -fL --progress-bar -o "$TMP/pingo.tar.gz" "$BASE/downloads/pingo-server-$VERSION.tar.gz" if have sha256sum; then GOT=$(sha256sum "$TMP/pingo.tar.gz" | cut -d' ' -f1); else GOT=$(shasum -a 256 "$TMP/pingo.tar.gz" | cut -d' ' -f1); fi [ "$GOT" = "$SHA256" ] || fail "O arquivo baixado não confere com o esperado. Nada foi instalado." "The downloaded file does not match what was expected. Nothing was installed." tar -xzf "$TMP/pingo.tar.gz" -C "$TMP" mkdir -p "$DIR" rm -rf "$DIR/out" # the program only: the data is in ~/.pingo-server cp -R "$TMP/pingo-server/." "$DIR/" say "Instalando os pacotes…" "Installing its packages…" (cd "$DIR" && npm ci --omit=dev --ignore-scripts --no-audit --no-fund >/dev/null) fi NODE=$(command -v node) SERVICE= if [ -z "${PINGO_NO_SERVICE:-}" ] && have systemctl && [ -d /etc/systemd/system ]; then SUDO= if [ "$(id -u)" != 0 ]; then if have sudo && sudo -n true 2>/dev/null; then SUDO=sudo; else SUDO=none; fi; fi if [ "$SUDO" != none ]; then $SUDO tee /etc/systemd/system/pingo.service >/dev/null </dev/null 2>&1 || true $SUDO systemctl restart pingo SERVICE=1 fi fi [ -n "${PINGO_NO_SERVICE:-}" ] && exit 0 echo if [ -n "$SERVICE" ]; then say "Pingo $VERSION instalado e rodando como serviço (pingo.service)." "Pingo $VERSION is installed and running as a service (pingo.service)." sleep 2 say "O link para entrar:" "The link to sign in:" if [ "$RUN_USER" = "$(id -un)" ]; then (cd "$DIR" && "$NODE" out/main/server.js link) || true; else su - "$RUN_USER" -c "cd '$DIR' && '$NODE' out/main/server.js link" || true; fi else say "Pingo $VERSION instalado em $DIR. Para ligar:" "Pingo $VERSION is installed in $DIR. To start it:" echo " cd $DIR && node out/main/server.js" say "E, em outro terminal, o link para entrar:" "And, in another terminal, the link to sign in:" echo " cd $DIR && node out/main/server.js link" fi echo say "O Pingo só atende neste servidor (127.0.0.1:7337). Para abrir do seu computador, um túnel SSH basta:" "Pingo only answers on this server (127.0.0.1:7337). To open it from your computer, an SSH tunnel is enough:" echo " ssh -L 7337:127.0.0.1:7337 $RUN_USER@" say "Para um endereço próprio com HTTPS, veja o guia do servidor." "For an address of its own with HTTPS, see the server guide."