Installation
Node64 is a single Docker container. You start it with one command or a small Compose file – on a Linux server, a VM, your NAS or a Raspberry Pi.
The ghcr.io/ipv64net/node64:latest image is currently being prepared for release. All commands on this page will work as soon as it is public.
Requirements
- Docker Engine on Linux. For the Compose examples you also need Docker Compose (
docker compose). - Architecture:
amd64(x86-64),arm64(aarch64) orarmv7(32-bit ARM). - A volume for
/data. It holds the database, keys and certificates. The rest of the container can run read-only. - Port 8080 free on the host. DNS64 adds port 53 (plus 443/853 depending on encryption), PROXY64 adds ports 80 and 443.
- No ipv64.net account required. Node64 runs fully standalone. What an account adds is explained in Connect to ipv64.net.
Platforms
| Platform | Architecture | Notes |
|---|---|---|
| Linux server, PC, mini PC, VM | linux/amd64 | The usual case. Any current Linux distribution with Docker. |
| Raspberry Pi | linux/arm64, linux/arm/v7 | With a 64-bit OS it runs arm64, with 32-bit Raspberry Pi OS (e.g. older models) armv7. Docker picks automatically. |
| NAS | amd64, arm64 or armv7 | Anywhere your NAS vendor offers Docker or containers from a Compose file. Put the /data volume on persistent storage. |
| Proxmox & co. | amd64 | Typically inside a Linux VM or a container with Docker installed. From there it works like on any Linux server. |
The image is built as a multi-arch image for linux/amd64, linux/arm64 and linux/arm/v7. Docker pulls the right variant automatically.
Installing with docker run
The quickest way – one command and you're done:
docker run -d --name node64 \
-p 8080:8080 \
-v node64-data:/data \
--restart unless-stopped \
ghcr.io/ipv64net/node64:latest
| Part | What it does |
|---|---|
-d --name node64 | Runs in the background with the container name node64. |
-p 8080:8080 | Web interface and API on port 8080 – HTTP and HTTPS on the same port. |
-v node64-data:/data | Named volume for all data. Survives updates. |
--restart unless-stopped | Important: after a restore or a reset, Node64 exits on its own and Docker brings it back up. |
Installing with docker compose
For long-term use we recommend a compose.yaml. Pick the variant that matches your modules, then start it with docker compose up -d in the file's folder.
For health checks, notifications and DynDNS, Docker's regular bridge network is all you need. A read-only file system and unprivileged ping are already set up.
services:
node:
image: ghcr.io/ipv64net/node64:latest
container_name: node64
restart: unless-stopped
ports:
- "8080:8080"
# - "8443:8443" # optional HTTPS-only port, also set NODE64_HTTPS_PORT=8443
volumes:
- node64-data:/data
environment:
NODE64_LOG_LEVEL: info
read_only: true
tmpfs:
- /tmp
sysctls:
- net.ipv4.ping_group_range=0 65535 # ICMP checks without root
volumes:
node64-data:
On the host network, DNS64 sees the real IP addresses of your devices and finds the router for local names by itself. PROXY64 can open streams on any port without you publishing each one. DynDNS's “interface” IPv6 mode also needs the host network.
services:
node:
image: ghcr.io/ipv64net/node64:latest
container_name: node64
restart: unless-stopped
network_mode: host # instead of ports: – UI on NODE64_HTTP_PORT (8080)
volumes:
- node64-data:/data
environment:
NODE64_LOG_LEVEL: info
read_only: true
tmpfs:
- /tmp
cap_add:
- NET_RAW # ICMP checks (sysctls are not possible on the host network)
volumes:
node64-data:
With the host network there is no ports: section. Node64 binds its ports directly on the host – only those an enabled module actually needs. Docker doesn't allow net.* sysctls in a container on the host network, so use cap_add: NET_RAW for ICMP checks instead.
The Docker container check type asks the Docker API for the state of your containers. For that, Node64 gets the socket and the group that owns it.
services:
node:
image: ghcr.io/ipv64net/node64:latest
container_name: node64
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- node64-data:/data
- /var/run/docker.sock:/var/run/docker.sock:ro
group_add:
- "996" # socket group: stat -c %g /var/run/docker.sock
environment:
NODE64_LOG_LEVEL: info
read_only: true
tmpfs:
- /tmp
sysctls:
- net.ipv4.ping_group_range=0 65535
volumes:
node64-data:
The group ID differs from system to system. Look it up like this:
stat -c %g /var/run/docker.sock
Whoever has the socket can control the host – even with :ro, which only protects the file, not the API. Node64 only ever sends read-only GET requests. To limit the risk further, put a docker-socket-proxy with CONTAINERS=1 in front and set NODE64_DOCKER_HOST=tcp://socket-proxy:2375 (example in Configuration).
All environment variables are listed in Configuration.
What lives in the /data volume
/data is the only directory Node64 writes to. Back up this volume and you have everything.
| Path | Contents |
|---|---|
/data/node64.db | SQLite database: settings, users, checks, channels, encrypted certificate keys and more. |
/data/secret.key | 32-byte key (AES-256-GCM) that encrypts the secrets in the database. Created on first start. |
/data/backups/ | Automatic backups before every database migration (the last 5 are kept) and the previous data after a restore. |
/data/tls/ | Self-signed certificate for the web interface (cert.pem, key.pem), created on first start. |
/data/dns64/ | DNS64: query log (dns64.db), allowlist (allowlist.txt), blocklists (lists/). |
/data/cdn64/cdn64.db | PROXY64: statistics and access log. |
/data/acme, /data/certs, /data/cache | Working directories for certificates, ACME and cache. |
Without /data/secret.key, channel tokens, SMTP passwords, the ipv64 API key and certificate keys can no longer be decrypted. How to back up properly is explained in Update & backup.
Ports
| Port | Used for | When open |
|---|---|---|
8080/tcp | Web interface and API – HTTP and HTTPS on the same port | always (configurable via NODE64_HTTP_PORT) |
8443/tcp | additional HTTPS-only port | only with NODE64_HTTPS_PORT |
53/udp, 53/tcp | DNS64 | only with the DNS64 module (port configurable) |
853/tcp, 853/udp | DNS64 via DoT or DoQ | only when enabled |
80/tcp, 443/tcp, 443/udp | Shared entry point: PROXY64, DoH, the UI under its own name, Let's Encrypt HTTP-01; HTTP/3 over 443/UDP | only while a module needs it |
In bridge mode you publish every port you need with -p or ports:, for example for DNS64:
ports:
- "8080:8080"
- "53:53/udp"
- "53:53/tcp"
- "443:443/tcp" # DoH (only when enabled)
- "853:853/tcp" # DoT
- "853:853/udp" # DoQ
Settings → Ports shows which ports the UI, DNS64 and the shared entry point use or want to use – including any conflicts.
Permissions and hardening
Node64 is frugal with privileges out of the box:
- Minimal image: built
FROM scratch– no operating system, no shell, just the binary and CA certificates. Time zones are embedded in the binary. - No root: the process runs as user and group
65532. read_only: true: the root file system can be read-only. Only/datahas to be writable.tmpfs: /tmp: an in-memory scratch area for temporary files.sysctls: net.ipv4.ping_group_range=0 65535: allows unprivileged ping for ICMP checks. Despite its name it also covers ICMPv6. Alternative:cap_add: NET_RAW.- Ports below 1024 without root: the binary carries
cap_net_bind_serviceandcap_net_rawas “permitted” only and activates them itself at startup – for ports 53, 80, 443 and ICMP. If they are missing (e.g. due tocap_dropor under Podman), Node64 still starts; only those features won't work.
HTTPS directly on the node
You don't need a separate HTTPS port: Node64 looks at the first byte of each connection to tell whether the browser speaks TLS. Both http://<host>:8080 and https://<host>:8080 work.
- Certificate: on first start Node64 creates a self-signed certificate, so your browser will warn you the first time. Later you can pick a proper certificate for the UI under Certificates (e.g. from Let's Encrypt), or mount your own files via
NODE64_TLS_CERTandNODE64_TLS_KEY. - TLS 1.2 or newer.
- Extra port: if you prefer a separate HTTPS-only port, set
NODE64_HTTPS_PORT=8443and publish8443.
Passkeys need HTTPS with a hostname (not just an IP address) – see Login & security.
IPv6 in the container
Node64 is dual-stack throughout. By default, however, Docker gives containers on the bridge network no IPv6. To run checks and DNS over IPv6 as well, give the network IPv6 (Docker 27 or newer) – or use network_mode: host:
networks:
default:
enable_ipv6: true
ipam:
config:
- subnet: fd00:64::/64 # ULA, Docker handles NAT66
If IPv6 is missing in the container, Node64 won't report it as an outage of your targets – it checks first whether the address family is reachable at all.
First visit
- Open
http://<host>:8080in your browser. - The setup wizard appears as long as no user exists. You choose the language, create the admin account (password at least 10 characters) and set the time zone, the node's name and its location.
- After submitting you are logged in right away. Continue with First steps.
There is no default password. For automated installs you can also have the admin created on the very first start via NODE64_ADMIN_USER and NODE64_ADMIN_PASSWORD (see Configuration).
Checking that Node64 is running
The image includes a Docker health check (/node64 healthcheck, every 30 seconds). After a short while docker ps shows (healthy):
docker ps --filter name=node64
The logs show what happens during startup:
docker logs -f node64
The /api/health endpoint answers without login, returning status, version and time:
curl http://localhost:8080/api/health
# {"status":"ok","version":…,"time":…}
The binary can also print the installed version directly:
docker exec node64 /node64 version
Something not working? Common causes and fixes are in FAQ & troubleshooting.
Something unclear, missing, or a question about Node64? Ask in the official forum v64.tech.