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.
- CI Status
- Versions
- Quick Start
- Compose
- Volumes
- Core Environment
- Script Docs
- Provider Setup
- Health, Self-Test, and Unhealthy Actions
- Build and Update (includes Docker Hub builds, local registry build)
- Troubleshooting
- Security
- 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.
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:stableWireGuard:
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:stableReady-to-edit examples live in examples/.
| 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. |
| 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 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-localin managed runtime script files (for example/data/scripts/lib.sh) to keep local custom edits whenBUNDLED_SYNC_POLICY=smart; README/docs files ignore this marker and still update. - For quick local diagnostics, run
/data/scripts/container/doctor.shinside 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.
- Start once so
/config/openvpn/is created. - Stop container.
- Put one
.ovpnand referenced files in/config/openvpn/. - Start container.
- Start once so
/config/wireguard/is created. - Stop container.
- Put one
.confin/config/wireguard/. - Start container.
- 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_SCRIPTandNOTIFY_UNHEALTHY_SCRIPT.
Use build.sh, build-testing.sh, build-testing-local.sh, and scripts in scripts/.
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/nzbgetvpnScript: 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.envis listed in.gitignoreso your registry hostname stays local and is not pushed to GitHub. The repository shipsbuild-testing-local.env.exampleas 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 loadsbuild-testing-local.envfrom that directory only). - Format: POSIX shell assignments, one variable per line; lines starting with
#are comments. Noexportkeyword needed. - If the file is missing: the script still runs; built-in defaults apply, and you can pass
--repo/--platformanytime.
| 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):
- Built-in defaults in the script.
- Assignments in
build-testing-local.env, if that file exists. LOCAL_REPO/LOCAL_PLATFORMalready set in the environment when you start the script (exported values are not overwritten by the file, so your shell can override values frombuild-testing-local.env).--repoand--platformon 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.shUse ./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:
pushandpull_request - Scope:
- unresolved merge conflict marker scan (
<<<<<<<,=======,>>>>>>>) - Docker Hub README size guard (
README-containers.mdmust stay under25000bytes) - shell syntax validation (
sh -n/bash -nbased on shebang) shellcheckfor static shell lintingshfmt --difffor 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)
- unresolved merge conflict marker scan (
./scripts/ci-quality-checks.shTemporary shellcheck baseline is enabled by default for known legacy findings. Run strict mode locally (no excludes) with:
SHELLCHECK_EXCLUDES= ./scripts/ci-quality-checks.shOptional conventional commit lint (for changelog/version flow consistency):
CI_CONVENTIONAL_COMMIT_LINT=true CI_CONVENTIONAL_COMMIT_RANGE=origin/develop..HEAD ./scripts/ci-quality-checks.shRuntime smoke test (run locally and in GitHub Actions):
- Workflow:
.github/workflows/smoke-test.yml - Trigger:
pushandpull_request - Scope:
- container boot and running-state validation
- NZBGet
6789/tcpand Privoxy8118/tcpreachability - healthcheck and direct self-test execution success
./scripts/ci-smoke-test.shFull smoke-test documentation: ci/README.md
On Apple Silicon or other non-amd64 hosts, use SMOKE_PLATFORM=linux/amd64.
| 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). |
See SECURITY.md.
Do not commit secrets, VPN profiles, keys, tokens, or .env files.