Running a kernel
Running a kernel gives you responsibility for its accounts, persistent records, and external payments. This chapter covers creation, funding, maintenance, and network participation. Routine supervision is covered in Operator duties.
Starting one
$ juice kernel serve acme --addr :4040
The name acme selects the kernel’s directory and supplies its initial nickname.
The --addr option sets its HTTP listening address. On first start, the command
asks you to confirm creation and select the network whose money the kernel will
use:
There is no kernel named acme. No kernels here yet.
Create acme as a new kernel? [y/N] y
Which money will acme use? This cannot be changed later.
play no real money: you credit accounts yourself and keep the records
test fake USDC on the Arbitrum Sepolia test chain
real USDC on Arbitrum One
Choice [play/test/real]: play
Superuser password:
Confirm password:
sys recovery phrase (write this down; it is shown only once and cannot be recovered):
depart motion moon climb useless hole learn usage delay fish brand lab
Press Enter once you have written it down:
Superuser "sys" created.
INF server.ready handle=acme network=play addr=[::]:4040 public_key=L3ciw7zj…
For a chain network, first boot also asks for the RPC endpoint through which the kernel will read the chain and submit payments. See Setting up on a chain. Declining creation or stopping before the network is chosen leaves no kernel state on disk.
The network cannot be changed afterwards. A kernel serves the one it was created with for its whole life; using another means creating another kernel.
After verification, the selected network is recorded in the database. Later starts use that record to ensure the kernel continues on the same network. Operational settings such as listening addresses, fees, bootstrap peers, and the chain endpoint can be changed in configuration.
Save the recovery phrase before pressing Enter. It is shown once, it is the only way to reset the
syspassword (juice auth recover sys@acme), and nobody can recover it for you.
With setup complete, later starts use the saved state and print a ready line identifying the kernel, network, and public key.
Setting up on a chain
A kernel on test or real needs access to the chain and funds for transaction
fees. It generates its own rail key during setup. The sequence is:
1. Obtain a chain endpoint. Supply the URL of a hosted node or one you
operate yourself. The kernel uses it to read payments and submit transactions.
First boot stores it as rail_rpc, which you may change later.
2. Start the kernel. First boot generates rail.key in the kernel’s home.
This key controls its account on the chain.
rail.keycontrols the kernel’s money on the chain. It is created once and never regenerated. Back it up with the rest of the home, and lose it and you lose what the kernel holds.
3. Read the kernel’s address. After registering the kernel with your client
and logging in as sys, inspect its rail address:
$ juice admin kernel show
Handle: bank
Network: real
Paid at: 0xcaf2a882af8730c6ad92d76361b1952c71c0453f
Holdings: 0.00 USDC (gas 0.00) as of block 13
…
4. Fund transaction fees. Send ETH to that address, following the procedure below.
Funding the kernel
The kernel needs ETH to submit withdrawals and paying settlement tickets.
A new kernel has none, so fund its address before expecting outgoing payments
to complete. The address appears as Paid at: in admin kernel show.
The shipped Arbitrum One settings trigger a refill below 0.001 ETH and target 0.003 ETH; Arbitrum Sepolia uses 0.0002 and 0.0004 ETH respectively. These thresholds describe the configured refill policy, rather than a guarantee of how much a particular transaction will cost.
Once funded, the kernel can buy more ETH using its own USDC earnings. User backing is excluded from that spending. A refill itself needs ETH, however, so a kernel that falls below the cost of submitting one may need another operator top-up. See How the kernel keeps itself in fuel.
Without sufficient ETH, outgoing payments cannot proceed. Deposits and calls can continue, but a blocked withdrawal or settlement payment requires the shortage to be resolved. Buying ETH also requires a transaction fee.
ETH sent to the rail address supplies the kernel’s transaction fees and is not credited to a user’s balance. Users deposit USDC at the same address, so explain the distinction when giving funding instructions; the deposit chapter covers it in Step 3.
The kernel’s own USDC ordinarily accumulates as fees in the sys account.
You may add to that balance through an ordinary deposit: register a sender
address for sys and send the token from it. These account funds are separate
from the ETH supplied for blockchain fees.
Starting without a terminal
For unattended first boot, create the configuration with the network choice
in advance and provide the superuser password through
JUICE_BOOTSTRAP_PASSWORD:
$ mkdir -p ~/.juice/kernels/acme
$ echo '{"world":"play"}' > ~/.juice/kernels/acme/config.json
$ JUICE_BOOTSTRAP_PASSWORD=… juice kernel serve acme --addr :4040
If required configuration is missing and no terminal is available, startup
fails with a message identifying the missing setting. A chain network also
requires rail_rpc.
The kernel’s home
Each kernel has a home directory containing the state needed to run it:
~/.juice/kernels/acme/
juice.db accounts, actions, ledger, and the signing key
config.json configuration, written once at first boot
serve.lock held by the running server
cache/ regenerable; safe to delete
On a chain network, the directory also contains the rail key and payment records. Keep these files together when moving or backing up the kernel: the account ledger, signing identity, and external payments belong to the same installation state.
To run another kernel under the same Juice installation, choose a different name:
$ juice kernel serve beta --addr :4242
Choose a distinct HTTP listening address. Federation uses OS-assigned ports
by default; if you configure fixed fed_listen_addrs, avoid collisions there
as well. An exclusive lock permits only one server to use a kernel’s home at
a time. Its database and configuration locations follow from the home rather
than separate --db or --config options.
Stopping, backing up, upgrading
Stop the server with SIGINT or SIGTERM. It stops accepting requests, drains
current work, and exits. Juice has no separate stop command.
For a consistent backup, stop the server and copy the complete home directory. Copying individual files while the server is running is not a supported backup procedure.
To upgrade, stop the server, replace the executable, and start it again. Startup applies forward database migrations. An older binary refuses a database whose migration version it does not recognize.
Juice provides no kernel-removal command. Before archiving a home directory, account for its balances and unsettled obligations, since the directory holds the records and keys needed to resolve them.
Joining the network
The default bootstrap_peers connect the kernel to the network, after which
it discovers peers and exchanges public catalogs. Eligible public actions are
then available to remote callers without another registration step.
Peers are identified by public key. A kernel behind a home router can be reached directly, through hole punching, or through a relay, without configuring port forwarding. Publicly reachable kernels also support routing and relay traffic; public bootstrap nodes conventionally listen on port 31313.
Discovery is separated by network, so play, test, and real kernels find
peers in their own network. You can inspect the local transport addresses with:
$ juice admin kernel show
…
Listen addresses:
/ip4/127.0.0.1/tcp/31401/p2p/12D3KooWJHdK…
Checking it is up
$ juice kernel health acme
ok acme network play fdlMi64P…
Health checks require no login and report the server’s identity as well as its status. Clients use that identity to check they have reached the expected kernel.
Logs
Logs are written to stderr and, if configured, a log file. Command response data uses stdout. Transition records include the request, caller, process, trace, action, and transaction identifiers needed to follow a call across stages. Credentials and other secrets are excluded.