Skip to content

Docker Compose Quickstart ​

Start p2pstream with Docker Compose, persist runtime state in the p2pstream-data volume, and open the management UI over HTTPS.

Use This When ​

Use this path for the normal self-hosted server deployment on a VPS, home lab host, or small private fleet. Compose starts one server container with the management UI/API on 8081, a seeded HTTP listener on 80, and a seeded HTTPS listener on 443.

Prerequisites ​

  • Linux amd64/arm64 and Docker Engine with the Docker Compose plugin.
  • Host ports 80, 443, and 8081 available, or adjusted port mappings in .env.
  • A hostname or IP address that browsers and agents can reach.

Optional one-command setup ​

For a new installation, with Docker, Compose, and curl already installed:

bash
curl -fsSL https://raw.githubusercontent.com/Kirari04/p2pstream/main/scripts/setup-server.sh | sh

This creates ./p2pstream/compose.yaml and a private .env, starts the server, and prints the management URL and initial admin setup token. It refuses an existing deployment directory, container, or data volume; existing installations use the normal upgrade commands below.

By default it asks ipify directly, bypassing configured HTTP proxies, for the host's public IPv4 address and falls back to a local IPv4 address. For a domain, or to skip that lookup, supply the address yourself:

bash
curl -fsSL https://raw.githubusercontent.com/Kirari04/p2pstream/main/scripts/setup-server.sh | sh -s -- --host proxy.example.com

For staging:

bash
curl -fsSL https://raw.githubusercontent.com/Kirari04/p2pstream/staging/scripts/setup-server.sh | sh -s -- --channel staging

Use --directory, --http-port, --https-port, or --management-port to override the defaults. Address detection does not open firewalls or configure NAT forwarding. The generated management certificate uses a local CA, so an initial browser certificate warning is expected.

Each script URL becomes available when the helper reaches that release channel. If it has not been published there yet, use the manual two-file setup below. The setup-server.sh release asset is the same channel installer: it installs the current stable image by default, or current staging with --channel staging, rather than pinning the release it was downloaded from. Use the manual path with an exact image tag or digest when a fixed version is needed.

Keep using the deployment directory printed by the script for later Compose commands. If a download, startup, or readiness check fails, the generated files and data remain there. Resolve the reported Docker, port, or configuration error, then run docker compose pull p2pstream && docker compose up -d p2pstream from that directory. The first-run token is saved as MANAGEMENT_SETUP_TOKEN in the private .env; keep it private. Rerunning the fresh-install helper deliberately refuses those existing files and resources. There is no need to delete the data volume to resume.

Create two files manually ​

Create a directory for the deployment. Save the following as compose.yaml:

yaml
services:
  p2pstream:
    image: "${P2PSTREAM_IMAGE:-ghcr.io/kirari04/p2pstream:latest}"
    container_name: p2pstream
    restart: unless-stopped
    read_only: true
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    tmpfs:
      - /tmp:rw,nosuid,nodev,mode=1777
    environment:
      CONFIG_DIR: /data
      MANAGEMENT_PORT: "8081"
      # Default accepts Docker forwarding; preserve explicit operator overrides.
      MANAGEMENT_BIND_ADDRESS: "${MANAGEMENT_BIND_ADDRESS:-0.0.0.0}"
      MANAGEMENT_UI_DISABLED: "${MANAGEMENT_UI_DISABLED:-false}"
      MANAGEMENT_PUBLIC_URL: "${MANAGEMENT_PUBLIC_URL:-https://localhost:8081}"
      MANAGEMENT_SETUP_TOKEN: "${MANAGEMENT_SETUP_TOKEN:-}"
      MANAGEMENT_TLS_EXTRA_HOSTS: "${MANAGEMENT_TLS_EXTRA_HOSTS:-}"
      MANAGEMENT_TRUSTED_PROXY_CIDRS: "${MANAGEMENT_TRUSTED_PROXY_CIDRS:-}"
      MANAGEMENT_CLIENT_IP_HEADER: "${MANAGEMENT_CLIENT_IP_HEADER:-X-Forwarded-For}"
      MANAGEMENT_CLIENT_IP_MODE: "${MANAGEMENT_CLIENT_IP_MODE:-trusted_chain}"
      PUBLIC_MAX_HEADER_BYTES: "${PUBLIC_MAX_HEADER_BYTES:-65536}"
      PUBLIC_MAX_REQUEST_BODY_BYTES: "${PUBLIC_MAX_REQUEST_BODY_BYTES:-1073741824}"
      PUBLIC_REQUEST_BODY_IDLE_TIMEOUT_MILLIS: "${PUBLIC_REQUEST_BODY_IDLE_TIMEOUT_MILLIS:-30000}"
      PUBLIC_MAX_CONCURRENT_REQUESTS: "${PUBLIC_MAX_CONCURRENT_REQUESTS:-2048}"
      PUBLIC_MAX_CONCURRENT_REQUESTS_PER_TARGET: "${PUBLIC_MAX_CONCURRENT_REQUESTS_PER_TARGET:-0}"
      PUBLIC_MAX_CONNECTIONS_PER_TARGET: "${PUBLIC_MAX_CONNECTIONS_PER_TARGET:-256}"
      SERVER_TUNNEL_MAX_CONCURRENT_STREAMS: "${SERVER_TUNNEL_MAX_CONCURRENT_STREAMS:-0}"
    ports:
      - "${P2PSTREAM_HTTP_PORT:-80}:80"
      - "${P2PSTREAM_HTTPS_PORT:-443}:443"
      - "${P2PSTREAM_MANAGEMENT_PUBLISH_ADDRESS:-}:${P2PSTREAM_MANAGEMENT_PORT:-8081}:8081"
    volumes:
      - p2pstream-data:/data

volumes:
  p2pstream-data:
    name: p2pstream-data

Next to it, create .env:

dotenv
MANAGEMENT_PUBLIC_URL=https://your-server:8081
P2PSTREAM_IMAGE=ghcr.io/kirari04/p2pstream:latest
P2PSTREAM_HTTP_PORT=80
P2PSTREAM_HTTPS_PORT=443
P2PSTREAM_MANAGEMENT_PORT=8081

Replace your-server with your reachable hostname or IP. Use ghcr.io/kirari04/p2pstream:staging for prereleases, or select an exact published version tag or digest. The Docker reference describes the channels.

The setup script is optional. No Python, host updater, or release.json is required. The two files belong to you and can be edited directly.

Start the server ​

Run from that directory:

bash
docker compose up -d
docker compose logs -f p2pstream

Open https://your-server:8081. The management server uses HTTPS by default. It creates a local management CA and server certificate under /data/certs/management; browsers warn until you trust that CA or place management behind trusted TLS. The startup log contains the initial admin setup token unless you supplied MANAGEMENT_SETUP_TOKEN.

Configure and upgrade ​

Edit .env or compose.yaml, then run docker compose up -d to apply settings. To disable the browser UI while keeping the management API and agents available, set MANAGEMENT_UI_DISABLED=true in .env.

To update the selected channel, keep the same files and data volume:

bash
docker compose pull p2pstream
docker compose up -d p2pstream

Supported database migrations run automatically at startup. Back up before upgrading and read Upgrades for compatibility notes. An exact version tag or digest stays pinned until you change P2PSTREAM_IMAGE.

If an old server updater still manages the deployment, follow its transition procedure. If only abandoned updater metadata remains in a standalone deployment, the normal image upgrade handles it without deleting markers or repairing Compose.

Verification ​

The first browser visit should show Setup admin. After setup, Overview should load. Proxy -> Listeners shows the seeded public-http and public-https listeners. Open their shared published default site under Proxy -> Sites to inspect its welcome route and static target. Create a separate draft site for your application's hostnames, configure its routes inside the site workspace, review readiness, and publish when ready.

p2pstream Setup Admin screen showing setup token, username, password, and confirm password fields
The first-run setup screen appears only before the initial admin user exists. Use the setup token from the configured environment or server startup log.

Default sites handle hostnames that no named site owns. A published named site keeps its own routing boundary, including when a path has no matching route. See Sites for listener assignments, publication, and migration of older routing configurations.

On a new database, p2pstream seeds:

ObjectDefault
HTTP listenerpublic-http on :80
HTTPS listenerpublic-https on :443
Routesdefault catch-all routes with static welcome targets
HTTPS fallback certificateself-signed mapping for localhost

The seeded static targets serve a local Welcome to p2pstream proxy page. Replace them or add more specific routes before publishing real traffic.

Troubleshooting ​

SymptomCheck
Browser cannot connectConfirm docker ps, host firewall, and P2PSTREAM_MANAGEMENT_PORT.
Certificate warningExpected with auto management TLS until the generated CA is trusted.
Agent snippets use the wrong URLFix MANAGEMENT_PUBLIC_URL in .env, then run docker compose up -d.
Public listener does not answerConfirm the listener exists under Proxy -> Listeners, is enabled and running, and its port is published by Compose.

See Troubleshooting for route, TLS, agent, and cache-specific checks.

Next Steps ​

Operations documentation for self-hosted p2pstream deployments.