Skip to content

marc0janssen/nzbgetvpn

Repository files navigation

NZBGetVPN

Docker image for NZBGet with VPN leak protection, OpenVPN/WireGuard, Privoxy, SOCKS support, and operational hooks.

Built on top of binhex/arch-int-vpn: the base image owns VPN/provider lifecycle, this repo owns NZBGet integration, helper scripts, and documentation.

Thanks for the tip!

CI Status

Quality Checks Smoke Test Security Scan Drift Radar Release Orchestration

Table of Contents

Versions

NZBGet release information

  • NZBGetVPN image/codebase version: 5.5.21
  • NZBGET Current stable version: 26.1
  • NZBGET Current testing version: 26.2-testing-20260508
  • Base image stable tag: binhex/arch-int-vpn:2026050402
  • Base image testing tag: binhex/arch-int-vpn:2026050402

The NZBGetVPN image/codebase version is stored in VERSION.

Quick Start

Default NZBGet login is nzbget / tegbzn6789. Change this immediately after first start.

OpenVPN:

docker run -d \
  --name=nzbgetvpn \
  --cap-add=NET_ADMIN \
  --restart unless-stopped \
  -p 6789:6789 \
  -p 8118:8118 \
  -v /path/to/config:/config \
  -v /path/to/data:/data \
  -v /etc/localtime:/etc/localtime:ro \
  -e VPN_ENABLED=yes \
  -e VPN_CLIENT=openvpn \
  -e VPN_PROV=custom \
  -e LAN_NETWORK=192.168.1.0/24 \
  -e NAME_SERVERS=1.1.1.1,1.0.0.1 \
  -e ENABLE_PRIVOXY=yes \
  -e STRICT_PORT_FORWARD=no \
  -e UMASK=000 \
  -e PUID=1000 \
  -e PGID=1000 \
  marc0janssen/nzbgetvpn:stable

WireGuard:

docker run -d \
  --name=nzbgetvpn \
  --privileged=true \
  --sysctl="net.ipv4.conf.all.src_valid_mark=1" \
  --restart unless-stopped \
  -p 6789:6789 \
  -p 8118:8118 \
  -v /path/to/config:/config \
  -v /path/to/data:/data \
  -v /etc/localtime:/etc/localtime:ro \
  -e VPN_ENABLED=yes \
  -e VPN_CLIENT=wireguard \
  -e VPN_PROV=custom \
  -e LAN_NETWORK=192.168.1.0/24 \
  -e NAME_SERVERS=1.1.1.1,1.0.0.1 \
  -e ENABLE_PRIVOXY=yes \
  -e STRICT_PORT_FORWARD=no \
  -e UMASK=000 \
  -e PUID=1000 \
  -e PGID=1000 \
  marc0janssen/nzbgetvpn:stable

Compose

Ready-to-edit examples live in examples/.

Volumes

Path Required Description
/config Yes Persistent config, OpenVPN profiles and WireGuard profiles.
/data Yes Downloads and optional scripts/state.
/etc/localtime:ro Recommended Keeps container time aligned with host time.

Core Environment

Variable Required Example Purpose
VPN_ENABLED Usually yes Enable/disable VPN behavior.
VPN_CLIENT If VPN enabled openvpn, wireguard Select VPN implementation.
VPN_PROV If VPN enabled custom Provider key for base image handling.
LAN_NETWORK If VPN enabled 192.168.1.0/24 Allowed LAN CIDR(s) for local services.
NAME_SERVERS Recommended 1.1.1.1,1.0.0.1 Resolver list inside container.
ENABLE_PRIVOXY No yes Enables Privoxy on 8118/tcp.
PUID / PGID No 1000 Runtime ownership.
UMASK No 000 File creation mask.
BUNDLED_SYNC_POLICY No smart, force, preserve Controls startup sync behavior for bundled /data templates (default smart; docs still sync in smart mode).

Boolean-style toggles across this project accept yes/no, true/false, and 1/0.

Script Docs

Script details are split into smaller files to reduce maintenance overhead and merge conflicts.

  • Index: data/scripts/README.md
  • Per-script docs under data/scripts/docs/
  • Bundled script docs are also synced into the container at /data/scripts/docs/.
  • Add nzbgetvpn: preserve-local in managed runtime script files (for example /data/scripts/lib.sh) to keep local custom edits when BUNDLED_SYNC_POLICY=smart; README/docs files ignore this marker and still update.
  • For quick local diagnostics, run /data/scripts/container/doctor.sh inside the container.
  • To force-restore managed bundled templates and then run diagnostics, use /data/scripts/container/doctor.sh --heal (creates backups under /data/backups/doctor-heal-<timestamp>/).
  • For host-side execution via a running container, use ./data/scripts/host/run-container-helper.sh.

Provider Setup

OpenVPN

  1. Start once so /config/openvpn/ is created.
  2. Stop container.
  3. Put one .ovpn and referenced files in /config/openvpn/.
  4. Start container.

WireGuard

  1. Start once so /config/wireguard/ is created.
  2. Stop container.
  3. Put one .conf in /config/wireguard/.
  4. Start container.

Health, Self-Test, and Unhealthy Actions

  • Docker healthcheck runs /root/healthcheck.sh.
  • Internal self-test is controlled by VPN_SELFTEST_ENABLED.
  • Unhealthy behavior is controlled by VPN_UNHEALTHY_*.
  • Dedicated notifications use NOTIFY_SELFTEST_STATE_SCRIPT and NOTIFY_UNHEALTHY_SCRIPT.

Build and Update

Use build.sh, build-testing.sh, build-testing-local.sh, and scripts in scripts/.

Docker Hub builds

Scripts: build.sh (stable image, Dockerfile) and build-testing.sh (testing image, Dockerfile-testing). Both push to Docker Hub via docker buildx build ... --push and run docker pushrm for README-containers.md.

Optional env files (gitignored, not pushed to GitHub)

File Template Used by
build.env build.env.example build.sh
build-testing.env build-testing.env.example build-testing.sh

Copy and edit: cp build.env.example build.env (same idea for testing).

Place the file in the repository root, next to the matching script. Format: POSIX shell assignments (KEY=value), # comments.

Variable Default when unset Purpose
DOCKER_IMAGE_REPO marc0janssen/nzbgetvpn Docker Hub repository (namespace/name, no tag). Used for all -t arguments and for docker pushrm.
BUILD_PLATFORM linux/amd64,linux/arm64 Passed to docker buildx build --platform.

Precedence: built-in defaults, then assignments in the env file if present, then DOCKER_IMAGE_REPO / BUILD_PLATFORM already exported in your shell (exports win over the file), then --docker-repo and --platform on the command line (strongest).

./build.sh --docker-repo otheruser/nzbgetvpn --platform linux/amd64
./build-testing.sh --docker-repo otheruser/nzbgetvpn

Local registry build

Script: build-testing-local.sh. Use this for pushing testing images to your own Docker registry (home lab, LAN, or VPN), instead of Docker Hub. Behaviour matches build-testing.sh for NZBGet bumps (newest, --sha256, --accept-downloaded-sha256) and base image updates (--base), but the build uses Dockerfile-testing and ends with:

sudo docker buildx build ... --push

You need a working buildx builder, permission for sudo docker, and a registry that accepts pushes (login with docker login where required).

Tags pushed to your registry (repository = value of LOCAL_REPO, without tag):

Tag Meaning
<NZBGET_VERSION> Taken from Dockerfile-testing (ENV NZBGET_VERSION), for example the testing train string.
<NZBGET_VERSION>-image-v<semver> Same NZBGet version plus codebase semver from VERSION at repo root.
testing Convenience rolling tag for the latest push from this script.

There is no docker pushrm step; Docker Hub README sync is only for build-testing.sh / build.sh.

Optional config file build-testing-local.env

  • Git: build-testing-local.env is listed in .gitignore so your registry hostname stays local and is not pushed to GitHub. The repository ships build-testing-local.env.example as a template; copy it and edit: cp build-testing-local.env.example build-testing-local.env
  • Location: repository root, next to build-testing-local.sh (the script loads build-testing-local.env from that directory only).
  • Format: POSIX shell assignments, one variable per line; lines starting with # are comments. No export keyword needed.
  • If the file is missing: the script still runs; built-in defaults apply, and you can pass --repo / --platform anytime.
Variable Default when unset Purpose
LOCAL_REPO 192.168.1.1:5000/nzbgetvpn Image repository on your registry: host:port/path/name with no image tag.
LOCAL_PLATFORM linux/amd64 Value passed to docker buildx build --platform (comma-separated for multi-arch).

Precedence (each step overrides the previous):

  1. Built-in defaults in the script.
  2. Assignments in build-testing-local.env, if that file exists.
  3. LOCAL_REPO / LOCAL_PLATFORM already set in the environment when you start the script (exported values are not overwritten by the file, so your shell can override values from build-testing-local.env).
  4. --repo and --platform on the command line (highest priority).

Examples

./build-testing-local.sh
./build-testing-local.sh --repo 192.168.178.200:5050/nzbgetvpn
./build-testing-local.sh newest --accept-downloaded-sha256 --platform linux/amd64,linux/arm64
export LOCAL_REPO=192.168.178.200:5050/nzbgetvpn
./build-testing-local.sh

Use ./build-testing-local.sh --help for the full flag list.

CI quality checks (run locally and in GitHub Actions):

  • Workflow: .github/workflows/quality-checks.yml
  • Trigger: push and pull_request
  • Scope:
    • unresolved merge conflict marker scan (<<<<<<<, =======, >>>>>>>)
    • Docker Hub README size guard (README-containers.md must stay under 25000 bytes)
    • shell syntax validation (sh -n / bash -n based on shebang)
    • shellcheck for static shell linting
    • shfmt --diff for formatting drift detection
    • rotate-defaults docs drift check (./scripts/sync-rotate-defaults-doc.sh check)
    • AGENTS.md validation checklist commands
    • optional conventional commit lint (enable with CI_CONVENTIONAL_COMMIT_LINT=true)
./scripts/ci-quality-checks.sh

Temporary shellcheck baseline is enabled by default for known legacy findings. Run strict mode locally (no excludes) with:

SHELLCHECK_EXCLUDES= ./scripts/ci-quality-checks.sh

Optional conventional commit lint (for changelog/version flow consistency):

CI_CONVENTIONAL_COMMIT_LINT=true CI_CONVENTIONAL_COMMIT_RANGE=origin/develop..HEAD ./scripts/ci-quality-checks.sh

Runtime smoke test (run locally and in GitHub Actions):

  • Workflow: .github/workflows/smoke-test.yml
  • Trigger: push and pull_request
  • Scope:
    • container boot and running-state validation
    • NZBGet 6789/tcp and Privoxy 8118/tcp reachability
    • healthcheck and direct self-test execution success
./scripts/ci-smoke-test.sh

Full smoke-test documentation: ci/README.md On Apple Silicon or other non-amd64 hosts, use SMOKE_PLATFORM=linux/amd64.

Troubleshooting

Symptom Check
LAN_NETWORK is not set Set valid CIDR like 192.168.1.0/24.
VPN_REMOTE_PORT is not set Verify provider profile and parsed endpoint values.
VPN_CRON_SCHEDULE doesn't run Use 5-field cron and executable script path.
Container exits and stays down Add restart policy (unless-stopped).

Security

See SECURITY.md.
Do not commit secrets, VPN profiles, keys, tokens, or .env files.

About

Combination of binhex's nzbget docker with openvpn access

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors