Docker
These apply whether you run standalone Docker or Docker inside Kubernetes.Published Image
Use the published image when you do not need to modify the go-quai source:quainetwork Docker Hub organization.
Local Image Build
Use a minimal base image
alpine or distroless to reduce attack surface. Ensure the image includes libc dependencies required by go-quai’s CGO components (LevelDB, kawpow).Copy the chain config into the image
Expose both TCP and UDP on the p2p port
Dockerfile, declare both protocols:Basic Start
The container image usesgo-quai start by default, so a basic node can be started without passing any go-quai flags:
/mnt/ssd/quai-data with the host directory that should store chain data. If you already run go-quai on the host, this is commonly ~/.local/share/go-quai.
For mining, slice selection, environment selection, coinbase configuration, and other node runtime flags, use the same flags documented in the Run a Node guide. To pass go-quai flags to the container, include the start subcommand after the image name:
Container Runtime
Raise the file descriptor limit to 65536+
Allocate sufficient CPU
Allocate sufficient memory
Use local SSD storage for chain data
Publish p2p ports on the host
Enable pprof for diagnostics
Docker-Specific Options
These options are specific to containerized deployments:Public P2P Address
Most standalone Docker deployments can start without explicit p2p address flags. If the node is behind Kubernetes, host networking, a reverse proxy, or any setup where automatic NAT detection advertises the wrong address, pass an explicit public multiaddr:--node.external-addr is the public address peers should dial. --node.force-public skips NAT detection, and --node.portmap=false disables automatic NAT port mapping when the port is already explicitly published.
Kubernetes
These apply on top of the Docker requirements when orchestrating with Kubernetes.Resource Configuration
Use Guaranteed QoS to prevent CPU throttling
Raise file descriptor limits
ulimit -n.Networking
Use hostNetwork or hostPort for p2p ports
Set the external address flag to the host's public IP
Ensure network policies allow both ingress and egress
- Ingress to the p2p port from external peers
- Egress to other peers and DNS
Verify pod labels match network policy selectors
Storage
Use local PersistentVolumes for chain data
PersistentVolumeClaim backed by local SSD storage, not network-attached volumes.Pin pods to specific nodes
nodeSelector or node affinity to keep the pod on the same host as its local storage and maintain a stable network identity.Availability
Set a PodDisruptionBudget
Reverse Proxy (nginx)
If the node sits behind a reverse proxy (e.g., nginx on an edge VPS forwarding to the node), these settings are critical.Configuration
Use the stream module, not http
stream module.Set proxy_timeout to 300s or higher
Create separate server blocks for TCP and UDP
listen <port>; is TCP only. QUIC transport requires an explicit UDP listener. Without it, UDP traffic is silently dropped even if the port is exposed.Set proxy_responses to 0 for UDP
proxy_responses 1 closes the UDP session after a single response packet. QUIC requires many packets per session. Set to 0 (unlimited) and let proxy_timeout handle session cleanup.Raise worker_connections
Monitoring
- CPU Throttling
- File Descriptors
- pprof
- Proxy Connectivity
