diff --git a/README.md b/README.md index e2929de..6186aec 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This project packages the official PulseChain clients in Docker Compose with a s ## Quick start -**Requirements:** Linux (Ubuntu 22.04 / 24.04 or Debian recommended; amd64 or arm64), `sudo`, outbound internet, and a large SSD mounted where `/blockchain` will live. +**Requirements:** Linux (Ubuntu 22.04 / 24.04, Debian, or [Omarchy](https://omarchy.org); amd64 or arm64), `sudo`, outbound internet, and a large SSD mounted where `/blockchain` will live. ```bash git clone https://github.com/DavidFeder/pulsechain-rpc-node.git @@ -26,10 +26,11 @@ chmod +x install.sh The installer will: -1. Install Docker Engine and the Compose plugin if they are missing (Ubuntu/Debian) -2. Create `/blockchain` (with `execution` / `consensus` subdirs) and generate a JWT secret if needed -3. Pull the official images and start both containers -4. Print your LAN IP and wallet connection settings +1. Install Docker Engine and the Compose plugin if they are missing (Ubuntu/Debian via Docker CE; Omarchy/Arch via `omarchy-pkg-add` or pacman) +2. Enable Docker to start on boot (needed so the node comes back after reboot; Omarchy otherwise only socket-activates Docker) +3. Create `/blockchain` (with `execution` / `consensus` subdirs) and generate a JWT secret if needed +4. Pull the official images and start both containers +5. Print your LAN IP and wallet connection settings --- @@ -85,11 +86,32 @@ LAN binding is intentional so phones and other machines on the same network can --- +## Omarchy Linux + +[Omarchy](https://omarchy.org) is Arch-based and already ships Docker, Compose, and UFW on typical installs. `./install.sh` detects it even when `/etc/os-release` still says `ID=arch`. + +What the installer does on Omarchy: + +- Installs `docker`, `docker-compose`, `docker-buildx`, and `openssl` if missing, using `omarchy-pkg-add` when that command exists (otherwise `pacman -S --needed`). It does **not** run `pacman -Syu`, which Omarchy blocks in favor of `omarchy update`. +- Enables `docker.service` on boot. Omarchy’s default is `docker.socket` only; without a running daemon, `restart: unless-stopped` containers would not return after a reboot. +- Adds UFW rules for P2P (open) and wallet RPC (private ranges). Omarchy’s first-run firewall is deny-incoming, so those P2P rules are what allow inbound peers. + +```bash +git clone https://github.com/DavidFeder/pulsechain-rpc-node.git +cd pulsechain-rpc-node +chmod +x *.sh +./install.sh +``` + +If Docker was just added to your user group, log out and back in (or reboot) before using `./status.sh` without sudo. + +--- + ## Installation ### Prerequisites -- Linux host (Ubuntu 22.04 / 24.04 or Debian recommended; **amd64 or arm64**) +- Linux host (Ubuntu 22.04 / 24.04, Debian, or [Omarchy](https://omarchy.org); **amd64 or arm64**). Vanilla Arch works with the same pacman path. - `sudo` privileges - Sufficient free space for `/blockchain` - Outbound connectivity to pull images and sync with the network @@ -334,7 +356,7 @@ Optional variables (`DATA_DIR`, ports, image pins) are documented in `.env.examp | Issue | Suggested action | |-------|------------------| -| Docker permission denied | Log out and back in after install (docker group membership), or prefix commands with `sudo` | +| Docker permission denied | Log out and back in after install (docker group membership), or prefix commands with `sudo`. On Omarchy this is common until the session picks up the `docker` group. | | `address already in use` / crash loop | Another node is using ports 8545, 8546, 3500, 4000, or 8551. Stop the other process or change ports in `docker-compose.yml` | | Beacon cannot find execution client | Confirm both containers are running and that `/blockchain/jwt.hex` exists and is shared by both | | JWT / `401 Unauthorized` to execution | Ensure only one execution client is on port 8551 and both services use the same `/blockchain/jwt.hex`. The file must be 64 hex characters with **no newline**. Keep the host clock in sync (NTP / `timedatectl`); JWT `iat` skew also returns 401. | diff --git a/common.sh b/common.sh index 871c885..a74b63c 100755 --- a/common.sh +++ b/common.sh @@ -266,3 +266,36 @@ confirm_yes() { *) return 1 ;; esac } + +os_is_debian_family() { + local os_id="${1:-}" + case "${os_id}" in + ubuntu|debian|linuxmint|pop) return 0 ;; + *) return 1 ;; + esac +} + +# Omarchy (https://omarchy.org) is Arch-based. Stock images still report ID=arch, +# so also look for Omarchy tools and install paths. +os_is_omarchy() { + local os_id="${1:-}" + [[ "${os_id}" == "omarchy" ]] && return 0 + command -v omarchy-pkg-add >/dev/null 2>&1 && return 0 + command -v omarchy >/dev/null 2>&1 && return 0 + [[ -f /etc/profile.d/omarchy.sh ]] && return 0 + [[ -d /usr/share/omarchy ]] && return 0 + [[ -d "${HOME}/.local/share/omarchy" ]] && return 0 + [[ -n "${OMARCHY_PATH:-}" && -e "${OMARCHY_PATH}" ]] && return 0 + return 1 +} + +os_is_arch_family() { + local os_id="${1:-}" + local id_like="${2:-}" + case "${os_id}" in + arch|omarchy) return 0 ;; + esac + [[ "${id_like}" == *arch* ]] && return 0 + [[ -f /etc/arch-release ]] && return 0 + return 1 +} diff --git a/install.sh b/install.sh index 9200e60..13a155e 100755 --- a/install.sh +++ b/install.sh @@ -56,25 +56,41 @@ else fi # --------------------------------------------------------------------------- -# 2. Detect OS (Ubuntu/Debian focused) +# 2. Detect OS (Ubuntu/Debian, Omarchy, Arch) # --------------------------------------------------------------------------- if [[ -f /etc/os-release ]]; then # shellcheck source=/dev/null . /etc/os-release OS_ID="${ID:-unknown}" + OS_ID_LIKE="${ID_LIKE:-}" else OS_ID="unknown" + OS_ID_LIKE="" fi -case "${OS_ID}" in - ubuntu|debian|linuxmint|pop) - ok "Detected Debian-family OS: ${OS_ID}" - ;; - *) - warn "OS '${OS_ID}' is not Ubuntu/Debian. Docker install may need to be done manually." - warn "If Docker + Compose are already installed, the rest of this script should still work." - ;; -esac +if os_is_omarchy "${OS_ID}"; then + ok "Detected Omarchy Linux (Arch-based)" +elif os_is_debian_family "${OS_ID}"; then + ok "Detected Debian-family OS: ${OS_ID}" +elif os_is_arch_family "${OS_ID}" "${OS_ID_LIKE}"; then + ok "Detected Arch-based OS: ${OS_ID}" +else + warn "OS '${OS_ID}' is not Ubuntu/Debian or Omarchy/Arch. Docker install may need to be done manually." + warn "If Docker + Compose are already installed, the rest of this script should still work." +fi + +install_arch_packages() { + if command -v omarchy-pkg-add >/dev/null 2>&1; then + # Official Omarchy helper; avoids -Syu so the ALPM update-guard is not tripped. + omarchy-pkg-add "$@" || die "omarchy-pkg-add failed for: $*" + return 0 + fi + if ! command -v pacman >/dev/null 2>&1; then + die "pacman not found. Install Docker and openssl manually, then re-run." + fi + # Install only (no -Syu). Omarchy blocks unattended system upgrades via ALPM guard. + $SUDO pacman -S --noconfirm --needed "$@" || die "pacman failed to install: $*" +} # --------------------------------------------------------------------------- # 3. Install Docker + Compose plugin if missing @@ -91,8 +107,7 @@ fi if [[ "${need_docker_install}" == true ]]; then info "Installing Docker Engine + Compose plugin..." - case "${OS_ID}" in - ubuntu|debian|linuxmint|pop) + if os_is_debian_family "${OS_ID}"; then $SUDO apt-get update -y # Distro docker.io / containerd packages conflict with Docker CE. $SUDO apt-get remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc || true @@ -125,27 +140,47 @@ if [[ "${need_docker_install}" == true ]]; then else die "Docker was installed but the daemon is not responding. Try: sudo systemctl status docker" fi - ;; - *) - die "Automatic Docker install is only supported on Ubuntu/Debian. Install Docker manually: https://docs.docker.com/engine/install/ then re-run this script." - ;; - esac + elif os_is_omarchy "${OS_ID}" || os_is_arch_family "${OS_ID}" "${OS_ID_LIKE}"; then + # Arch packages: docker-compose is the v2 CLI plugin (`docker compose`). + # Do not use pacman -Syu — Omarchy's ALPM guard aborts unattended sysupgrades. + install_arch_packages docker docker-compose docker-buildx openssl + # Omarchy enables docker.socket (on-demand). A node needs dockerd at boot + # so unless-stopped containers come back after reboot. + $SUDO systemctl enable docker.socket 2>/dev/null || true + $SUDO systemctl enable --now docker + info "Waiting for the Docker daemon..." + if wait_for_docker; then + ok "Docker installed (Omarchy/Arch packages)." + else + die "Docker was installed but the daemon is not responding. Try: sudo systemctl status docker" + fi + else + die "Automatic Docker install is only supported on Ubuntu/Debian and Omarchy/Arch. Install Docker manually: https://docs.docker.com/engine/install/ then re-run this script." + fi else ok "Docker and Compose plugin already available." fi +# Full nodes must start Docker on boot (Omarchy defaults to socket-activation only). +if command -v systemctl >/dev/null 2>&1; then + $SUDO systemctl enable docker.socket 2>/dev/null || true + $SUDO systemctl enable docker 2>/dev/null || true + if ! $SUDO systemctl is-active --quiet docker 2>/dev/null; then + $SUDO systemctl start docker 2>/dev/null || true + fi +fi + # Ensure openssl for JWT generation if ! command -v openssl >/dev/null 2>&1; then info "Installing openssl..." - case "${OS_ID}" in - ubuntu|debian|linuxmint|pop) + if os_is_debian_family "${OS_ID}"; then $SUDO apt-get update -y $SUDO apt-get install -y openssl || die "Please install openssl and re-run." - ;; - *) + elif os_is_omarchy "${OS_ID}" || os_is_arch_family "${OS_ID}" "${OS_ID_LIKE}"; then + install_arch_packages openssl + else die "openssl is required. Please install it and re-run." - ;; - esac + fi fi # Allow the invoking user to run docker without sudo (best-effort; needs re-login) @@ -375,15 +410,24 @@ if command -v ufw >/dev/null 2>&1; then warn "If UFW is not enabled yet, the rules are stored and apply after: sudo ufw enable" fi echo "" - warn "IMPORTANT about UFW:" - warn " The rules have been added, but UFW may still be inactive." - warn " To enable the firewall safely (after confirming SSH still works):" - warn " sudo ufw allow OpenSSH" - warn " sudo ufw enable" - warn " Then check: sudo ufw status numbered" - warn " If your home network uses a different subnet, edit the rules accordingly." - warn " IPv4 rules do not cover IPv6 — if the host has global IPv6, add matching rules or disable it." - warn " 10.0.0.0/8 on a cloud VPC is the VPC, not a home LAN — tighten that range on VPS hosts." + if ufw_is_active; then + ok "UFW is already active — new PulseChain rules apply immediately." + if os_is_omarchy "${OS_ID}"; then + info "Omarchy defaults to deny-incoming; inbound P2P (30303/13000/12000) is now allowed." + fi + warn "If your LAN uses a different subnet than 10/8, 172.16/12, or 192.168/16, edit the RPC rules." + warn "IPv4 rules do not cover IPv6 — if the host has global IPv6, add matching rules or disable it." + else + warn "IMPORTANT about UFW:" + warn " The rules have been added, but UFW may still be inactive." + warn " To enable the firewall safely (after confirming SSH still works):" + warn " sudo ufw allow OpenSSH" + warn " sudo ufw enable" + warn " Then check: sudo ufw status numbered" + warn " If your home network uses a different subnet, edit the rules accordingly." + warn " IPv4 rules do not cover IPv6 — if the host has global IPv6, add matching rules or disable it." + warn " 10.0.0.0/8 on a cloud VPC is the VPC, not a home LAN — tighten that range on VPS hosts." + fi else info "UFW not found — assuming no software firewall (or it is managed elsewhere). Skipping firewall rules." fi diff --git a/tests/test_common.sh b/tests/test_common.sh index cfc4248..2909285 100755 --- a/tests/test_common.sh +++ b/tests/test_common.sh @@ -213,6 +213,54 @@ if grep -q 'effective_install_user' "${ROOT}/install.sh"; then else fail "install.sh should not rely on possibly-empty USER" fi +if grep -q 'omarchy-pkg-add' "${ROOT}/install.sh" && grep -q 'os_is_omarchy' "${ROOT}/install.sh"; then + pass "install.sh has an Omarchy/Arch package path" +else + fail "install.sh should install Docker via omarchy-pkg-add or pacman" +fi +if grep -q 'systemctl enable docker' "${ROOT}/install.sh"; then + pass "install.sh enables docker.service on boot" +else + fail "install.sh should enable docker.service so Omarchy nodes survive reboot" +fi +if grep -E '^[[:space:]]*[^#[:space:]].*pacman[[:space:]].*-Syu' "${ROOT}/install.sh"; then + fail "install.sh must not run pacman -Syu (Omarchy ALPM guard)" +else + pass "install.sh does not run pacman -Syu" +fi + +# Distro detection helpers +if os_is_debian_family ubuntu && os_is_debian_family debian && os_is_debian_family linuxmint && os_is_debian_family pop; then + pass "os_is_debian_family accepts Ubuntu/Debian/Mint/Pop" +else + fail "os_is_debian_family rejected a Debian-family id" +fi +if os_is_debian_family arch || os_is_debian_family omarchy; then + fail "os_is_debian_family accepted an Arch id" +else + pass "os_is_debian_family rejects arch/omarchy" +fi +if os_is_omarchy omarchy; then + pass "os_is_omarchy accepts ID=omarchy" +else + fail "os_is_omarchy rejected ID=omarchy" +fi +if os_is_arch_family arch "" && os_is_arch_family omarchy "" && os_is_arch_family cachyos "arch"; then + pass "os_is_arch_family accepts arch, omarchy, and ID_LIKE=arch" +else + fail "os_is_arch_family rejected an Arch-family id" +fi +if os_is_arch_family ubuntu ""; then + fail "os_is_arch_family accepted ubuntu" +else + pass "os_is_arch_family rejects ubuntu" +fi + +if grep -q 'Omarchy' "${ROOT}/README.md"; then + pass "README documents Omarchy Linux" +else + fail "README should document Omarchy support" +fi # status.sh prints wallet URL via detect_lan_ip if grep -q 'detect_lan_ip' "${ROOT}/status.sh"; then