mirror of
https://github.com/luxfi/explorer.git
synced 2026-09-24 00:25:12 +00:00
feat: include graph engine (subgraph replacement) in combined image
4 repos, 4 images: indexer → chain data (blocks, txs, tokens, contracts) graph → subgraph events (swaps, pools, DeFi, GraphQL) explore → Next.js frontend explorer → all three combined (this) Single image contains 3 binaries: indexer, graph, explorer. Each can run standalone or together.
This commit is contained in:
+58
-14
@@ -1,18 +1,22 @@
|
||||
# luxfi/explorer — Combined: indexer backend + explore frontend
|
||||
# luxfi/explorer — Combined: indexer + graph + explore frontend
|
||||
#
|
||||
# Uses the pre-built indexer image as base, adds the frontend static export.
|
||||
# No Go compilation needed — just layers the frontend on top.
|
||||
# ghcr.io/luxfi/indexer ← chain data (blocks, txs, tokens, contracts)
|
||||
# ghcr.io/luxfi/graph ← subgraph events (swaps, pools, DeFi, GraphQL)
|
||||
# ghcr.io/luxfi/explore ← Next.js frontend
|
||||
# ghcr.io/luxfi/explorer ← This: all three combined
|
||||
#
|
||||
# ghcr.io/luxfi/indexer ← Go backend (built by luxfi/indexer CI)
|
||||
# ghcr.io/luxfi/explore ← Next.js frontend (built by luxfi/explore CI)
|
||||
# ghcr.io/luxfi/explorer ← This: combined
|
||||
# Each component can also run standalone for independent scaling.
|
||||
|
||||
ARG INDEXER_IMAGE=ghcr.io/luxfi/indexer:main
|
||||
ARG GO_VERSION=1.26
|
||||
ARG NODE_VERSION=22
|
||||
ARG INDEXER_REPO=https://github.com/luxfi/indexer.git
|
||||
ARG INDEXER_REF=main
|
||||
ARG GRAPH_REPO=https://github.com/luxfi/graph.git
|
||||
ARG GRAPH_REF=main
|
||||
ARG EXPLORE_REPO=https://github.com/luxfi/explore.git
|
||||
ARG EXPLORE_REF=main
|
||||
|
||||
# ---- Stage 1: Build frontend static export ----
|
||||
# ---- Stage 1: Build frontend ----
|
||||
FROM node:${NODE_VERSION}-alpine AS frontend
|
||||
ARG EXPLORE_REPO
|
||||
ARG EXPLORE_REF
|
||||
@@ -21,17 +25,57 @@ WORKDIR /app
|
||||
RUN git clone --depth=1 --branch=${EXPLORE_REF} ${EXPLORE_REPO} .
|
||||
RUN corepack enable && pnpm install --frozen-lockfile
|
||||
ENV NEXT_PUBLIC_API_BASE_PATH=/v1/explorer
|
||||
ENV NODE_OPTIONS="--max-old-space-size=8192"
|
||||
RUN sed -i "s/output: 'standalone'/output: 'export'/" next.config.js || true
|
||||
RUN pnpm build || true
|
||||
RUN mkdir -p /app/out && [ -f /app/out/index.html ] || \
|
||||
echo '<!DOCTYPE html><html><head><title>Explorer</title></head><body></body></html>' > /app/out/index.html
|
||||
|
||||
# ---- Stage 2: Combine indexer + frontend ----
|
||||
FROM ${INDEXER_IMAGE}
|
||||
# ---- Stage 2: Build Go binaries ----
|
||||
FROM golang:${GO_VERSION}-alpine AS builder
|
||||
ARG INDEXER_REPO
|
||||
ARG INDEXER_REF
|
||||
ARG GRAPH_REPO
|
||||
ARG GRAPH_REF
|
||||
RUN apk add --no-cache gcc musl-dev sqlite-dev git
|
||||
ARG VERSION=dev
|
||||
|
||||
USER root
|
||||
# Build indexer
|
||||
WORKDIR /indexer
|
||||
RUN git clone --depth=1 --branch=${INDEXER_REF} ${INDEXER_REPO} .
|
||||
RUN go mod download
|
||||
COPY --from=frontend /app/out /indexer/cmd/explorer/static
|
||||
RUN sed -i 's|//go:embed static/\*|//go:embed all:static|' /indexer/cmd/explorer/frontend.go 2>/dev/null || true
|
||||
RUN CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build \
|
||||
-ldflags="-s -w -X main.version=${VERSION}" -o /bin/indexer ./cmd/indexer/
|
||||
RUN CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build \
|
||||
-ldflags="-s -w -X main.version=${VERSION}" -o /bin/explorer ./cmd/explorer/
|
||||
|
||||
# Build graph
|
||||
WORKDIR /graph
|
||||
RUN git clone --depth=1 --branch=${GRAPH_REF} ${GRAPH_REPO} .
|
||||
RUN go mod download
|
||||
RUN CGO_ENABLED=1 CGO_CFLAGS="-D_LARGEFILE64_SOURCE" go build \
|
||||
-ldflags="-s -w -X main.version=${VERSION}" -o /bin/graph ./cmd/graph/
|
||||
|
||||
# ---- Stage 3: Runtime ----
|
||||
FROM alpine:3.21
|
||||
RUN apk add --no-cache ca-certificates sqlite-libs
|
||||
COPY --from=builder /bin/indexer /usr/local/bin/indexer
|
||||
COPY --from=builder /bin/explorer /usr/local/bin/explorer
|
||||
COPY --from=builder /bin/graph /usr/local/bin/graph
|
||||
COPY --from=frontend /app/out /srv/frontend
|
||||
USER explorer
|
||||
|
||||
# The explorer binary serves /srv/frontend at /* and API at /v1/explorer/*
|
||||
ENV FRONTEND_DIR=/srv/frontend
|
||||
RUN adduser -D -u 65532 explorer
|
||||
USER explorer
|
||||
VOLUME /data
|
||||
ENV DATA_DIR=/data HTTP_ADDR=:8090
|
||||
EXPOSE 8090 4000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
|
||||
CMD wget -qO- http://localhost:8090/health || exit 1
|
||||
|
||||
# Default: run the multi-chain explorer (indexer + graph + frontend)
|
||||
# Override with: docker run ... indexer --chain cchain --rpc ...
|
||||
# or: docker run ... graph --rpc ...
|
||||
ENTRYPOINT ["explorer"]
|
||||
|
||||
@@ -1,39 +1,49 @@
|
||||
# Explorer
|
||||
|
||||
Combined block explorer image: Go backend ([`luxfi/indexer`](https://github.com/luxfi/indexer)) + Next.js frontend ([`luxfi/explore`](https://github.com/luxfi/explore)) in a single container.
|
||||
Combined block explorer: chain indexer + subgraph engine + frontend in a single image.
|
||||
|
||||
```
|
||||
ghcr.io/luxfi/indexer ← Go backend (API + chain indexing)
|
||||
ghcr.io/luxfi/indexer ← chain data: blocks, txs, tokens, contracts (SQLite)
|
||||
ghcr.io/luxfi/graph ← subgraph events: swaps, pools, DeFi, GraphQL (SQLite)
|
||||
ghcr.io/luxfi/explore ← Next.js frontend
|
||||
ghcr.io/luxfi/explorer ← This: combined single image
|
||||
ghcr.io/luxfi/explorer ← all three combined (this image)
|
||||
```
|
||||
|
||||
Each component runs standalone for independent scaling, or together in one container.
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
# Combined (default) — indexes chain + subgraphs, serves API + frontend
|
||||
docker run -p 8090:8090 \
|
||||
-e RPC_ENDPOINT=http://node:9650/ext/bc/C/rpc \
|
||||
-e CHAIN_NAME="My Chain" \
|
||||
-e COIN_SYMBOL=ETH \
|
||||
-v explorer-data:/data \
|
||||
-v data:/data \
|
||||
ghcr.io/luxfi/explorer
|
||||
|
||||
# Just the indexer (chain data API only)
|
||||
docker run -p 8090:8090 \
|
||||
-v data:/data \
|
||||
ghcr.io/luxfi/explorer \
|
||||
indexer --chain cchain --rpc http://node:9650/ext/bc/C/rpc
|
||||
|
||||
# Just the graph engine (subgraph GraphQL only)
|
||||
docker run -p 4000:4000 \
|
||||
-v data:/data \
|
||||
ghcr.io/luxfi/explorer \
|
||||
graph --rpc http://node:9650/ext/bc/C/rpc
|
||||
```
|
||||
|
||||
Single port, single image. Backend API at `/v1/explorer/*`, frontend at `/`.
|
||||
## Architecture
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
docker build -t ghcr.io/luxfi/explorer .
|
||||
```
|
||||
|
||||
Pulls `luxfi/indexer` and `luxfi/explore` from GitHub at build time. Override branches:
|
||||
|
||||
```bash
|
||||
docker build \
|
||||
--build-arg INDEXER_REF=v1.2.0 \
|
||||
--build-arg EXPLORE_REF=v2.7.2 \
|
||||
-t ghcr.io/luxfi/explorer .
|
||||
explorer (1 image, 3 binaries)
|
||||
├── indexer /v1/explorer/* Chain data REST API
|
||||
├── graph /graphql Subgraph-compatible GraphQL
|
||||
├── explore /* Embedded Next.js frontend
|
||||
│
|
||||
├── SQLite per-chain Zero-config, WAL mode
|
||||
├── ZapDB KV Fast hash lookups
|
||||
└── Replicate → S3 E2E PQ encrypted (ML-KEM-768)
|
||||
```
|
||||
|
||||
## White-Label
|
||||
@@ -41,25 +51,14 @@ docker build \
|
||||
```bash
|
||||
docker run -p 8090:8090 \
|
||||
-e RPC_ENDPOINT=http://node:8545 \
|
||||
-e CHAIN_NAME="Awesome Chain" \
|
||||
-e COIN_SYMBOL=AWE \
|
||||
-e CHAIN_ID=12345 \
|
||||
-e CHAIN_NAME="My Chain" \
|
||||
-e COIN_SYMBOL=MYC \
|
||||
ghcr.io/luxfi/explorer
|
||||
```
|
||||
|
||||
## Multi-Chain
|
||||
|
||||
Mount a `chains.yaml`:
|
||||
|
||||
```bash
|
||||
docker run -p 8090:8090 \
|
||||
-v ./chains.yaml:/etc/explorer/chains.yaml \
|
||||
-v explorer-data:/data \
|
||||
ghcr.io/luxfi/explorer --config=/etc/explorer/chains.yaml
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [`luxfi/indexer`](https://github.com/luxfi/indexer) — Go backend, 1528 tests, SQLite, E2E PQ encrypted backups
|
||||
- [`luxfi/explore`](https://github.com/luxfi/explore) — Next.js frontend, Geist font, white-label
|
||||
- [`luxfi/indexer`](https://github.com/luxfi/indexer) — Go chain indexer, 1528 tests
|
||||
- [`luxfi/graph`](https://github.com/luxfi/graph) — Subgraph engine, Graph Node replacement
|
||||
- [`luxfi/explore`](https://github.com/luxfi/explore) — Next.js frontend
|
||||
- [`luxfi/explorer-v1`](https://github.com/luxfi/explorer-v1) — Legacy Elixir stack (archived)
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
# Patch Go embed directive to include _next prefixed files
|
||||
sed -i 's|//go:embed static/\*|//go:embed all:static|' /src/cmd/explorer/frontend.go
|
||||
Reference in New Issue
Block a user