Updated for new version
This commit is contained in:
@@ -5,13 +5,16 @@ Deploy the Wikideck production container to an existing Kubernetes cluster using
|
||||
volume claim, a dedicated ServiceAccount, a ClusterIP Service, and a NetworkPolicy.
|
||||
An HTTPS Ingress is optional and disabled by default.
|
||||
|
||||
**Wikideck is an experimental RandomX testnet, not a production-ready public
|
||||
mainnet.** The updated application has independent validating nodes, fork choice,
|
||||
native NFTs, and encrypted wallet backup/recovery. It supplies no public bootnodes
|
||||
or deployed public network. Use test wallets and no valuable assets. This role
|
||||
**Wikideck is mainnet-first in code but remains an experimental, launch-gated
|
||||
candidate; the current production decision is NO-GO.** No public network,
|
||||
bootnodes, independent audit, or production readiness is established. The
|
||||
application includes validating nodes, fork choice, native NFTs, and encrypted
|
||||
local-wallet backup/recovery. Use test wallets and no valuable assets. This role
|
||||
deploys a **validator**, never a miner: mining is an explicitly started native CLI
|
||||
process outside the browser. Private keys, backups and passwords must stay off
|
||||
validator pods and out of Ansible variables.
|
||||
validator pods and out of Ansible variables. See the upstream
|
||||
[mainnet launch gates](https://github.com/ericomeehan/wikideck/blob/main/docs/mainnet-launch.md)
|
||||
and [operations/recovery guidance](https://github.com/ericomeehan/wikideck/blob/main/docs/operations-recovery.md).
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -24,13 +27,16 @@ validator pods and out of Ansible variables.
|
||||
- Kubeconfig access to create/update/read the resources in the target namespace,
|
||||
delete the role's Ingress/NetworkPolicy when disabled, and optionally create a
|
||||
Namespace. No cluster-admin access or in-cluster workload RBAC is needed.
|
||||
- **A published image built from Wikideck's production Dockerfile.** There is no
|
||||
- **A published, immutable image built from Wikideck's production Dockerfile.** There is no
|
||||
assumed official registry image. Set `wikideck_image` to your actual tagged or
|
||||
digest-pinned image. The role does not build/push images or install a cluster.
|
||||
preferably digest-pinned image. The role does not build/push images or install a cluster.
|
||||
Rebuild from the current source: the image must include Node 24, libstdc++, and
|
||||
the native RandomX executable, with `RANDOMX_BINARY` set by the image. An old
|
||||
browser-mining image is incompatible. Build and verify for your worker node
|
||||
architecture; do not assume a locally built image is multi-architecture.
|
||||
architecture; do not assume a locally built image is multi-architecture. The
|
||||
production Dockerfile defaults to mainnet and pins its profile/genesis into the
|
||||
image manifest; runtime settings cannot change that identity. Testnet is an
|
||||
explicit development fixture, not a public deployment profile.
|
||||
- For ingress: an ingress controller, DNS, and a trusted TLS Secret in the app
|
||||
namespace. Alternatively, configure cert-manager annotations and an existing
|
||||
issuer. The role does not install cert-manager or create an issuer.
|
||||
@@ -43,30 +49,23 @@ environment. Windows controllers must run Ansible through WSL or Linux container
|
||||
|
||||
Install this checkout into your playbook's role search path as `roles/wikideck`,
|
||||
or install it using an Ansible Galaxy Git role requirement named `wikideck`.
|
||||
[examples/playbook.yml](examples/playbook.yml) shows an HTTPS deployment with
|
||||
ingress-nginx and cert-manager. Replace the image, hostname, peer URLs, class,
|
||||
issuer, and controller namespace with real values before running it.
|
||||
|
||||
```yaml
|
||||
- name: Deploy a cluster-internal Wikideck instance
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: false
|
||||
roles:
|
||||
- role: wikideck
|
||||
vars:
|
||||
wikideck_image: registry.example.com/games/wikideck:1.0.0
|
||||
```
|
||||
[examples/playbook.yml](examples/playbook.yml) is the gated HTTPS deployment
|
||||
example with ingress-nginx and cert-manager. It requires an approved image
|
||||
digest, the image's verified manifest/genesis, launch gates, and real peers before
|
||||
it will change the cluster. There is intentionally no ungated, copy-and-run
|
||||
mainnet snippet: use a pre-task gate like the example. Empty gates cause the
|
||||
application to exit before listening, but do not by themselves prevent Kubernetes
|
||||
resources from being created.
|
||||
|
||||
Run the playbook on the controller, using its normal kubeconfig discovery or
|
||||
`wikideck_kubeconfig` / `wikideck_kube_context` overrides. Do not target every
|
||||
Kubernetes node: the role operates on the Kubernetes API, not over node SSH.
|
||||
|
||||
For a private local preview, forward the Service with
|
||||
For an explicitly built testnet development image, forward the Service with
|
||||
`kubectl -n wikideck port-forward service/wikideck 3001:80` and open
|
||||
<http://127.0.0.1:3001>. Keep the forwarding bind address at its loopback default.
|
||||
Wikideck already allows this local origin. Different hosts, ports, schemes, and
|
||||
browser profiles use different browser wallets.
|
||||
The app allows this local origin. Different hosts, ports, schemes, and browser
|
||||
profiles use different browser wallets. This does not bypass mainnet startup gates.
|
||||
|
||||
For remote browsers, enable ingress and set `wikideck_public_origin` to exactly
|
||||
`https://` followed by `wikideck_ingress_host` (no slash or path). HTTPS is needed
|
||||
@@ -81,6 +80,11 @@ Set `wikideck_peers` to a list of up to 16 compatible peer HTTPS origins, such a
|
||||
An empty list deliberately starts an **isolated validator**. There is no automatic
|
||||
discovery, bootnode list, or automatic reciprocal configuration: configure the
|
||||
other operators' nodes too. All nodes must run the same network/genesis/consensus.
|
||||
For mainnet, application startup additionally requires at least two distinct
|
||||
public HTTPS peer origins, an arrived image-pinned genesis time, the exact chain-ID
|
||||
approval, and explicit unaudited-risk acceptance. These switches are not launch
|
||||
approval from this role; the project currently records a NO-GO decision. The role
|
||||
does not discover or verify peer independence.
|
||||
|
||||
Peer RPC uses `/p2p/*` on the **same port 3001** as the UI/API; no separate TCP/UDP
|
||||
P2P Service or host networking is required. The existing `/` ingress path forwards
|
||||
@@ -149,6 +153,8 @@ All defaults are in [defaults/main.yml](defaults/main.yml).
|
||||
| `wikideck_image_pull_secrets` | `[]` | Names of existing registry Secrets in this namespace. |
|
||||
| `wikideck_peers` | `[]` | Up to 16 static peer origins; empty means isolated. |
|
||||
| `wikideck_allow_private_peers` | `false` | Explicit test-only private/HTTP peer permission. |
|
||||
| `wikideck_mainnet_launch` | empty | Exact 64-character chain-ID startup approval; leave empty unless a launch is formally approved. |
|
||||
| `wikideck_mainnet_risk_ack` | empty | Must equal `operator-accepts-unaudited-risk` to acknowledge residual risk; not a certification. |
|
||||
| `wikideck_public_origin` | empty | Additional allowed HTTPS browser origin; required with ingress. |
|
||||
| `wikideck_ingress_enabled` | `false` | Create TLS ingress; disabling removes the role's named ingress. |
|
||||
| `wikideck_ingress_host` | empty | DNS hostname, without scheme, port, or path. |
|
||||
@@ -161,6 +167,8 @@ All defaults are in [defaults/main.yml](defaults/main.yml).
|
||||
| `wikideck_storage_access_modes` | `[ReadWriteOnce]` | `ReadWriteOnce` or `ReadWriteOncePod`; never `ReadWriteMany`. |
|
||||
| `wikideck_resources` | see defaults | CPU/memory requests `250m`/`512Mi`, limits `1`/`1Gi`; small-validator starting point, not a capacity guarantee. |
|
||||
| `wikideck_node_selector` / `wikideck_tolerations` / `wikideck_affinity` | `{}` / `[]` / `{}` | Pod placement settings. |
|
||||
| `wikideck_trusted_proxies` | `[]` | Up to 16 literal proxy IPs/CIDRs; only trust actual edge source addresses after the edge overwrites forwarded headers. |
|
||||
| `wikideck_ops_port` | empty | Optional port for a diagnostics listener bound only to container loopback; never add it to the Service, Ingress, or NetworkPolicy. |
|
||||
| `wikideck_network_policy_enabled` | `true` | Manage network isolation; disabling deletes this role's policy. |
|
||||
| `wikideck_network_policy_ingress_from` | same-namespace pods | List of NetworkPolicy peers allowed to reach TCP 3001; empty list denies all ingress. |
|
||||
| `wikideck_network_policy_dns_to` | `kube-system` namespace | DNS peers allowed on UDP/TCP 53; adapt for custom/NodeLocal DNS. |
|
||||
@@ -182,10 +190,14 @@ entrypoint are deliberately preserved; no production fake-PoW fallback is added.
|
||||
`ReadWriteOncePod` if supported by your CSI driver. Do not force-delete an old
|
||||
pod on a partitioned node until it has been fenced; Recreate is not a
|
||||
distributed storage lock.
|
||||
- `/app/data/testnet/ledger.json` stores the block DAG and pending transfers;
|
||||
`/app/data/testnet-node.lock` exclusively locks the entire data directory.
|
||||
The old demo chain is separate, not imported, and has **no migration** to the
|
||||
new testnet. Back it up first; preferably use a fresh claim for the new network.
|
||||
- The active ledger is SQLite at `/app/data/<profile>/ledger.sqlite` (with WAL
|
||||
sidecars); `/app/data/<profile>-node.lock` exclusively locks that profile's data.
|
||||
A matching legacy `ledger.json` may be imported once and is retained as a
|
||||
recovery copy. The import path accepts at most 128 MiB and 10,000 blocks; these
|
||||
are legacy-import limits, not live SQLite disk bounds. Different profiles and
|
||||
chain identities must not share a writable claim. Preserve and back up existing
|
||||
data before changing image profile or genesis; incompatible chain data fails
|
||||
closed rather than resetting automatically.
|
||||
The process runs
|
||||
as UID/GID 1000 with `fsGroup: 1000`. Your storage driver must honor ownership
|
||||
settings, or the existing volume must already be writable by this identity.
|
||||
@@ -199,15 +211,18 @@ entrypoint are deliberately preserved; no production fake-PoW fallback is added.
|
||||
backup or use your CSI provider's documented snapshot procedure. Encrypt disks
|
||||
and backups, define retention, and test restores. Deleting a namespace or PVC
|
||||
can still destroy data depending on the underlying reclaim policy.
|
||||
- The current `node:backup` utility creates/verifies/restores ledger-only packages
|
||||
while the node is stopped. It does not contain browser wallets, secrets, or
|
||||
configuration, and it does not encrypt the package; store it in restricted,
|
||||
encrypted off-host storage and verify a restore before relying on it.
|
||||
- Full native RandomX revalidation runs before the server listens. Increase
|
||||
`wikideck_startup_probe_failure_threshold` and `wikideck_wait_timeout` together
|
||||
for your measured replay time, leaving scheduling/image-pull margin. A healthy
|
||||
empty node does not exercise the native cache or prove peer synchronization.
|
||||
- The app bounds the ledger to 128 MiB and 10,000 total DAG blocks, with 256
|
||||
pending transfers. Complete NFT states are retained per DAG node, so RAM may
|
||||
grow quadratically despite disk bounds. Whole-ledger rewrites and full replay
|
||||
are **not suitable for a long-lived public chain**; a larger PVC does not fix
|
||||
those application limits.
|
||||
- SQLite avoids whole-ledger JSON rewrites, but the node retains DAG records in
|
||||
memory, rebuilds state roots over the full NFT set, and revalidates proofs at
|
||||
startup. Long-chain capacity and archival-scale operation remain unresolved;
|
||||
a larger PVC does not fix memory, replay, or consensus-capacity limits.
|
||||
|
||||
### Crash recovery and resource sizing
|
||||
|
||||
@@ -268,12 +283,15 @@ your worker architecture and runtime security profile; HTTP health alone cannot
|
||||
detect every native engine failure. Do not grant privileged mode or disable
|
||||
seccomp as an untested performance workaround.
|
||||
|
||||
Wikideck does not currently configure Express `trust proxy`. Clients behind one
|
||||
proxy can therefore share an IP-based application rate limit. Review the
|
||||
application before public exposure; do not try to fix this by blindly trusting
|
||||
forwarded headers. The current app limits `/api` and `/p2p` together; default
|
||||
forwarded-header behavior can also produce express-rate-limit validation errors
|
||||
in logs. The role adds no authentication, WAF, or abuse protection. Eclipse,
|
||||
`WIKIDECK_TRUSTED_PROXIES` is empty/untrusted by default. Populate
|
||||
`wikideck_trusted_proxies` only with the literal source addresses/CIDRs actually
|
||||
used by the trusted edge; the app validates them at startup. The edge must
|
||||
overwrite forwarded headers, and network controls must prevent direct backend
|
||||
access. Do not copy a generic proxy range without verifying the cluster path.
|
||||
The optional `WIKIDECK_OPS_PORT` listener is loopback-only inside the pod and is
|
||||
not exposed by role resources. It is intended for local/container-exec checks,
|
||||
not an ingress endpoint. The role adds no authentication, WAF, or abuse
|
||||
protection. Eclipse,
|
||||
majority-hashpower, spam/DoS and reorganization risks remain application/protocol
|
||||
issues; deployment hardening does not make a public mainnet safe.
|
||||
|
||||
@@ -282,8 +300,8 @@ issues; deployment hardening does not make a public mainnet safe.
|
||||
[tests/render.yml](tests/render.yml) runs entirely offline: it validates inputs,
|
||||
renders/parses every template across default, ingress, existing-claim, storage
|
||||
class, isolated/public/private peers, custom HTTPS ports, deny-all, longer startup,
|
||||
and digest-image variants, and checks wiring/security
|
||||
invariants. It also checks that unsafe/invalid settings are rejected. Run it with
|
||||
digest-image, launch-gate, proxy-trust and diagnostics variants, and checks
|
||||
wiring/security invariants. It also checks that unsafe/invalid settings are rejected. Run it with
|
||||
`ansible-playbook -i tests/inventory tests/render.yml`.
|
||||
|
||||
[tests/test.yml](tests/test.yml) is a real-cluster smoke test using the local
|
||||
|
||||
Reference in New Issue
Block a user