Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.git
.github
.agents
.codex
.bitcoin-rs
.env
target
**/target
crash-*
perf.data*
flamegraph.svg
docs/benchmarks/data
13 changes: 13 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Node network: mainnet, testnet3, testnet4, signet, or regtest.
BITCOIN_RS_NETWORK=mainnet

# JSON-RPC is published to 127.0.0.1 on the Docker host.
BITCOIN_RS_RPC_PORT=8332
BITCOIN_RS_RPC_USER=bitcoin-rs
BITCOIN_RS_RPC_PASSWORD=

# P2P is published on all Docker host interfaces so other nodes can connect.
BITCOIN_RS_P2P_PORT=8333

# Runtime tracing filter.
BITCOIN_RS_LOG_LEVEL=info
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ heap-profile-*
core.*
/tmp/
/.bitcoin-rs/
/.env

# Re-include project plan tracked in-repo (global ~/.gitignore drops PLAN.md).
!PLAN.md
Expand Down
45 changes: 45 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# syntax=docker/dockerfile:1.7

FROM rust:1.95-bookworm AS builder

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
clang \
cmake \
libboost-dev \
libclang-dev \
libzmq3-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /workspace
COPY . .

# Build the production verifier with the default fjall storage backend, while
# leaving the other storage engines out of the runtime image.
RUN cargo build --locked --release -p bitcoin-rs \
--no-default-features --features fjall,kernel

FROM debian:bookworm-slim AS runtime

RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
libgcc-s1 \
libstdc++6 \
libzmq5 \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd --gid 10001 bitcoin-rs \
&& useradd --uid 10001 --gid bitcoin-rs --no-create-home bitcoin-rs \
&& install -d -o bitcoin-rs -g bitcoin-rs /data

COPY --from=builder /workspace/target/release/bitcoin-rs /usr/local/bin/bitcoin-rs

USER bitcoin-rs
VOLUME ["/data"]
EXPOSE 8332 8333

ENTRYPOINT ["bitcoin-rs"]
CMD ["--data-dir", "/data", "--rpc-bind", "0.0.0.0:8332", "--p2p-listen", "0.0.0.0:8333"]
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,35 @@ That starts a mainnet node storing state in `.bitcoin-rs` and serving JSON-RPC
on `127.0.0.1:8332`. See [docs/getting-started.md](docs/getting-started.md) for
backend selection, RPC authentication, and checking sync progress.

### Docker Compose

The included Compose configuration builds the production `fjall` +
`bitcoinkernel` profile, keeps chain state in a named volume, exposes P2P on
port 8333, and binds RPC to the Docker host's loopback interface only.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reconcile the production Docker posture in CONCEPTS

This section establishes a durable container deployment configuration and explicitly calls it the production profile, but the affected Optimized default posture term in CONCEPTS.md is not reconciled with the container-specific volume, port, and RPC exposure decisions. Update that project vocabulary alongside this documentation so the two descriptions do not drift, as required by the repository guidance.

AGENTS.md reference: AGENTS.md:L5-L7

Useful? React with 👍 / 👎.


Set non-default RPC credentials in `.env`, then start the node:

```sh
cp .env.example .env
# Edit .env and set BITCOIN_RS_RPC_PASSWORD before starting the node.

docker compose up --build -d
docker compose logs -f node
```

Check sync progress through the host RPC port:

```sh
. ./.env
curl --user "$BITCOIN_RS_RPC_USER:$BITCOIN_RS_RPC_PASSWORD" \
-H 'content-type: application/json' \
-d '{"jsonrpc":"1.0","id":"sync","method":"getblockchaininfo","params":[]}' \
http://127.0.0.1:8332/
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use the configured host RPC port in the example

When BITCOIN_RS_RPC_PORT is changed from 8332, Compose publishes the RPC service on that configured host port (docker-compose.yaml:23), but this command still connects to 8332. The documented sync check therefore fails for a supported non-default .env; construct the URL using $BITCOIN_RS_RPC_PORT (with the same default) instead.

Useful? React with 👍 / 👎.

```

Stop the process without deleting its chain data with `docker compose down`.
Deleting the named volume requires the explicit `docker compose down -v` form.

## Measured performance

Full verification replay of mainnet blocks 0 to 150,000 (1,718,407
Expand Down
40 changes: 40 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: bitcoin-rs

services:
node:
build:
context: .
dockerfile: Dockerfile
image: bitcoin-rs:local
restart: unless-stopped
init: true
stop_grace_period: 30s
Comment thread
gosunuts marked this conversation as resolved.
Outdated
environment:
BITCOIN_RS_NETWORK: "${BITCOIN_RS_NETWORK:-mainnet}"
BITCOIN_RS_STORAGE_BACKEND: fjall
BITCOIN_RS_RPC_USER: "${BITCOIN_RS_RPC_USER:-bitcoin-rs}"
BITCOIN_RS_RPC_PASSWORD: "${BITCOIN_RS_RPC_PASSWORD:-bitcoin-rs}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Remove the fallback RPC password.

Line 16 starts the node with the known password bitcoin-rs when the variable is unset or empty. .env.example leaves the value empty, so this path is easy to reach. Host-local clients can then authenticate with public credentials.

Require a non-empty BITCOIN_RS_RPC_PASSWORD with ${BITCOIN_RS_RPC_PASSWORD:?set BITCOIN_RS_RPC_PASSWORD in .env}. Do not provide a fixed fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose.yaml` at line 16, Update the BITCOIN_RS_RPC_PASSWORD
environment assignment in the Docker Compose configuration to require a
non-empty value using the specified mandatory-variable syntax, removing the
hardcoded bitcoin-rs fallback while preserving the existing variable name.

Source: MCP tools

Comment thread
gosunuts marked this conversation as resolved.
Outdated
BITCOIN_RS_LOG_LEVEL: "${BITCOIN_RS_LOG_LEVEL:-info}"
volumes:
- bitcoin-rs-data:/data
Comment thread
gosunuts marked this conversation as resolved.
ports:
# Keep RPC private to the Docker host. Change this deliberately if a
# trusted remote client must connect.
- "127.0.0.1:${BITCOIN_RS_RPC_PORT:-8332}:8332"
- "${BITCOIN_RS_P2P_PORT:-8333}:8333"
healthcheck:
test:
- CMD-SHELL
- >-
curl --fail --silent --show-error
--user "$${BITCOIN_RS_RPC_USER}:$${BITCOIN_RS_RPC_PASSWORD}"
--header 'content-type: application/json'
--data '{"jsonrpc":"1.0","id":"health","method":"getblockchaininfo","params":[]}'
http://127.0.0.1:8332/ >/dev/null
interval: 30s
timeout: 5s
retries: 5
start_period: 30s

volumes:
bitcoin-rs-data:
Loading