sidecar: build FIPS from source in Docker, handle fipstop terminal init

- Add multi-stage Dockerfile: Rust builder stage compiles FIPS with
  --no-default-features --features tui (excludes BLE/libdbus)
- Move build context to repo root so Dockerfile can access Cargo.toml/src
- Add .dockerignore to exclude target/, .git/, testing/ from context
- Fix UDP port mapping to 2121:2121
- Delete scripts/build.sh cross-compile workflow
- Simplify README setup steps (no local Rust toolchain needed)
- Replace ratatui::init() with try_init() for clean error on terminal
  init failure (e.g. Docker on macOS Sequoia)
This commit is contained in:
Origami74
2026-03-31 18:11:00 +00:00
committed by Johnathan Corgan
parent 8e38d889fa
commit 7224ce34f6
6 changed files with 38 additions and 89 deletions

View File

@@ -1,3 +1,19 @@
# ── Build stage: compile FIPS from source ──
FROM rust:1.94-slim-trixie AS builder
RUN apt-get update && \
apt-get install -y --no-install-recommends \
pkg-config && \
rm -rf /var/lib/apt/lists/*
WORKDIR /build
COPY Cargo.toml Cargo.lock rust-toolchain.toml build.rs ./
COPY src ./src
RUN cargo build --release --no-default-features --features tui && \
cp target/release/fips target/release/fipsctl target/release/fipstop /usr/local/bin/
# ── Runtime stage ──
FROM debian:trixie-slim
RUN apt-get update && \
@@ -45,9 +61,8 @@ RUN printf '%s\n' \
'no-resolv' \
>> /etc/dnsmasq.conf
COPY fips fipsctl fipstop /usr/local/bin/
RUN chmod +x /usr/local/bin/fips /usr/local/bin/fipsctl /usr/local/bin/fipstop
COPY --from=builder /usr/local/bin/fips /usr/local/bin/fipsctl /usr/local/bin/fipstop /usr/local/bin/
COPY entrypoint.sh /entrypoint.sh
COPY examples/sidecar-nostr-relay/entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -0,0 +1,6 @@
target/
.git/
.github/
testing/
examples/
!examples/sidecar-nostr-relay/

View File

@@ -7,19 +7,7 @@ iptables — it can only be reached via the node's `.fips` name.
## How to Run
### 1. Build the FIPS binaries
From the repo root, compile FIPS for Linux and copy the binaries into the
Docker build context:
```bash
cd examples/sidecar-nostr-relay
./scripts/build.sh
```
Cross-compilation from macOS is supported via `cargo-zigbuild`.
### 2. Set your node identity
### 1. Set your node identity
The relay needs a unique FIPS identity. Generate one with:
@@ -36,9 +24,13 @@ FIPS_NSEC=nsec1... # paste your nsec here
`FIPS_NSEC` is required — the container will refuse to start without it.
### 3. Start the stack
### 2. Start the stack
FIPS is compiled from source inside the Docker build stage — no local Rust
toolchain, Zig, or cargo-zigbuild needed.
```bash
cd examples/sidecar-nostr-relay
docker compose up -d
```
@@ -47,7 +39,7 @@ This starts two containers that share a network namespace:
- **fips** — FIPS daemon + dnsmasq. Owns the namespace, creates `fips0`.
- **app** — strfry relay + nginx. Joins the namespace via `network_mode: service:fips`.
### 4. Verify
### 3. Verify
```bash
# FIPS node is up and has a mesh address:
@@ -63,7 +55,7 @@ docker exec sidecar-nostr-relay-fips-1 fipsctl show peers
docker compose logs -f
```
### 5. Connect to the relay
### 4. Connect to the relay
Your node's npub (and therefore its `.fips` name) is derived from its keypair:
@@ -146,17 +138,6 @@ DNS inside the container is handled by dnsmasq (127.0.0.1:53):
The `resolv.conf` mount points the container's resolver at 127.0.0.1,
where dnsmasq handles the routing.
## Build
```bash
cd examples/sidecar-nostr-relay
./scripts/build.sh
```
This compiles FIPS for Linux, copies the binaries into the Docker context,
and builds the sidecar and app images. Cross-compilation from macOS is
supported via `cargo-zigbuild`.
## Run with Peers
To connect the sidecar to an existing mesh, provide the peer's npub and

View File

@@ -9,7 +9,8 @@ networks:
services:
fips:
build:
context: .
context: ../..
dockerfile: examples/sidecar-nostr-relay/Dockerfile
hostname: fips-sidecar
cap_add:
- NET_ADMIN

View File

@@ -1,57 +0,0 @@
#!/bin/bash
# Build the FIPS binary and Docker sidecar image.
# Usage: ./build.sh
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
DOCKER_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# Find project root (directory containing Cargo.toml)
PROJECT_ROOT="$(cd "$DOCKER_DIR/../.." && pwd)"
if [ ! -f "$PROJECT_ROOT/Cargo.toml" ]; then
echo "Error: Cannot find Cargo.toml at $PROJECT_ROOT" >&2
echo "Expected layout: <project-root>/examples/sidecar-nostr-relay/scripts/build.sh" >&2
exit 1
fi
# Detect host OS
UNAME_S=$(uname -s)
CARGO_TARGET="x86_64-unknown-linux-musl"
if [ "$UNAME_S" = "Darwin" ]; then
echo "Detected macOS host — using cross-compilation for Linux..."
if ! command -v cargo-zigbuild &> /dev/null; then
echo "Error: cargo-zigbuild not found." >&2
echo "Please install it: cargo install cargo-zigbuild" >&2
exit 1
fi
if ! rustup target list --installed | grep -q "$CARGO_TARGET"; then
echo "Installing Rust target $CARGO_TARGET..."
rustup target add "$CARGO_TARGET"
fi
echo "Building FIPS for Linux (release) using cargo-zigbuild..."
cargo zigbuild --release --target "$CARGO_TARGET" --manifest-path="$PROJECT_ROOT/Cargo.toml"
echo "Copying binaries to docker context..."
cp "$PROJECT_ROOT/target/$CARGO_TARGET/release/fips" "$DOCKER_DIR/fips"
cp "$PROJECT_ROOT/target/$CARGO_TARGET/release/fipsctl" "$DOCKER_DIR/fipsctl"
cp "$PROJECT_ROOT/target/$CARGO_TARGET/release/fipstop" "$DOCKER_DIR/fipstop"
else
echo "Building FIPS (release)..."
cargo build --release --manifest-path="$PROJECT_ROOT/Cargo.toml"
echo "Copying binaries to docker context..."
cp "$PROJECT_ROOT/target/release/fips" "$DOCKER_DIR/fips"
cp "$PROJECT_ROOT/target/release/fipsctl" "$DOCKER_DIR/fipsctl"
cp "$PROJECT_ROOT/target/release/fipstop" "$DOCKER_DIR/fipstop"
fi
echo "Done. Binaries at $DOCKER_DIR/{fips,fipsctl,fipstop}"
echo ""
echo "Building Docker image..."
docker compose -f "$DOCKER_DIR/docker-compose.yml" build
echo ""
echo "Ready: cd examples/sidecar-nostr-relay && docker compose up -d"

View File

@@ -121,7 +121,10 @@ fn main() {
.expect("failed to create tokio runtime");
let client = ControlClient::new(&socket_path);
let mut terminal = ratatui::init();
let mut terminal = ratatui::try_init().unwrap_or_else(|e| {
eprintln!("fipstop: failed to initialize terminal: {e}");
std::process::exit(1);
});
let mut app = App::new(refresh);
let events = EventHandler::new(refresh);