Skip to content

Pin node image to linux/amd64 - #164

Open
pucedoteth wants to merge 1 commit into
hyperliquid-dex:mainfrom
pucedoteth:pin-amd64-platform
Open

Pin node image to linux/amd64#164
pucedoteth wants to merge 1 commit into
hyperliquid-dex:mainfrom
pucedoteth:pin-amd64-platform

Conversation

@pucedoteth

Copy link
Copy Markdown

Problem

hl-visor (and the hl-node binaries it downloads) are published as x86-64 ELF executables only. The root Dockerfile uses:

FROM ubuntu:24.04

which resolves to the host's architecture. ubuntu:24.04 publishes an arm64 manifest, so on an arm64 host — Apple Silicon, Graviton, arm64 CI runners — docker compose build produces an arm64 image containing an amd64-only binary.

Nothing fails at build time. The download succeeds and gpg --verify passes, because the fetched binary is perfectly valid — it's just for the wrong architecture:

gpg: Good signature from "Hyperliquid <notices@hyperfoundation.org>"
=> writing image ... done

The image only breaks when started, with an error that doesn't point at the cause:

ERROR: Dynamic loader not found: /lib64/ld-linux-x86-64.so.2

and the container exits 255.

Confirmed on an arm64 host

$ uname -m
arm64
$ docker image inspect hl-node-test --format '{{.Architecture}}/{{.Os}}'
arm64/linux                      # <-- image is arm64

$ docker run --rm --entrypoint /bin/bash hl-node-test -c 'od -An -tx1 -N20 /home/hluser/hl-visor'
 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
 03 00 3e 00                     # <-- e_machine = 0x3e = x86-64

$ docker inspect -f '{{.State.Running}} exit={{.State.ExitCode}}' hlnode
false exit=255

So the image architecture and its payload architecture disagree.

Fix

Pin the base image to linux/amd64 so the image matches the only architecture the binaries are published for.

  • On amd64 hosts this is a no-op.
  • On arm64 hosts the image now runs under emulation instead of failing outright.

Verification

Rebuilt with the pin on the same arm64 host:

$ docker image inspect hl-node-amd64 --format '{{.Architecture}}/{{.Os}}'
amd64/linux

$ docker inspect -f 'running={{.State.Running}} exit={{.State.ExitCode}}' hlamd
running=true exit=0

$ docker logs hlamd
hl-visor @@ starting visor
hl-visor @@ child status @@ [start_time: ...] @ [n_restarts: 0]
hl-visor @@ downloading new hl-node binary @@ [chain: Testnet] @ [index: 1186]

The node starts and proceeds normally, where before it exited immediately.

Scope

pruner/Dockerfile is deliberately left unpinned — it only runs cron, bash, and coreutils, so it is genuinely architecture independent and should keep building natively on arm64 rather than paying for emulation.

🤖 Generated with Claude Code

`hl-visor` and the `hl-node` binaries it downloads are published as x86-64
ELF executables only. `FROM ubuntu:24.04` resolves to the host's
architecture, so on an arm64 host (Apple Silicon, Graviton, arm64 CI)
`docker compose build` produces an arm64 image containing an amd64-only
binary.

Nothing fails at build time -- the download and `gpg --verify` both
succeed, since the fetched binary is fine. The image only breaks when it
is started, with an error that does not point at the cause:

    ERROR: Dynamic loader not found: /lib64/ld-linux-x86-64.so.2

Confirmed on an arm64 host: the built image reports `arm64/linux`, while
the `hl-visor` it contains has ELF `e_machine = 0x3e` (x86-64), and the
container exits 255 on start.

Pinning the platform makes the image match its payload. On amd64 hosts
this is a no-op; on arm64 the image now runs under emulation instead of
failing. Verified by rebuilding with the pin on the same arm64 host: the
image reports `amd64/linux` and the node starts normally --

    hl-visor @@ starting visor
    hl-visor @@ child status @@ [start_time: ...] @ [n_restarts: 0]
    hl-visor @@ downloading new hl-node binary @@ [chain: Testnet] @ [index: 1186]

The pruner image is left alone: it only runs shell tooling, so it is
genuinely architecture independent and should keep building natively.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants