This is Part 1 — preparation (configuration files, cluster plumbing, and TLS) before you install the provider.
Time: about 1–2 hours, depending on DNS and certificate issuance
Prerequisites
Before starting, ensure you have:
Required
- Kubernetes cluster deployed and verified
- Domain name that you control (e.g.,
provider.example.com) - Akash wallet with:
- Provider bid deposit is in AKT (0.5 AKT); keep AKT for gas. Recommended balance for multiple bids.
- Funded account (Fund Your Account)
Optional (if configured)
- GPU support enabled
- Persistent storage (Rook-Ceph) deployed
STEP 1 - Prepare Provider Wallet
Don’t have an Akash wallet yet?
Export Wallet Key
On your local machine (where you created your Akash wallet):
# Export your private keyprovider-services keys export <your-key-name>You’ll be prompted for your keyring passphrase. The output will look like:
-----BEGIN TENDERMINT PRIVATE KEY-----kdf: bcryptsalt: <salt-value>type: secp256k1
<base64-encoded-key>-----END TENDERMINT PRIVATE KEY-----Save this output to a file called key.pem.
Create Key Secret
Create a password for your key:
echo "your-secure-password" > key-pass.txtSTEP 2 - Setup on Control Plane Node
SSH into your Kubernetes control plane node and create the provider directory:
mkdir -p /root/providercd /root/providerUpload Files
Upload the following files to /root/provider/:
key.pem(your private key)key-pass.txt(your key password)
Encode Secrets
# Base64 encode the keyKEY_SECRET=$(cat /root/provider/key.pem | openssl base64 -A)
# Base64 encode the passwordKEY_PASSWORD=$(cat /root/provider/key-pass.txt | openssl base64 -A)
# Get your provider addressACCOUNT_ADDRESS=$(provider-services keys show <your-key-name> -a)STEP 3 - Install Helm and Add Akash Repository
Install Helm
# Download Helmwget https://get.helm.sh/helm-v4.0.1-linux-amd64.tar.gztar -zxvf helm-v4.0.1-linux-amd64.tar.gzinstall linux-amd64/helm /usr/local/bin/helm
# Verify installationhelm versionAdd Akash Helm Repository
helm repo add akash https://akash-network.github.io/helm-chartshelm repo updateSTEP 4 - Create Namespaces
Create all required namespaces:
kubectl create namespace akash-serviceskubectl create namespace leasekubectl label namespace akash-services akash.network=truekubectl label namespace lease akash.network=trueSTEP 5 - Install Akash RPC Node
Important: Running your own RPC node is a strict requirement for Akash providers. This removes dependence on public nodes and ensures reliable access to the blockchain.
Install Akash Node via Helm
The default installation uses blockchain snapshots for fast synchronization.
helm install akash-node akash/akash-node \ -n akash-servicesVerify Node is Running
kubectl -n akash-services get pods -l app=akash-nodeExpected output:
NAME READY STATUS RESTARTS AGEakash-node-1-0 1/1 Running 0 2mSync Time: The node will download and extract a blockchain snapshot, then sync to the latest block. This typically takes ~5 minutes. You can proceed with the next steps while it syncs.
STEP 6 - Create full provider configuration
Download Price Script
cd /root/providercurl -s https://raw.githubusercontent.com/akash-network/helm-charts/main/charts/akash-provider/scripts/price_script_generic.sh > price_script.shchmod +x price_script.shCreate provider.yaml
Replace the values with your actual configuration:
cat > /root/provider/provider.yaml << 'EOF'---from: "$ACCOUNT_ADDRESS"key: "$KEY_SECRET"keysecret: "$KEY_PASSWORD"domain: "provider.example.com"node: "http://akash-node-1:26657"withdrawalperiod: 12hchainid: "akashnet-2"attributes: - key: region value: us-west - key: host value: akash - key: tier value: community - key: organization value: "Your Organization" - key: country value: US - key: city value: "San Francisco" - key: location-type value: datacenter - key: capabilities/cpu value: intel - key: capabilities/cpu/arch value: x86-64 - key: capabilities/memory value: ddr4 - key: network-speed-up value: 1000 - key: network-speed-down value: 1000
email: [email protected]website: https://example.comorganization: Your Organization
# Pricing (in uact per unit)price_target_cpu: 1.60price_target_memory: 0.30price_target_hd_ephemeral: 0.02price_target_hd_pers_hdd: 0.01price_target_hd_pers_ssd: 0.03price_target_hd_pers_nvme: 0.10price_target_endpoint: 0.05price_target_ip: 5.00EOFAdd Persistent Storage Attributes (if you have Rook-Ceph)
If you configured persistent storage with Rook-Ceph, add the storage attributes to your provider.yaml:
attributes: # ... existing attributes ... - key: capabilities/storage/1/class value: <storage-class> - key: capabilities/storage/1/persistent value: "true"Example for beta3 (NVMe) storage class:
- key: capabilities/storage/1/class value: beta3 - key: capabilities/storage/1/persistent value: "true"Example for beta2 (SSD) storage class:
- key: capabilities/storage/1/class value: beta2 - key: capabilities/storage/1/persistent value: "true"Important: You can only advertise one storage class per provider. Choose either beta1 (HDD), beta2 (SSD), or beta3 (NVMe) based on what you configured in Rook-Ceph.
Add GPU Attributes (if you have GPUs)
If you configured GPU support, add GPU attributes to your provider.yaml:
attributes: # ... existing attributes ... - key: capabilities/gpu/vendor/nvidia/model/<model> value: "true" - key: capabilities/gpu/vendor/nvidia/model/<model>/ram/<ram> value: "true" - key: capabilities/gpu/vendor/nvidia/model/<model>/interface/<interface> value: "true" - key: capabilities/gpu/vendor/nvidia/model/<model>/interface/<interface>/ram/<ram> value: "true"Example for NVIDIA RTX 4090:
- key: capabilities/gpu/vendor/nvidia/model/rtx4090 value: "true" - key: capabilities/gpu/vendor/nvidia/model/rtx4090/ram/24Gi value: "true" - key: capabilities/gpu/vendor/nvidia/model/rtx4090/interface/pcie value: "true" - key: capabilities/gpu/vendor/nvidia/model/rtx4090/interface/pcie/ram/24Gi value: "true"Note: Model names should be lowercase with no spaces. List each GPU model you’re offering.
Complete Example with All Features
Here’s a full example showing GPU, persistent storage, and all optional attributes:
---from: "akash1..."key: "LS0tLS1CRUdJTi..."keysecret: "eHJiajdSS..."domain: "provider.example.com"node: "http://akash-node-1:26657"withdrawalperiod: 12hchainid: "akashnet-2"
attributes: # Location - key: region value: us-west - key: country value: US - key: city value: "San Francisco" - key: location-type value: datacenter - key: datacenter value: us-west-dc-1
# Required - key: host value: akash - key: tier value: community - key: organization value: "Your Organization"
# CPU - key: capabilities/cpu value: intel - key: capabilities/cpu/arch value: x86-64
# Memory - key: capabilities/memory value: ddr5ecc
# Network - key: network-speed-up value: 10000 - key: network-speed-down value: 10000
# GPU (if you have GPUs) - key: capabilities/gpu value: nvidia - key: capabilities/gpu/vendor/nvidia/model/h100 value: "true" - key: capabilities/gpu/vendor/nvidia/model/h100/ram/80Gi value: "true" - key: capabilities/gpu/vendor/nvidia/model/h100/interface/sxm value: "true" - key: capabilities/gpu/vendor/nvidia/model/h100/interface/sxm/ram/80Gi value: "true" - key: cuda value: "13.0"
# Persistent Storage (if you have Rook-Ceph) - key: capabilities/storage/1/class value: beta3 - key: capabilities/storage/1/persistent value: "true"
# SHM (Shared Memory) storage class (optional) - key: capabilities/storage/2/class value: ram - key: capabilities/storage/2/persistent value: "false"
website: https://example.comorganization: Your Organization
# Pricingprice_target_cpu: 1.60price_target_memory: 0.30price_target_hd_ephemeral: 0.02price_target_hd_pers_hdd: 0.01price_target_hd_pers_ssd: 0.03price_target_hd_pers_nvme: 0.10price_target_endpoint: 0.05price_target_ip: 5.00
# GPU pricing (format: "model=price,model=price" or "*=price" for all)price_target_gpu_mappings: "h100=840,*=840"Note: This example shows all possible configurations. Only include the sections relevant to your provider setup.
STEP 7 - Configure DNS
Configure at Your DNS Provider
Log into your DNS provider (Cloudflare, GoDaddy, Route53, etc.) and create the following DNS records:
1. Provider A Record:
Type: AName: provider (or your subdomain)Value: <your-provider-public-ip>TTL: 3600 (or Auto)2. Wildcard Ingress A Record:
Type: AName: *.ingress.provider (or *.ingress.your-subdomain)Value: <your-provider-public-ip>TTL: 3600 (or Auto)Example:
provider.example.com → 203.0.113.45*.ingress.provider.example.com → 203.0.113.45Verify DNS Propagation
After configuring DNS, verify both records resolve correctly:
# Check provider domaindig provider.example.com +short
# Check wildcard ingress domaindig test.ingress.provider.example.com +shortBoth should return your provider’s public IP.
Note: DNS propagation can take a few minutes. Wait until both records resolve before proceeding.
STEP 8 - Install Gateway API and NGINX Gateway Fabric
Install the Kubernetes Gateway API and NGINX Gateway Fabric (NGF) with port 443 in hostPorts so the data plane is ready to terminate HTTPS after you install the Akash Gateway chart. Next, complete STEP 9 – Let’s Encrypt and cert-manager to create TLS Secrets before you helm install akash-gateway in the install guide.
Install Gateway API CRDs
# Standard Gateway API CRDs (NGINX Gateway Fabric)kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v2.4.2" | kubectl apply -f -
# Experimental bundle (includes TCPRoute)kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yamlVerify:
kubectl get crd | grep gateway.networking.k8s.ioInstall NGINX Gateway Fabric
Save the following as /root/provider/values-nginx-gateway-fabric.yaml:
nginxGateway: gatewayClassName: nginx gwAPIExperimentalFeatures: enable: true leaderElection: enable: true config: logging: level: info resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi
nginx: kind: daemonSet service: type: ClusterIP container: hostPorts: - port: 80 containerPort: 80 - port: 443 containerPort: 443 - port: 8443 containerPort: 8443 - port: 8444 containerPort: 8444 - port: 5002 containerPort: 5002 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 1000m memory: 512MiInstall NGF (from /root/provider):
cd /root/provider
helm install ngf oci://ghcr.io/nginx/charts/nginx-gateway-fabric \ --create-namespace \ -n nginx-gateway \ -f values-nginx-gateway-fabric.yamlVerify:
kubectl -n nginx-gateway get podsSTEP 9 - Let’s Encrypt (cert-manager) and TLS Secrets
Required for all providers: The akash-gateway chart terminates HTTPS for deployment traffic. You must run cert-manager and supply TLS Secrets
wildcard-ingress-tlsandakash-default-tls.
- NGF in STEP 8 already includes 443 in
hostPorts. - Do not
helm installthe Akash provider until after STEP 11 (operators).
If you are migrating from ingress-nginx, see TLS migration to Gateway API.
STEP 1 - Install Cert-Manager
Add Jetstack Helm Repository
helm repo add jetstack https://charts.jetstack.iohelm repo updateInstall Cert-Manager
helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.19.1 \ --set crds.enabled=trueVerify Installation
kubectl -n cert-manager get podsExpected output:
NAME READY STATUS RESTARTS AGEcert-manager-xxx 1/1 Running 0 2mcert-manager-cainjector-xxx 1/1 Running 0 2mcert-manager-webhook-xxx 1/1 Running 0 2mSTEP 2 - Configure DNS Provider
The examples below use Cloudflare or Google Cloud DNS. If your public DNS is hosted elsewhere, you can still use Let’s Encrypt DNS-01 as long as cert-manager has a matching solver. See the full list of supported providers and configuration options in the cert-manager DNS-01 documentation.
Choose your DNS provider:
Create API Token
- Log into Cloudflare dashboard
- Go to “My Profile” → “API Tokens” → “Create Token”
- Use “Custom token” template
- Set permissions:
- Zone - DNS - Edit
- Zone - Zone - Read
- Zone Resources: Include - All Zones
- Copy the generated token
Create Secret
cat > cloudflare-secret.yaml << 'EOF'apiVersion: v1kind: Secretmetadata: name: cloudflare-api-token-secret namespace: cert-managertype: OpaquestringData: api-token: your-cloudflare-api-tokenEOF
kubectl apply -f cloudflare-secret.yamlCreate ClusterIssuer
cat > letsencrypt-issuer.yaml << 'EOF'apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: email: [email protected] # Replace with your email server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod-issuer-account-key solvers: - dns01: cloudflare: apiTokenSecretRef: key: api-token name: cloudflare-api-token-secret email: [email protected] # Replace with your email selector: dnsZones: - 'example.com' - 'ingress.example.com'EOF
kubectl apply -f letsencrypt-issuer.yamlCreate Service Account in GCP
-
Create Role:
- Name:
DNS Administrator Limited - ID:
dns.admin.light - Permissions:
dns.resourceRecordSets.*dns.changes.*dns.managedZones.list
- Name:
-
Create Service Account:
- Name:
dns01-solver - Assign the role created above
- Name:
-
Download Service Account Key (JSON format)
Create Secret
# Base64 encode the service account keycat your-gcp-service-account-key.json | base64 | tr -d ''
# Create the secretcat > gcp-dns-secret.yaml << 'EOF'apiVersion: v1kind: Secretmetadata: name: clouddns-gcp-dns01-solver-sa namespace: cert-managertype: Opaquedata: key.json: <your-base64-encoded-service-account-key>EOF
kubectl apply -f gcp-dns-secret.yamlCreate ClusterIssuer
cat > letsencrypt-issuer.yaml << 'EOF'apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencrypt-prodspec: acme: email: [email protected] # Replace with your email server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: letsencrypt-prod-issuer-account-key solvers: - dns01: cloudDNS: project: "your-gcp-project-id" serviceAccountSecretRef: name: clouddns-gcp-dns01-solver-sa key: key.jsonEOF
kubectl apply -f letsencrypt-issuer.yamlSTEP 3 - Request Wildcard Certificate
Create the namespace now so cert-manager can issue the Certificate into it. The same namespace is also created if you helm install akash-gateway first, but this order issues certificates before that chart.
kubectl create namespace akash-gatewayCreate a wildcard certificate in the akash-gateway namespace. cert-manager will create a TLS Secret named wildcard-ingress-tls, which matches the akash-gateway chart default for the https-wildcard listener.
cat > wildcard-cert.yaml << 'EOF'apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: wildcard-ingress namespace: akash-gatewayspec: secretName: wildcard-ingress-tls issuerRef: name: letsencrypt-prod kind: ClusterIssuer commonName: '*.yourdomain.com' dnsNames: - '*.yourdomain.com' - '*.ingress.yourdomain.com'EOF
kubectl apply -f wildcard-cert.yamlImportant: Replace
yourdomain.comwith your actual domain. Keep the*.ingress.entry as a separatednsName(wildcards do not cover an extra label under RFC 2818).
Verify Certificate
kubectl -n akash-gateway get certificatekubectl -n akash-gateway describe certificate wildcard-ingressWait for the certificate to show Ready: True (may take 1-2 minutes).
Default TLS secret for the catch‑all HTTPS listener
The chart also mounts akash-default-tls for the https-custom listener (other hostnames on port 443). For production, a short‑lived self‑signed cert is only to satisfy the reference until you replace it; point your issuer at this Secret name in a Certificate if you prefer a real cert there too. Minimal placeholder:
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout /tmp/default.key \ -out /tmp/default.crt \ -subj "/CN=default"
kubectl create secret tls akash-default-tls \ --cert=/tmp/default.crt \ --key=/tmp/default.key \ -n akash-gatewayConfirm cert-manager and namespaces
If kubectl create namespace akash-gateway failed because the namespace already exists, that is expected when re-running the guide.
kubectl -n cert-manager get podskubectl -n akash-gateway get secret wildcard-ingress-tls akash-default-tlsWhen describe certificate shows Ready: True and both Secrets exist, Let’s Encrypt is ready for the next step in the main install: Provider installation (install) — helm install akash-gateway. Do not install the akash/provider provider chart until after that and the operators step in the install guide.
End-to-end HTTPS test (after helm install akash-gateway)
openssl to test.ingress.<domain>:443 only checks the right certificate once the Gateway and listeners exist, which is after you run helm install akash-gateway. After Provider installation (install) — STEP 1 there:
echo "" | openssl s_client -connect test.ingress.yourdomain.com:443 -showcerts 2>&1 | \ openssl x509 -issuer -subject -dates -noout -text | \ grep -E '(Issuer:|Subject:|Not Before:|Not After :|DNS:)'Expected (Let’s Encrypt on the wire):
Issuer: C = US, O = Let's Encrypt, CN = R3Not Before: Nov 28 10:40:06 2025 GMTNot After : Feb 26 10:40:05 2026 GMTSubject: CN = *.yourdomain.comDNS:*.ingress.yourdomain.com, DNS:*.yourdomain.comCheck all cert-manager objects
kubectl get certificates,certificaterequests,orders,challenges -ATroubleshooting
Certificate Not Issuing
Check cert-manager logs:
kubectl -n cert-manager logs -l app=cert-managerCheck certificate status:
kubectl -n akash-gateway describe certificate wildcard-ingresskubectl -n akash-gateway get certificaterequestDNS-01 Challenge Failing
Verify API token secret:
kubectl -n cert-manager get secret cloudflare-api-token-secret -o yamlCheck token has correct permissions in Cloudflare dashboard:
- Zone - DNS - Edit
- Zone - Zone - Read
- Zone Resources: All Zones
Verify service account secret:
kubectl -n cert-manager get secret clouddns-gcp-dns01-solver-sa -o yamlCheck service account has DNS admin permissions in GCP:
dns.resourceRecordSets.*dns.changes.*dns.managedZones.list
Certificate Not Picked Up by Gateway
After cert-manager has issued the certificate (Ready: True), NGINX Gateway Fabric may need to reload. Restart the NGF data plane so it picks up the new Secret:
kubectl -n nginx-gateway rollout restart deployment -l app.kubernetes.io/name=nginx-gateway-fabricWait a minute, then test HTTPS again.
External links
Next — install the provider
When TLS Secrets are Ready and the steps above are complete, continue to Provider installation (install) to deploy akash-gateway, operators, and the akash/provider release.