No description
  • HTML 57.5%
  • Python 25.3%
  • Shell 10.9%
  • Dockerfile 3.4%
  • CSS 2.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-05-18 06:57:15 -03:00
btpd v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
examples v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
gateway v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
portal v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
.env.example v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
.gitignore v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
bootstrap.sh v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
CHANGELOG.md v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
docker-compose.yml v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
LICENSE v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
README.md v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00
seed-example-site.sh v0.7 - Welcome to the New Internet 2026-05-18 06:57:15 -03:00

btp-docker

Production deploy stack for the Berkeley Transport Protocol — the post-quantum successor to HTTP + TLS.

Compress everything. Trust nothing. Encrypt always.

btp-docker is the operator-facing Docker Compose stack for the BTP reference implementation. It bundles the origin daemon (btpd), an HTTPS browser gateway, a discovery portal, and an optional witness service into one repeatable deploy behind Nginx Proxy Manager.

The protocol implementation itself lives in the separate btp repository.

Current version: see CHANGELOG.md.


Layout

btp-docker/
├── README.md                     this file
├── CHANGELOG.md                  versioned change history
├── LICENSE                       Apache-2.0
├── .env.example                  copy to .env, edit if needed
├── .gitignore                    ignores data/ and .env
├── bootstrap.sh                  one-shot deploy / update / stop / logs
├── docker-compose.yml            4 services (3 active + 1 optional witness)
├── seed-example-site.sh          generate signed example doc via container's btpctl
│
├── btpd/
│   └── Dockerfile                builds btpd via --from=btp_source, with nc
│
├── gateway/
│   ├── Dockerfile                builds btpctl + adds local server.py
│   ├── server.py                 Flask + share-link engine (Session-B hardening)
│   └── tests/test_server.py      pytest suite (25 tests)
│
├── portal/
│   ├── Dockerfile                nginx:alpine with envsubst template
│   ├── nginx.conf                hardened CSP that actually works
│   └── html/                     self-contained landing site
│       ├── index.html            12 languages + dynamic content + origin info
│       ├── connect.html          full connect guide with envsubst vars
│       └── styles.css            connect.html styling (palette-aligned)
│
└── examples/
    ├── build-example-site.sh     host-side alternative (no docker exec needed)
    └── example.md

Ports

Service Host port Container port Behind NPM?
btpd 3004 4434 No (raw TCP — BTP wire protocol)
portal 3003 80 Yes
gateway 3005 8088 Yes
witness (optional) 3006 9443 Yes

All host ports configurable in .env.

Prerequisites

  • Linux host (tested: Debian 12, Ubuntu 22.04+, Fedora 39+)
  • Docker Engine 24.0+ with the buildx plugin (BuildKit) and compose v2 plugin
  • Optional: Nginx Proxy Manager already running on the host

Verify:

docker version           # 24.0+
docker buildx version    # any recent — required for additional_contexts
docker compose version   # v2.20+

Quick deploy

# 1. Get the BTP source (the Dockerfiles need it via additional_contexts)
cd /opt
git clone https://git.securityops.co/cristiancmoises/btp.git

# 2. Get this stack
git clone https://git.securityops.co/cristiancmoises/btp-docker.git

# 3. Bootstrap and seed
cd btp-docker
./bootstrap.sh
./seed-example-site.sh         # produces the signed origin doc
sudo ufw allow 3004/tcp        # open the BTP TCP port to the wider internet

The bootstrap script auto-detects the BTP source by trying, in order:

  1. $BTP_SOURCE_DIR env var (highest precedence)
  2. $BTP_SOURCE from .env
  3. ../btp (most common after side-by-side clone)
  4. ../btp-source
  5. /opt/btp

It then:

  1. Checks Docker + compose v2 + buildx are installed
  2. Verifies (and offers to create) the npm-bridge network
  3. Creates data directories with the right ownership
  4. Builds and starts the stack
  5. Probes each service for health (max 120 s)
  6. Prints a summary with next-step actions

Upgrade from a prior version

cd /opt
docker compose -f btp-docker/docker-compose.yml down

# extract the new tarball next to the existing tree
tar -xzf btp-docker-<new-version>.tar.gz

# carry forward .env and data/ (bind-mounted state)
cp    /opt/btp-docker/.env  /opt/btp-docker-<new-version>/.env
cp -a /opt/btp-docker/data  /opt/btp-docker-<new-version>/

# atomic swap with versioned backup
mv /opt/btp-docker            /opt/btp-docker.<old-version>-bak
mv /opt/btp-docker-<new-ver>  /opt/btp-docker

cd /opt/btp-docker
./bootstrap.sh
./seed-example-site.sh   # idempotent; reuses key + doc if present

For per-version migration notes, see CHANGELOG.md.

Bootstrap script subcommands

./bootstrap.sh              # full deploy + start + healthcheck
./bootstrap.sh --check      # preflight only — no build, no start
./bootstrap.sh --update     # rebuild (pulling base images) + restart
./bootstrap.sh --logs       # tail logs from all services
./bootstrap.sh --stop       # docker compose down
./bootstrap.sh --help       # this summary

NPM configuration

Configure proxy hosts:

Domain Forward Host Forward Port
btp.securityops.co 172.17.0.1 3003
btp-gw.securityops.co 172.17.0.1 3005
w1.btp.securityops.co 172.17.0.1 3006

For each: enable Block Common Exploits, Cache Assets, Websockets Support. SSL via Let's Encrypt with Force SSL and HTTP/2 Support.

Operating

Seeding the first signed document (fresh deploy)

After ./bootstrap.sh, data/site/ is empty so the gateway returns 502 upstream_error for /render and /raw. Run the bundled helper once to generate an origin key, capture the BLAKE3 fingerprint from the CLI output, and sign an example document — all via the btpctl that ships inside the gateway container (no need for btpctl on host):

./seed-example-site.sh

Re-runs are idempotent. Use --force to re-sign with the same key, or --regen-key to rotate the origin key (this breaks pinned clients).

The seed script uses the real btpctl CLI surface:

  • btpctl genkey --out FILE --ml-dsa — writes JSON {sk, pk} and prints the BLAKE3-256 fingerprint to stdout. The script parses both.
  • btpctl doc new --ml-dsa-key FILE --title … --input … --out … — signs.
  • btpctl doc verify FILE — sanity-check before exfiltrating from the container.

File movement to/from the container uses docker exec -i ... sh -c 'cat > F' and docker exec ... cat F (not docker cp), which avoids a tmpfs visibility bug on certain Docker daemon versions when the container's rootfs is read-only.

Adding a signed document

# On your build host (NOT the VPS), with btpctl in PATH:
btpctl genkey --out origin --ml-dsa
btpctl doc new --ml-dsa-key origin --title "Hello" --input hello.md --out hello.btp

# Rsync to VPS:
scp hello.btp vps:/opt/btp-docker/data/site/

btpd auto-reloads with --verify-on-load on the next request.

Origin fingerprint

Put your origin's BLAKE3-256 fingerprint in data/keys/fingerprint.txt. This shows up on the portal homepage (in the "This BTP Origin" section) for visitors to pin. The seed script writes this automatically.

To compute the fingerprint of an existing key out-of-band, the simplest trick on the current CLI is to sign a throwaway doc and read the author fingerprint from doc verify output:

echo '# probe' > /tmp/probe.md
btpctl doc new --ml-dsa-key origin --title probe --input /tmp/probe.md --out /tmp/probe.btp
btpctl doc verify /tmp/probe.btp | grep author

The genkey --ml-dsa command also prints the fingerprint at key generation time — easiest to capture it then.

Backups

Only stateful data: data/gateway/sharelinks.db (SQLite share-link DB) and data/keys/origin.key (the ML-DSA-87 keypair JSON). data/site/ is reproducible from your signed documents.

# Daily DB backup
sqlite3 data/gateway/sharelinks.db ".backup '/backup/sharelinks-$(date +%F).db'"

# Origin key — copy to offline media, NEVER to cloud storage
cp data/keys/origin.key /media/usb/btp-origin-$(date +%F).key

License

Apache-2.0 (matches the BTP reference implementation). See LICENSE.

The names "BTP" and "Berkeley Transport Protocol" are registered trademarks of Security Ops. See TRADEMARK.md in the main repo. Nominative fair use is fine; calling YOUR implementation "BTP" requires passing the conformance test suite at crates/btp/tests/conformance/.

Contact


Part of the Security Ops ecosystem.

In Code We Trust.