π¦ Parrot says: Found this useful? Drop a β an' help another crew find the map.
βββ β§ βββ
π Questions or cursed code? Step forwardβ¦ enter π₯HADESπ₯.
Privateerr is a containerized configuration tool for Private Internet Access (PIA). It packages PIA's official, unmodified manual-connection scripts in a small Alpine container and uses them to generate a WireGuard configuration file plus PIA server metadata for automation.
Use Privateerr when you want wg0.conf for Gluetun, WireGuard, or another compatible VPN clientβespecially when a Docker Compose deployment needs to generate that configuration repeatably.
Important
Privateerr is not a virtual private network (VPN) client. It does not create or maintain a tunnel. It generates wg0.conf for a VPN client such as Gluetun or WireGuard. Its optional supervisor refreshes Gluetun's connection settings; Gluetun still owns the tunnel.
The upstream PIA scripts remain visible as the docker/pia-manual-connections submodule. Privateerr adds repeatable container execution, safe defaults, health reporting, and a small metadata handoff without modifying those scripts.
For one-shot generation, you need an active PIA subscription and Docker. Replace YOUR_PIA_USERNAME and YOUR_PIA_PASSWORD with your account credentials.
This command pulls the published image and writes wireguard/wg0.conf and wireguard/privateerr.env under your current directory. Docker creates wireguard if it does not exist. Existing directories must allow container UID 0 to traverse the path and write files with all Linux capabilities dropped. Preserve any files you need and stop other writers before running it; generation replaces saved files.
Warning
Keep live wg0.conf and privateerr.env files private. They contain VPN connection material and deployment-specific metadata.
docker run --rm --pull always \
--cap-drop ALL \
--security-opt no-new-privileges:true \
--env PIA_USER='YOUR_PIA_USERNAME' \
--env PIA_PASS='YOUR_PIA_PASSWORD' \
--env VPN_PROTOCOL=wireguard \
--env PIA_CONNECT=false \
--env DISABLE_IPV6=no \
--env DIP_TOKEN=no \
--env AUTOCONNECT=true \
--env PIA_PF=true \
--env PIA_DNS=true \
--env PRIVATEERR_KEEPALIVE=false \
--volume "$(pwd)/wireguard:/gluetun/wireguard" \
ghcr.io/scottgigawatt/privateerr:latestThis one-shot container uses recovery-disabled defaults, leaves IPv6 settings unchanged, and exits after generation.
Use Git, Make, and Docker with Compose and Buildx. Clone the repository with its PIA submodule and create your private environment file:
git clone --recurse-submodules https://github.com/scottgigawatt/privateerr.git
cd privateerr
cp example.env .envThe public PIA submodule needs no GitHub SSH key. If cloning reports a submodule error or building reports a missing pia-manual-connections/LICENSE, follow Recover a missing PIA submodule.
Set PIA_USER and PIA_PASS in .env and keep the file private. Keep PIA_VPN_PROTOCOL=wireguard and PIA_CONNECT=false for configuration generation. The example selects a port-forwarding-capable region with PIA_PF=true.
The command below builds the checked-out source, disables recovery and keepalive for the disposable run, and exits after generation. Preserve any files you need and stop a supervisor using that directory first; generation replaces saved files.
make run-privateerrThe repository workflow writes:
config/gluetun/wireguard/wg0.confβ WireGuard configuration for Gluetun or another compatible VPN client.config/gluetun/wireguard/privateerr.envβ PIA server metadata used by Gluetun and related automation.
If you do not have Make, complete the same checkout and .env setup above, then use Compose directly. It reads your credentials and paths from .env. The same overwrite and single-writer precautions apply. Generate from the published image with:
docker compose --env-file .env run --rm --no-deps --pull always \
--env PRIVATEERR_AUTO_RECOVER=false \
--env PRIVATEERR_KEEPALIVE=false \
--env PIA_CONNECT=false \
--env VPN_PROTOCOL=wireguard \
privateerrTo build the checked-out source instead, keep the PIA submodule initialized and use:
docker compose --env-file .env run --rm --no-deps --build --pull never \
--env PRIVATEERR_AUTO_RECOVER=false \
--env PRIVATEERR_KEEPALIVE=false \
--env PIA_CONNECT=false \
--env VPN_PROTOCOL=wireguard \
privateerrThe supplied Compose file runs Privateerr, Gluetun, and qBittorrent together. qBittorrent shares Gluetun's VPN namespace and receives its forwarded port. This application example requires amd64 or arm64; Privateerr itself also supports arm/v7.
The stack also needs two scripts from your checkout:
- gluetun-entrypoint-wrapper.sh loads Privateerr's server metadata and prepares recovery access before starting Gluetun.
- qbittorrent-port-forwarding.sh keeps qBittorrent's listening port and VPN interface synchronized with Gluetun's forwarded-port lease.
The supplied Compose file mounts both scripts automatically. Keep them at the configured paths and readable inside Gluetun; the port-forwarding script must remain executable. If you change configuration locations, keep the script files and .env mount settings aligned.
After completing the repository checkout and .env setup above:
-
Generate a recovery API key:
openssl rand -hex 24
-
Set
PRIVATEERR_GLUETUN_API_KEYin.envto that value. Review qBittorrent's user/group IDs, storage paths, and Web UI port in the same file. -
Pull the published application images and start the three services in the background:
make up
make up-pull is an explicit alias for make up. Neither target builds images or starts Buccaneerr. To build Privateerr from the checked-out source instead, keep the PIA submodule initialized and run:
make up-buildup-build pulls Gluetun and qBittorrent, builds Privateerr locally, and starts the three services without pulling over that build.
Without Make, pull the published images explicitly, then start them without building or pulling again:
docker compose --env-file .env pull privateerr gluetun qbittorrent
docker compose --env-file .env up --detach --no-build --pull never privateerr gluetun qbittorrentFor a source build, pull only the two upstream application images, build Privateerr, then start the same three services:
docker compose --env-file .env pull gluetun qbittorrent
docker compose --env-file .env build privateerr
docker compose --env-file .env up --detach --no-build --pull never privateerr gluetun qbittorrentUse make ps to inspect service status and make logs to read output. Without Make, use docker compose --env-file .env ps and docker compose --env-file .env logs. The qBittorrent Web UI uses the configured host port, 8080 by default; follow the application access instructions to obtain and change its initial password.
The example enables automatic recovery: Privateerr monitors Gluetun and refreshes stale PIA settings through its authenticated API. Configure the shared key before starting. See automatic Gluetun recovery for timing, diagnostics, and custom deployments.
Buccaneerr is a separate test-only service in the test profile. make test runs credential-free repository checks; make test-e2e explicitly enables live VPN validation and deliberate recovery faults. See Buccaneerr's testing guide before running live tests.
Automatic selection is enabled by default. To pin a region, set PIA_AUTOCONNECT=false and PIA_PREFERRED_REGION=ca in .env. Replace ca with another PIA region ID when needed. See region selection for regeneration steps and recovery behavior.
Privateerr's Python supervisor prepares a matching wg0.conf and privateerr.env pair before Gluetun starts. With recovery enabled, it reuses valid saved files, checks recovery storage access, and remains running to monitor Gluetun. Gluetun owns the tunnel and the network namespace shared by applications.
flowchart TB
accTitle: Privateerr startup and automatic recovery
accDescr: Inside Privateerr, a Python supervisor checks storage and reuses or generates configuration through unmodified PIA scripts. Gluetun loads the saved files at startup. With recovery enabled, the supervisor monitors Gluetun status and health, generates a candidate after a sustained outage, applies it through the authenticated API, and saves it only after confirmation. Applications retain Gluetun's network namespace.
Supervisor["π΄ββ οΈ Privateerr Python supervisor<br/>Check storage; reuse or generate"]
PIA["π Unmodified PIA scripts<br/>Invoked through shell adapter"]
Files["π¦ Saved wg0.conf<br/>and privateerr.env"]
Gluetun["π‘οΈ Gluetun owns<br/>the VPN tunnel"]
Services["π’ Applications share<br/>Gluetun networking"]
Supervisor <-->|"Generate and validate<br/>candidate configuration"| PIA
Supervisor <-->|"Read saved pair;<br/>publish confirmed replacement"| Files
Files -->|"Load at startup"| Gluetun
Gluetun -.->|"Status and health"| Supervisor
Supervisor -.->|"Recovery API:<br/>apply and read back settings"| Gluetun
Gluetun -->|"Protected network namespace"| Services
classDef upstream fill:#fef3c7,stroke:#d97706,color:#451a03,stroke-width:2px
classDef generation fill:#dbeafe,stroke:#2563eb,color:#172554,stroke-width:2px
classDef handoff fill:#ede9fe,stroke:#7c3aed,color:#2e1065,stroke-width:2px
classDef connected fill:#dcfce7,stroke:#16a34a,color:#14532d,stroke-width:2px
class PIA upstream
class Supervisor generation
class Files handoff
class Gluetun,Services connected
The dashed arrows are the optional recovery loop. Privateerr updates Gluetun through its API; changing a saved file alone does not refresh a running tunnel. It verifies applied settings and tunnel health before publishing recovered configuration, without restarting the containers. Privateerr's own healthcheck reports startup readiness, not current tunnel health or guaranteed recovery write access. See diagnostics and filesystem checks for warnings and region messages.
Run make or make help for the command menu. The maintenance reference covers inspection, backups, cleanup, and generated files. Buccaneerr's testing guide explains offline checks and live PIA validation.
Privateerr and Buccaneerr support linux/amd64, linux/arm64, and linux/arm/v7; individual applications can support fewer architectures. Use latest for stable releases, edge to preview successful main builds, or an exact version to select a release. See registry publishing and image channels for tags, registries, and supply-chain controls.
- Developer documentation: Supervisor architecture, contributor guides, and generated Python reference.
- Advanced usage: Testing, builds, publishing, maintenance, and generated files.
- Configuration directories: Runtime state and Gluetun handoff paths.
- Host scripts: Backup, credential preflight, cleanup, and status helpers.
- Buccaneerr testing: Offline checks and live end-to-end validation.
- Support: Usage questions, bugs, documentation requests, and safe reporting routes.
- Contributing: Development setup and pull request expectations.
- Security policy: Supported versions and private vulnerability reporting.
- Code of Conduct: Community expectations and enforcement.
Privateerr is licensed under the Apache License 2.0. The bundled PIA manual-connection scripts remain under PIA's MIT license.
Fair winds, private keys below deck, and no VPN-client identity crises. π΄ββ οΈ