Install and first-run setup, from a fresh Ubuntu host to a synced, mining stack. The pithead
script drives every step.
This is the DIY path: your host, your OS. To dedicate a machine and skip the host management entirely, write the appliance image to a USB stick instead — same stack, same dashboard, no Linux to set up.
TL;DR
curl -fsSL https://github.com/p2pool-starter-stack/pithead/releases/latest/download/pithead.tar.gz | tar xz cd pithead ./pithead setupHave a Monero payout address ready; Tari merge-mining is an optional beta, off unless you say yes, and has its own payout address. Let it run, then open the dashboard at
https://<your-hostname>.
| Requirement | Recommendation |
|---|---|
| Operating system | Ubuntu Server 24.04 LTS is the supported platform. Other Linux distributions may work but aren't supported. macOS is deprecated as of 2026-09-10 and is not tested; the installer refuses it. |
| CPU | A processor with AVX2 support for RandomX performance. |
| RAM | 16 GB minimum with HugePages enabled (~6 GB is reserved for RandomX); 32 GB for a full node or long uptimes. |
| Disk | A Monero node synced from genesis with pruning enabled consumed 285.8 GB in September 2026. Buy at least a 600 GB SSD with both Monero and Tari local, in either prune mode, or 370 GB with Tari remote. Both chains keep growing, so a 2–4 TB drive is the set-and-forget choice. Running either node on another machine drops its share — see Running a node elsewhere. |
| Software | Docker Engine, Docker Compose V2, jq, openssl, and python3. |
📐 Sizing guidance for the stack host — minimum vs. recommended specs, plus ways to run leaner — is in Hardware Requirements. Miner specs live in RigForge.
🔎
setupchecks this for you. Before it starts anything,./pithead setupruns a best-effort pre-flight on free disk and total RAM. If free disk is below the enforced budget (528 GiB with both nodes local) or RAM is below the 16 GB floor, it prints a warning. The disk figure follows the node modes you configured; the 16 GB RAM warning fires regardless. It never blocks setup, so you can proceed on a smaller host at your own risk. See Hardware Requirements.
You don't have to install the software dependencies yourself. setup checks for them and, on
Ubuntu, offers to install anything missing. To do it manually:
sudo apt update && sudo apt install -y jq docker.io docker-compose-v2 openssl python3On an unsupported OS, or if dependency detection misfires on an unusual setup, run setup with
--skip-deps to bypass the check entirely.
Download the latest release. This pulls the published, tested images (no local build), so the dashboard shows the real version and the update-checker works:
curl -fsSL https://github.com/p2pool-starter-stack/pithead/releases/latest/download/pithead.tar.gz | tar xz
cd pitheadLeave config.json absent to use the setup wizard. Have a Monero payout address ready, and a
Tari payout address if you enable merge-mining (Tari wallets are sometimes labeled Minotari).
For a manual configuration, copy config.minimal.json or config.reference.json to config.json
and edit it before setup; these files inherit the reference defaults rather than the wizard's
new-install choices.
To build the images locally instead of pulling the published ones, e.g. to develop or modify the
stack, clone the repo. pithead sees the build/ context and builds locally, tagging the images :dev
(the dashboard badge then reads dev · <branch> @ <commit> instead of the release version):
git clone https://github.com/p2pool-starter-stack/pithead.git
cd pithead && makeRelease archives already include the generated pithead executable. Git clones keep only its
numbered sources, so make builds the executable before the first ./pithead command.
Changed your mind later? You can convert a clone to the published images in place. See Switching a source checkout to release images.
./pithead setupSetup walks through five stages. It's interactive on the first run and safe to re-run later.
-
Dependency check. Verifies Docker, Docker Compose,
jq,openssl, andpython3are present. On Ubuntu it offers toapt installanything missing; on other systems it tells you what to install. Skip with--skip-deps. -
Interactive configuration. Asks only what only you can answer, in two short stages, then fills in the rest and writes a minimal
config.json, locked down to owner-only (chmod 600). Use a dedicated Monero mining wallet: P2Pool payout addresses are public (P2Pool's guidance).- Required: your Monero wallet address; whether you're running a local Monero node (the
default — the stack runs its own) or connecting to a remote one, with a local node's RPC
credentials auto-generated; and your P2Pool pool tier (
main/mini/nano— pick low if you're not sure, a high-hashrate default silently starves a small rig of shares). An dashboard login, generated on Enter and printed once; enternoneto opt out. - Merge-mine Tari? (beta) Three answers: no, run the bundled Tari node here, or use a Tari
node you already run. Tari runs on pre-release upstream software, so Enter means no. Yes
downloads and syncs a Tari chain over Tor, which takes days. A yes asks for your Tari payout address, and "a node I already run" asks
for its host and gRPC port — see Remote Tari node. A no
asks nothing further and stores no Tari address; nothing merge-mines and no Tari node runs.
The wizard writes
tari.modeexplicitly whichever way you answer, so the answer survives. The one exception is a reinstall that keeps its data: when./data/tarialready holds half the Tari budget or more, Enter keeps the bundled node on, so it does not silently drop merge-mining. The wizard prints the free space it measured against the whole-stack budget (the bundled Tari node adds 200 GiB to Monero's) for anyone who says yes. A yes on a new install also writesdashboard.tari_required: false, so Tari cannot hold or reject Monero mining. Changeable later from the dashboard's Configuration view, or by editingtari.modeand running./pithead apply. - Once the config is written, setup asks one more thing: the hostname you'll use to reach the dashboard in a browser. Enter accepts this machine's hostname.
- A few more, Enter for the default: a faster clearnet initial sync (hours instead of days, for every local chain, exposing your IP address to the Monero network and, when Tari runs locally, the Tari network until initial sync finishes) instead of the private Tor default; reaching the dashboard from outside your LAN over Tor; Telegram alerts; and whether this machine should also mine with its spare CPU (a co-located RigForge worker).
- XvB is off and is not asked; enable it later from the Configuration view.
- Everything else — ports, energy pricing, per-worker overrides, and more — keeps
its documented default; the wizard prints a pointer to
config.jsonand Configuration at the end for anyone who wants it.
- Required: your Monero wallet address; whether you're running a local Monero node (the
default — the stack runs its own) or connecting to a remote one, with a local node's RPC
credentials auto-generated; and your P2Pool pool tier (
-
Tor provisioning. Brings up the Tor service and waits for the hidden-service (onion) addresses: P2Pool always, plus Monero and Tari for whichever of those nodes runs locally. A node in remote mode gets no inbound onion — it accepts its own peers where it runs.
-
Kernel optimization (Linux only). Configures HugePages for RandomX performance. Making HugePages persistent adds
/etc/default/grub.d/zz-pithead-hugepages.cfgand requires a reboot. Setup preserves existing boot arguments, including cloud console settings, and verifies the generated kernel entries afterupdate-grub. It repairs previous Pithead reservations on re-run; a new or unrecognized reservation requires confirmation. An unchanged setup on a host already booted with the verified flags continues to Start without requesting another reboot. Skip this stage with--skip-optimize. -
Start. Once everything is provisioned, setup offers to start the stack.
If you enabled persistent HugePages, reboot before mining. After the reboot, start the stack with
./pithead up.
| Flag | Effect |
|---|---|
--skip-optimize |
Skip the kernel/GRUB HugePages tuning (useful on non-Linux hosts or when you tune the kernel yourself). |
--skip-deps |
Skip dependency detection and installation. |
This section assumes both nodes run here, the default. A chain served from another machine
(monero.mode / tari.mode: remote) never syncs on this host — its container isn't started at all.
The first time the stack starts, your Monero and Tari nodes download and verify the blockchain
from the network. Until both are fully synced, the dashboard shows a dedicated Sync Mode screen
with live progress for each chain, and no hashrate is routed yet. When the stack first comes up,
pithead prints a short "what happens next" note saying the miner is held until both chains sync,
then starts automatically — it shows once, not on every restart.
This can take anywhere from a few hours to a day or more depending on your hardware, disk, and
network. Watch progress on the dashboard, with ./pithead status (it prints each chain's percent
and blocks remaining while syncing), or in the logs:
./pithead logs monerod
./pithead logs tariEach line applies only to a node this host actually runs — in remote mode that service isn't in the
stack, so logs has nothing to follow.
Once both chains report fully synced, the dashboard switches from Sync Mode to the full operational view and the stack begins mining. See The Dashboard for a tour of both states.
Already have a synced Monero node? You can skip most of the initial sync by pointing the stack at your existing blockchain data, or by connecting to a remote node. See Reusing an existing node. The same holds for Tari: point
tari.data_dirat an existing Minotari chain, or settari.mode: remoteto merge-mine against a node on another machine — see Remote Tari node.
Sync crawling over Tor? The default routes the first sync over Tor for privacy, which is slow. You can opt into a faster clearnet initial sync for Monero and/or Tari while the egress firewall stays on. It takes hours instead of days, exposes your IP to that chain's peers during the sync, and switches each node back to Tor automatically when it finishes; the warning stays until the host verifies the live daemon and firewall. Read the trade-off first: Optional clearnet initial sync.
The dashboard is served over HTTPS by Caddy:
https://<your-hostname>
<your-hostname> is the host you set during setup (the script prints the exact URL when it
starts the stack). Caddy uses a self-signed certificate (tls internal), so the first time you
visit, your browser shows a one-time "your connection is not private" / untrusted-certificate
warning. Accept it to continue. Prefer plain HTTP on your LAN? Set dashboard.secure: false in
config.json and run ./pithead apply.
Point your XMRig miners at the stack machine on port 3333. That's the single endpoint for all
your rigs. Do not put your wallet address in the miner config; the stack handles payouts
centrally.
See Connecting Miners to point an existing rig at the stack, or use RigForge to provision a tuned miner from scratch in one command.
- Configuration — fine-tune the stack, reuse an existing node, or switch P2Pool sidechains.
- The Dashboard — understand Sync Mode and every panel of the live view.
- Operations & Maintenance — upgrades, backups, and troubleshooting.