Sign inSign up

techroy23/docker-urnetwork

By techroy23

•Updated about 16 hours ago

Image
Networking
Internet of things
2

100K+

techroy23/docker-urnetwork repository overview

⁠Docker-UrNetwork

A minimal Docker setup that automatically fetches, updates, and runs the latest urNetwork Provider. The container is built on Alpine Linux, ensuring a minimal footprint. Includes built-in authentication handling, resilient restarts, scheduled in‑container updates (nightly build), and a built-in provider status endpoint.

Payout wallet — highly advised: set your earning wallet in the UrNetwork mobile app or website before expecting rewards. This container does not configure wallet consent; a registered provider without a wallet is not paid.

DockerHubGitHubInvite
Docker HubGitHub RepoInvite Link

⁠Features

  • Automated retrieval of the latest urNetwork Provider binary on startup (nightly build)
  • Daily in‑container update at 00:00 UTC (configurable with UPDATE_TIME)
  • Two auth modes: userpass (email/password) and authcode
  • Reuses a valid JWT and only re‑authenticates when the token is missing, expired or rejected
  • Persistent provider identity, credentials and version metadata
  • Built‑in provider status JSON on port 8080 (no separate vnStat/httpd)
  • Resilient provider execution with automatic retries
  • Provider process runs as the unprivileged urnetwork user (UID/GID 1000) via gosu
  • Optional proxy, all‑operators and auto‑register support

⁠Environment variables

VariableRequirementDescription
-e AUTH='userpass'
-e AUTH='authcode'
Optionaluserpass Log in with USER_AUTH and PASSWORD and keep the provider running.

authcode Log in with an auth code from https://ur.io/⁠ (AUTHCODE or the container argument).

Default is userpass
-e USER_AUTH <EMAIL>
and
-e PASSWORD <PASSWORD>
Required for
userpass
Your Email and Password.
The container will exit if not provided.
-e AUTHCODE <AUTH-CODE>Required for
authcode
Your authentication code.
The container will exit if not provided.
Generate one here: https://ur.io/⁠
-e API_URL
and
-e CONNECT_URL
OptionalCustom operator endpoints, for example API_URL='https://api.example.net' and CONNECT_URL='wss://connect.example.net'.
Passed as --api_url and --connect_url to both auth and provide.
Set both or neither — if only one is set the container exits instead of starting.
Ignored with a warning when ALL_OPERATORS=Y, because each operator uses its own endpoints.
Default is empty (the binary defaults to the public operator).
-e MAX_MEMORYOptionalSoft memory target passed as --max-memory, for example 1gib.
Default is empty (the binary picks a target from host memory).
-e VERBOSEOptionalProvider log verbosity: 0 off, 1 for -v, 2 for -vv.
Default is 0.
-e PROVIDER_PORTOptionalProvider status JSON port, passed as --port. http://localhost:8080/ returns version/status/diagnostics.
Set to 0 to disable the status server.
Default is 8080.
-e ALL_OPERATORSOptionalY/N. Y passes --all-operators and mines every operator in https://ur.xyz/operators.yml, with a separate state directory per operator.
N mines the default operator only.
Default is N.
-e AUTO_REGISTEROptionalY/N. Only used with ALL_OPERATORS=Y. Passes --auto-register, which implies --allow-client-registration, and requires HOTKEY_SEED_FILE.
Default is N.
-e HOTKEY_SEED_FILERequired for
AUTO_REGISTER=Y
Absolute path inside the container to an sr25519 hotkey seed file (32 raw bytes or 64 hex characters). The provider never creates this file.
-e ALLOW_CLIENT_REGISTRATIONOptionalauto/Y/N. Controls --allow-client-registration.

auto adds the flag only when /home/urnetwork/.urnetwork has no provider identity yet (a genuinely new install).
Y always adds it.
N never adds it.

Default is auto.
-e PROVIDER_ARGSOptionalExtra flags passed to provide, for example --adopt-legacy-provider-key or --max-memory=1gib.
Default is empty.
-e UPDATE_TIMEOptionalTime of the daily in‑container update, HH:MM in UTC.
Default is 00:00.
-v urnetwork_data:/home/urnetwork/.urnetwork
or
--mount type=volume,src=urnetwork_data,dst=/home/urnetwork/.urnetwork
RecommendedPersists the provider identity, JWT and registration state.
Without it, every new container becomes a new provider identity and loses its registration.
Both -v and --mount work, with a named volume or a host directory. See Persistent state and mount permissions⁠.
-v /path/to/your/proxy.txt:/app/proxy.txtOptionalMount a proxy configuration file from host to container.
Omit this line entirely if you don't want to use a proxy.
The proxy inside the proxy.txt should have this format ip:port:username:password.
See the sample below. one proxy per line.
Optional123.456.789.012:55555:myproxyusername:myproxypassword
234.567.890.123:44444:myproxyusername:myproxypassword
345.678.901.234:33333:myproxyusername:myproxypassword
456.789.012.345:22222:myproxyusername:myproxypassword
567.890.123.456:11111:myproxyusername:myproxypassword
-p 8080:8080OptionalProvider status JSON = http://localhost:8080/.
Exposing it publicly reveals provider diagnostics; restrict it to your monitoring network.
Set PROVIDER_PORT=0 to disable it.

⁠Persistent state and mount permissions

-v and --mount are equivalent here. All of these work:

# Named volume (Docker manages it; inherits urnetwork:urnetwork, mode 700)
-v urnetwork_data:/home/urnetwork/.urnetwork
--mount type=volume,src=urnetwork_data,dst=/home/urnetwork/.urnetwork

# Host directory (must be owned by UID/GID 1000)
-v /path/to/urnetwork_data:/home/urnetwork/.urnetwork
--mount type=bind,src=/path/to/urnetwork_data,dst=/home/urnetwork/.urnetwork

Prepare a host directory once before using it:

mkdir -p /path/to/urnetwork_data
sudo chown 1000:1000 /path/to/urnetwork_data
sudo chmod 700 /path/to/urnetwork_data

--mount type=bind fails when the host directory does not exist. -v creates a missing host path as root:root, which the urnetwork user cannot use, so create it first.

Do not chmod 777 the state directory. The provider requires /home/urnetwork/.urnetwork to be owned by the user it runs as and not writable by group/other. If it is world-writable, authentication fails with panic: registration parent must be owned and not writable by other users. Use chmod 700 instead.

The container starts as urnetwork (UID/GID 1000); no root process is used. Because a bind mount keeps the host's ownership, its source must be owned by UID/GID 1000 and not writable by group/other. If the source is owned by 1000 but world-writable (777), startup removes the group/other write bits. If it is owned by another UID, startup stops with a clear error: chown 1000:1000 <source>.

A named volume inherits ownership and mode from the image (/home/urnetwork/.urnetwork, urnetwork:urnetwork, mode 700), so it needs no manual preparation. If you start the container as root (--user 0), the entrypoint drops to urnetwork with gosu. Other non-root UIDs are rejected, because provider custody is tied to the runtime UID; chown the bind source to 1000:1000 instead.

Any other files mounted into the container, such as proxy.txt or a hotkey seed, must be readable by the runtime UID (1000 by default).

Upgrading: the state path moved from /root/.urnetwork to /home/urnetwork/.urnetwork, and the old files are root:root. Before starting the new image, give the existing volume or bind source to UID/GID 1000:

# Named volume (one-time; --user 0 is used only for this migration)
docker run --rm --user 0 -v urnetwork_data:/data \
  --entrypoint sh techroy23/docker-urnetwork:latest \
  -c 'chown -R 1000:1000 /data && chmod 700 /data'

# Host directory
sudo chown -R 1000:1000 /path/to/urnetwork_data

Otherwise the container cannot read the old state and registers a new identity.

⁠When to turn each flag on or off

FlagDefaultTurn it ON whenTurn it OFF when
ALLOW_CLIENT_REGISTRATIONautoA brand new install with an empty /home/urnetwork/.urnetwork (auto already does this), or you intentionally want a new provider identity/slot.Restoring an existing installation or any normal restart. Leaving it auto is correct for both cases.
ALL_OPERATORSNYou want one container to serve every operator in the published list. Each operator gets its own identity under ~/.urnetwork/operators/<domain>/.You want a single provider identity on the default operator (normal setup).
AUTO_REGISTERNYou use ALL_OPERATORS=Y and want each newly listed operator registered automatically from a Bittensor hotkey (HOTKEY_SEED_FILE required).You do not use ALL_OPERATORS, or you authenticate operators with your account instead.
PROVIDER_PORT8080You want the built-in status/diagnostics JSON.The port would be publicly reachable, or you do not need monitoring. Use 0.
API_URL + CONNECT_URLunsetYou serve a non-default operator. Set both together.You use the public default operator (normal setup).
MAX_MEMORYunsetThe host has a memory limit and you want the provider to stay under it, e.g. 1gib.You want the binary to size itself from host memory.
VERBOSE0You are debugging startup/connection problems.Normal operation.

⁠Run with username/password

# Option 1 : amd64 build
docker run -d --platform linux/amd64 \
  --name=urnetwork \
  --pull=always --restart=always \
  --log-driver=json-file --log-opt max-size=1m --log-opt max-file=1 \
  --cap-add=NET_ADMIN --cap-add=NET_RAW --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.ip_unprivileged_port_start=0 \
  -e AUTH='userpass' \
  -e USER_AUTH='[email protected]' \
  -e PASSWORD='mYv3rYsEcUr3dP@sSw0rD' \
  -v /path/to/your/proxy.txt:/app/proxy.txt \
  -v urnetwork_data:/home/urnetwork/.urnetwork \
  -p 8080:8080 \
  techroy23/docker-urnetwork:latest

# Option 2 : arm64 build
docker run -d --platform linux/arm64 \
  --name=urnetwork \
  --pull=always --restart=always \
  --log-driver=json-file --log-opt max-size=1m --log-opt max-file=1 \
  --cap-add=NET_ADMIN --cap-add=NET_RAW --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.ip_unprivileged_port_start=0 \
  -e AUTH='userpass' \
  -e USER_AUTH='[email protected]' \
  -e PASSWORD='mYv3rYsEcUr3dP@sSw0rD' \
  -v /path/to/your/proxy.txt:/app/proxy.txt \
  -v urnetwork_data:/home/urnetwork/.urnetwork \
  -p 8080:8080 \
  techroy23/docker-urnetwork:latest

⁠Run with auth code

  • Replace <AUTH-CODE> with the code you generated from https://ur.io/⁠
  • The code is only exchanged when no valid JWT exists, so restarts reuse the stored token.
# Option 1 : amd64 build
docker run -d --platform linux/amd64 \
  --name=urnetwork \
  --pull=always --restart=always \
  --log-driver=json-file --log-opt max-size=1m --log-opt max-file=1 \
  --cap-add=NET_ADMIN --cap-add=NET_RAW --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.ip_unprivileged_port_start=0 \
  -e AUTH='authcode' \
  -e AUTHCODE='<AUTH-CODE>' \
  -v /path/to/your/proxy.txt:/app/proxy.txt \
  -v urnetwork_data:/home/urnetwork/.urnetwork \
  -p 8080:8080 \
  techroy23/docker-urnetwork:latest

# Option 2 : arm64 build
docker run -d --platform linux/arm64 \
  --name=urnetwork \
  --pull=always --restart=always \
  --log-driver=json-file --log-opt max-size=1m --log-opt max-file=1 \
  --cap-add=NET_ADMIN --cap-add=NET_RAW --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.ip_unprivileged_port_start=0 \
  -e AUTH='authcode' \
  -e AUTHCODE='<AUTH-CODE>' \
  -v /path/to/your/proxy.txt:/app/proxy.txt \
  -v urnetwork_data:/home/urnetwork/.urnetwork \
  -p 8080:8080 \
  techroy23/docker-urnetwork:latest

⁠Run with every listed operator

docker run -d --platform linux/amd64 \
  --name=urnetwork \
  --pull=always --restart=always \
  --cap-add=NET_ADMIN --cap-add=NET_RAW --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.ip_unprivileged_port_start=0 \
  -e AUTH='userpass' \
  -e USER_AUTH='[email protected]' \
  -e PASSWORD='mYv3rYsEcUr3dP@sSw0rD' \
  -e ALL_OPERATORS='Y' \
  -v urnetwork_data:/home/urnetwork/.urnetwork \
  -p 8080:8080 \
  techroy23/docker-urnetwork:latest

Each operator is authenticated with your account when its token is missing. To register every operator from a Bittensor hotkey instead, add:

  -e ALL_OPERATORS='Y' \
  -e AUTO_REGISTER='Y' \
  -e HOTKEY_SEED_FILE='/home/urnetwork/.urnetwork/hotkey.seed' \
  -v /path/to/hotkey.seed:/home/urnetwork/.urnetwork/hotkey.seed:ro \

⁠Troubleshooting authentication

When authentication fails, the container now prints the provider's own output, even with DEBUG unset. Look for the last [ERROR] lines before "Will retry authentication", for example:

[ERROR]   panic: registration parent must be owned and not writable by other users
[ERROR] /home/urnetwork/.urnetwork is owned by another user or writable by group/other

In that case fix the mount permissions (chmod 700), not AUTHCODE or the password.

⁠Promo Video

⁠Promo

Tag summary

Content type

Image

Digest

sha256:59d46d2bc…

Size

91.5 MB

Last updated

about 16 hours ago

docker pull techroy23/docker-urnetwork