p2pstream is a self-hosted public reverse proxy with a web management UI, optional remote agents, route-owned proxy/static targets, built-in local-user and forward-auth access policies, TLS automation, WAF challenges, public asset caching, rate limits, traffic shaping, and live traffic tracing.
Prerequisite: Docker Engine with the Docker Compose plugin installed. See Docker's install docs if Docker is not already available on your server: https://docs.docker.com/engine/install/.
git clone https://github.com/Kirari04/p2pstream.git
cd p2pstream
cp .env.example .env
# edit MANAGEMENT_PUBLIC_URL in .env, for example:
# MANAGEMENT_PUBLIC_URL=https://your-server:8081
docker compose up -d
docker compose logs -f p2pstreamOpen the management UI:
https://your-server:8081
your-server must match the externally reachable hostname or IP address, and should match MANAGEMENT_PUBLIC_URL in .env.
The first admin user can be created only when no users exist and the setup window is open. The setup window lasts 5 minutes after server start.
If the setup window expires before any user exists, restart the container:
docker compose restart p2pstreamIf you forget the admin password later, reset it inside the running container so the command uses the persisted /data volume:
docker compose exec p2pstream p2pstream users reset-password admin| Host port | Purpose |
|---|---|
80 |
Public HTTP listener and ACME HTTP-01 |
443 |
Public HTTPS listener and ACME TLS-ALPN-01 |
8081 |
Management UI/API and agent connections |
Runtime state is stored in the named Docker volume p2pstream-data. It contains the SQLite database plus generated management, public TLS, and ACME material. Keep this volume during upgrades or server moves unless you intentionally want to reset the instance.
docker compose logs -f p2pstream
docker compose restart p2pstream
docker compose pull
docker compose up -d
docker compose downdocker compose down stops and removes the container and network, but it does not remove the named p2pstream-data volume. For repeatable deployments, pin a release tag in compose.yaml instead of using latest.
Published images are available from GitHub Container Registry:
ghcr.io/kirari04/p2pstream:latest
Use latest or a pinned vX.Y.Z tag for stable deployments. Staging publishes immutable vX.Y.Z-staging.N prereleases with matching server images and Linux agent assets; the staging image alias moves only after that exact prerelease passes the full build and manifest verification workflow. The nightly tag is rebuilt from the dev branch as a Docker-only development channel.
The default Compose file publishes ports 80, 443, and 8081. Override host ports in .env when needed:
P2PSTREAM_HTTP_PORT=80
P2PSTREAM_HTTPS_PORT=443
P2PSTREAM_MANAGEMENT_PORT=8081If management is behind NAT or another reverse proxy, set MANAGEMENT_PUBLIC_URL to the external URL so browser links and generated agent setup snippets are correct.
For API-only management, set MANAGEMENT_UI_DISABLED=true; agents and the management API keep working, but the browser UI is not served. Agents use an authenticated Yamux tunnel over management TLS; if management is behind another reverse proxy, allow HTTP/1.1 upgrade streaming for p2pstream-yamux on /agent/tunnel.
Management HTTPS is enabled by default. Without your own trusted certificate, p2pstream generates a local management CA and server certificate, so browsers may show a certificate warning until you trust that CA or place management behind trusted TLS.
Full self-hosting and operations documentation is available at https://kirari04.github.io/p2pstream/.
- Docker Compose quickstart
- First login
- Publish a service
- Response templates reference
- Backup and restore
- WAF reference
- Identity-aware access
- Cache reference
Create an agent from Agents in the management UI. The Install Agent modal gives you an AGENT_ID and one-time AGENT_TOKEN, then provides Linux install, Docker Compose, and CLI snippets.
Copy the Linux command and run it on the agent host. It includes the issued credentials, downloads the installer and architecture-specific binary from the selected GitHub release, and verifies their SHA-256 checksums before installation. No token prompts or local file paths are required. Advanced options support independently verified local files. Managed updates pin an exact release or prerelease; other installs can resolve latest once to an exact release.
Existing Linux agents have More → Reinstall / Repair, which reuses their host token and includes managed-update setup when available. Agents → Updates → Enable managed updates performs the one-time enrollment while keeping the existing tunnel running. Rotate token remains a separate credential action. All setup actions share a dialog with an editable Management URL. Remote environments use their saved address when the server advertises localhost. Managed campaigns verify exact GitHub releases and SHA-256 manifests, preserve route quorum during activation, and roll back locally on failure. See Managed agent updates.
Agents connect through MANAGEMENT_URL, usually https://your-server:8081. The server's MANAGEMENT_PUBLIC_URL supplies that URL to generated setup snippets. If p2pstream generated the management TLS certificate, use the CA material from the Install Agent modal so the agent can verify management HTTPS.
For shell-installed agents, uninstall and full-purge commands are documented in the systemd operations guide.
make dev
make test
make verify
make build
make docker-build
make docker-smokemake verify is a clean-tree CI-style gate: run it with no staged, unstaged, or untracked files. It regenerates code and fails if generation leaves any tracked diff or untracked generated file, then runs installer syntax and lifecycle checks, Go tests and vet, management UI unit tests, typecheck, and production build. GitHub Actions runs those checks and also builds the runtime Docker image.
Database migrations use the embedded Goose library at runtime. For one-off migration scaffolding, run the pinned CLI outside the tracked tool set, for example go run github.com/pressly/goose/v3/cmd/[email protected] create <name> sql.
Development happens on the dev branch. Open normal feature and dependency PRs against dev, merge dev into staging to publish staging binaries/images for validation, and merge staging into main only when you want to publish a stable release.
GitHub Actions verifies the project and publishes each release in one automatic workflow. A staging push publishes a unique vX.Y.Z-staging.N prerelease; stable publishing is dispatched from main with an exact vX.Y.Z. Both channels build Linux amd64/arm64 binaries and images, generate and verify a canonical SHA-256 manifest, publish immutable version/commit aliases, create the GitHub release, verify its uploaded assets, and then move only the matching channel alias (staging or latest). GitHub Releases is the managed updater's trusted distribution boundary; no separate release-signing ceremony or key is required.
A scheduled nightly workflow builds the current dev branch and publishes the Docker-only ghcr.io/kirari04/p2pstream:nightly tag. Nightly images are for development validation and should not be used as repeatable production pins.
p2pstream is licensed under the GNU Affero General Public License version 3 or later (AGPL-3.0-or-later). See LICENSE for the complete license text and NOTICE for the project notice.
Official binaries, Docker images, and release assets provide corresponding source through the matching tagged GitHub source archive. Running management instances also expose a source offer at:
/.well-known/p2pstream/source