Skip to content

Commit 34dd9f9

Browse files
authored
Dev0212 docker etc. (#30)
* Docker: add multi-arch image, CI/CD, and Docker guide - Dockerfile: static Go binary on alpine:3.21, Go 1.26 builder - .dockerignore: excludes test data (rpki.json ~82MB, MRT files) and build artifacts - .github/workflows/docker.yml: multi-arch build (8 platforms) pushed to ghcr.io on main/tags - .github/workflows/release.yml: cross-platform release binaries (30+ targets) on tags - docs/docker.md: Docker quick start, volume mounts, port forwarding, compose examples - docs/quickstart.md: tabbed install section (Docker / Binary / Go) - mkdocs.yml: Docker nav entry - README.md: Docker badge and Docker as first install option * add SEO meta descriptions to docs * bump bgpfix to v0.17.2 * Update .github/workflows/release.yml * fix copilot review: toolchain mismatch, mask build errors * fix: docker image tags use v-prefix to match git tags * fix flowspec doc: use RFC 8956 example for IPv6 prefix offset
1 parent c1cbc9b commit 34dd9f9

14 files changed

Lines changed: 432 additions & 50 deletions

File tree

.dockerignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.*
2+
*.yml
3+
*.md
4+
*.json
5+
*.bz2
6+
*.gz
7+
*.mrt
8+
*.csv
9+
*.txt
10+
11+
uv.lock
12+
bin/
13+
docs/
14+
scripts/
15+
site/
16+
test/
17+
tmp/
18+
19+
bgpipe
20+
Dockerfile
21+
LICENSE

.github/workflows/docker.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Docker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
tags: ["v*"]
7+
pull_request:
8+
branches: [main]
9+
workflow_dispatch:
10+
11+
env:
12+
REGISTRY: ghcr.io
13+
IMAGE_NAME: ${{ github.repository }}
14+
15+
jobs:
16+
build:
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up QEMU
27+
uses: docker/setup-qemu-action@v3
28+
29+
- name: Set up Docker Buildx
30+
uses: docker/setup-buildx-action@v3
31+
32+
- name: Log in to GitHub Container Registry
33+
if: github.event_name != 'pull_request'
34+
uses: docker/login-action@v3
35+
with:
36+
registry: ${{ env.REGISTRY }}
37+
username: ${{ github.actor }}
38+
password: ${{ secrets.GITHUB_TOKEN }}
39+
40+
- name: Extract metadata
41+
id: meta
42+
uses: docker/metadata-action@v5
43+
with:
44+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
45+
tags: |
46+
type=ref,event=branch
47+
type=semver,pattern=v{{version}}
48+
type=semver,pattern=v{{major}}.{{minor}}
49+
type=raw,value=latest,enable={{is_default_branch}}
50+
51+
- name: Build and push
52+
uses: docker/build-push-action@v6
53+
with:
54+
context: .
55+
platforms: linux/amd64,linux/arm64,linux/arm/v7
56+
push: ${{ github.event_name != 'pull_request' }}
57+
tags: ${{ steps.meta.outputs.tags }}
58+
labels: ${{ steps.meta.outputs.labels }}
59+
cache-from: type=gha
60+
cache-to: type=gha,mode=max

.github/workflows/release.yml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ["v*"]
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
release:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Go
19+
uses: actions/setup-go@v5
20+
with:
21+
go-version: "1.26"
22+
23+
- name: Build binaries
24+
run: |
25+
VERSION="${GITHUB_REF_NAME}"
26+
LDFLAGS="-s -w -X main.BuildVersion=${VERSION}"
27+
mkdir dist
28+
29+
build() {
30+
local os=$1 arch=$2 arm=$3
31+
local suffix=""
32+
[ "$os" = "windows" ] && suffix=".exe"
33+
local name="bgpipe-${os}-${arch}"
34+
[ -n "$arm" ] && name="${name}v${arm}"
35+
local out="dist/${name}${suffix}"
36+
37+
echo "Building $out ..."
38+
local output
39+
if output=$(env CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" GOARM="$arm" \
40+
go build -ldflags="$LDFLAGS" -trimpath -o "$out" . 2>&1); then
41+
echo " OK $(du -sh "$out" | cut -f1)"
42+
elif echo "$output" | grep -q "unsupported GOOS/GOARCH"; then
43+
echo " SKIP (unsupported ${os}/${arch})"
44+
else
45+
echo "$output" >&2
46+
echo " FAIL ${os}/${arch}" >&2
47+
return 1
48+
fi
49+
}
50+
51+
# Linux
52+
build linux amd64
53+
build linux arm64
54+
build linux arm 6
55+
build linux arm 7
56+
build linux 386
57+
build linux mips
58+
build linux mipsle
59+
build linux mips64
60+
build linux mips64le
61+
build linux ppc64
62+
build linux ppc64le
63+
build linux s390x
64+
build linux riscv64
65+
build linux loong64
66+
67+
# macOS
68+
build darwin amd64
69+
build darwin arm64
70+
71+
# Windows
72+
build windows amd64
73+
build windows arm64
74+
build windows 386
75+
76+
# BSDs
77+
build freebsd amd64
78+
build freebsd arm64
79+
build freebsd arm 7
80+
build freebsd 386
81+
build openbsd amd64
82+
build openbsd arm64
83+
build openbsd 386
84+
build netbsd amd64
85+
build netbsd arm64
86+
build netbsd arm 7
87+
build netbsd 386
88+
89+
ls -lh dist/
90+
91+
- name: Create release
92+
uses: softprops/action-gh-release@v2
93+
with:
94+
files: dist/*
95+
generate_release_notes: true

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
/site
44
.python-version
55
uv.lock
6+
.src/
7+
tmp/
8+
*.txt

Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# syntax=docker/dockerfile:1
2+
3+
# multi-stage build: cross-compile on builder platform, ship in scratch
4+
# NB: --platform=$BUILDPLATFORM keeps the Go compiler native (no QEMU needed for build)
5+
FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS builder
6+
7+
ARG TARGETOS TARGETARCH TARGETVARIANT
8+
9+
WORKDIR /build
10+
11+
# fetch dependencies first (cached layer)
12+
COPY go.mod go.sum ./
13+
RUN go mod download
14+
15+
# cross-compile static binary
16+
COPY . .
17+
RUN GOARM="$(echo ${TARGETVARIANT} | tr -d v)" \
18+
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} GOARM="${GOARM}" \
19+
go build -ldflags="-s -w" -trimpath -o bgpipe .
20+
21+
# ---
22+
23+
# scratch: zero base overhead; ca-certificates copied from builder
24+
FROM scratch
25+
26+
# ca-certificates: needed for HTTPS URLs (MRT archives, RPKI validators)
27+
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
28+
29+
COPY --from=builder /build/bgpipe /bgpipe
30+
31+
ENTRYPOINT ["/bgpipe"]
32+
CMD ["--help"]

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# bgpipe: BGP pipeline processor
22

3+
[![Docker Image](https://ghcr-badge.egpl.dev/bgpfix/bgpipe/size?label=docker)](https://github.com/bgpfix/bgpipe/pkgs/container/bgpipe)
4+
[![GitHub Release](https://img.shields.io/github/v/release/bgpfix/bgpipe)](https://github.com/bgpfix/bgpipe/releases/latest)
5+
36
An open-source tool that processes BGP messages through a pipeline of composable stages, built on [the bgpfix library](https://github.com/bgpfix/bgpfix).
47

58
**Full documentation at [bgpipe.org](https://bgpipe.org/)**
@@ -35,12 +38,16 @@ bgpipe \
3538

3639
## Installation
3740

38-
Download pre-built binaries from [GitHub Releases](https://github.com/bgpfix/bgpipe/releases/latest), or install from source:
39-
41+
**Docker** (fastest):
4042
```bash
41-
go install github.com/bgpfix/bgpipe@latest
43+
docker pull ghcr.io/bgpfix/bgpipe:latest
44+
docker run --rm ghcr.io/bgpfix/bgpipe:latest --help
4245
```
4346

47+
**Binary**: download from [GitHub Releases](https://github.com/bgpfix/bgpipe/releases/latest).
48+
49+
**Go**: `go install github.com/bgpfix/bgpipe@latest`
50+
4451
Run `bgpipe -h` or `bgpipe <stage> -h` for built-in help.
4552

4653
## Documentation

docs/docker.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Docker
2+
3+
bgpipe is published as a minimal, multi-architecture Docker image at `ghcr.io/bgpfix/bgpipe`.
4+
5+
Available tags:
6+
7+
- `latest` - latest build from `main` branch
8+
- `vX.Y.Z` - specific release
9+
- `vX.Y` - latest patch of a minor release
10+
11+
## Quick Start
12+
13+
```bash
14+
# print help
15+
docker run --rm ghcr.io/bgpfix/bgpipe:latest --help
16+
17+
# find RPKI-invalid announcements in RIPE RIS live stream
18+
docker run --rm ghcr.io/bgpfix/bgpipe:latest -go \
19+
-- ris-live \
20+
-- rpki --invalid=keep \
21+
-- grep 'tag[rpki/status] == INVALID'
22+
```
23+
24+
## Reading Files from the Host
25+
26+
Mount a host directory to pass MRT files or capture output:
27+
28+
```bash
29+
# read a local MRT file and write JSON output to the host
30+
docker run --rm \
31+
-v /path/to/data:/data \
32+
ghcr.io/bgpfix/bgpipe:latest \
33+
-- read /data/updates.mrt \
34+
-- write /data/output.json
35+
```
36+
37+
## BGP Sessions (Port Forwarding)
38+
39+
To run bgpipe as a proxy accessible from the host or other containers, expose port 179:
40+
41+
```bash
42+
# transparent proxy: host:1790 → bgpipe → 192.0.2.1:179
43+
docker run --rm \
44+
-p 1790:179 \
45+
ghcr.io/bgpfix/bgpipe:latest \
46+
-- listen :179 \
47+
-- connect --wait "listen" 192.0.2.1
48+
```
49+
50+
`--wait listen` tells the `connect` stage to wait until `listen` has accepted a connection before dialling out. This ensures the two halves of the proxy session are always synchronized.
51+
52+
## Docker Compose Examples
53+
54+
Docker Compose is included with [Docker Desktop](https://docs.docker.com/desktop/). To run any example below, save it as `compose.yml` in a new directory and run:
55+
56+
```bash
57+
docker compose up # start (Ctrl+C to stop)
58+
docker compose down # clean up
59+
```
60+
61+
### RIS Live Monitoring
62+
63+
The simplest example to try — no files or routers needed. Streams live BGP from [RIPE RIS Live](https://ris-live.ripe.net/) and prints matching routes to stdout:
64+
65+
```yaml
66+
services:
67+
bgpipe:
68+
image: ghcr.io/bgpfix/bgpipe:latest
69+
command: >-
70+
-- ris-live
71+
-- grep 'prefix ~ 8.0.0.0/8'
72+
-- stdout
73+
```
74+
75+
### MRT to JSON
76+
77+
Fetch a live MRT file from RIPE RIS and write it as JSON. The `read` stage handles URLs and gzip decompression automatically; the output JSON lands on the host via a volume mount:
78+
79+
```yaml
80+
services:
81+
bgpipe:
82+
image: ghcr.io/bgpfix/bgpipe:latest
83+
volumes:
84+
- ./data:/data
85+
command: >-
86+
-- read https://data.ris.ripe.net/rrc01/2025.11/updates.20251107.2300.gz
87+
-- write /data/output.json
88+
```
89+
90+
```bash
91+
mkdir data
92+
docker compose up
93+
# output.json appears in ./data/ when done
94+
```
95+
96+
### RPKI Proxy with Routinator
97+
98+
Run bgpipe as a RPKI-validating BGP proxy. [Routinator](https://routinator.docs.nlnetlabs.nl/) is an open-source RPKI validator by NLnet Labs that bgpipe connects to over RTR.
99+
100+
```yaml
101+
services:
102+
routinator:
103+
image: nlnetlabs/routinator:latest
104+
command: server --rtr 0.0.0.0:3323 --http 0.0.0.0:8323
105+
106+
bgpipe:
107+
image: ghcr.io/bgpfix/bgpipe:latest
108+
command: >-
109+
-- listen :179
110+
-- rpki --rtr routinator:3323
111+
-- connect --wait listen 192.0.2.1
112+
ports:
113+
- "1790:179"
114+
depends_on:
115+
- routinator
116+
```
117+
118+
Replace `192.0.2.1` with the address of your downstream router. bgpipe listens on port 1790 on the host, accepts one BGP connection, and proxies it through RPKI validation before forwarding to the real router.
119+
120+
## Building Locally
121+
122+
The Dockerfile auto-detects the target platform, so a plain `docker build` produces the right image for your machine — no flags needed:
123+
124+
```bash
125+
git clone https://github.com/bgpfix/bgpipe
126+
cd bgpipe
127+
docker build -t bgpipe .
128+
docker run --rm bgpipe --help
129+
```
130+
131+
To explicitly target a different platform:
132+
133+
```bash
134+
docker build --platform linux/arm64 -t bgpipe .
135+
```

0 commit comments

Comments
 (0)