Helm & Kubernetes
Esta página aún no está disponible en tu idioma.
This guide explains how to deploy Rafiki using Helm charts on a Kubernetes cluster. Helm is a package manager for Kubernetes that allows you to define, install, and upgrade complex Kubernetes applications through Helm charts.
Rafiki uses the following key infrastructure components:
- PostgreSQL: Used for storing application data, grants, and Open Payments resources
- Redis: Used for caching and session management
- TigerBeetle (recommended): High-performance accounting database for financial transaction processing and ledger management
Before you begin, ensure you have the following:
- Kubernetes cluster deployed
- kubectl installed and configured to access your cluster
- Helm installed
Add the official Interledger Helm repository which contains the Rafiki charts:
helm repo add interledger https://interledger.github.io/charts/interledgerhelm repo updateYou can list the available Rafiki charts:
helm search repo interledger/rafikiThis will show you the available chart versions for the different Rafiki components:
interledger/rafiki-authinterledger/rafiki-backendinterledger/rafiki-frontend
Create separate values files for each Rafiki service to customize your deployment. You can start with minimal configurations and add more settings as needed.
Create auth-values.yaml:
# Minimal auth service configurationnodeEnv: productionlogLevel: info
# Database configuration (update with your credentials)databaseUrl: secretKeyRef: name: rafiki-secrets key: DATABASE_URL
# Redis configurationredisUrl: secretKeyRef: name: rafiki-secrets key: REDIS_URL
# Identity server configurationidentityServer: domain: 'https://your-domain.com/idp' serverSecret: secretKeyRef: name: rafiki-secrets key: IDENTITY_SERVER_SECRET
# Cookie signing keycookieKey: secretKeyRef: name: rafiki-secrets key: COOKIE_KEY
# Service configurationservice: - name: service type: ClusterIP ports: - port: 3006 targetPort: 3006 protocol: TCP name: auth - port: 3003 targetPort: 3003 protocol: TCP name: admin - port: 3007 targetPort: 3007 protocol: TCP name: introspection - port: 3009 targetPort: 3009 protocol: TCP name: interactionCreate backend-values.yaml:
# Minimal backend service configurationnodeEnv: productionlogLevel: infoinstanceName: 'your-rafiki-instance'
# Database configurationdatabaseUrl: secretKeyRef: name: rafiki-secrets key: DATABASE_URL
# Redis configurationredisUrl: secretKeyRef: name: rafiki-secrets key: REDIS_URL
# Auth service URLsauth: grantUrl: http://rafiki-auth-service.default:3006 introspectionUrl: http://rafiki-auth-service.default:3007
# ILP configurationilp: host: 'https://your-domain.com' address: test.your-instance connector: 'http://rafiki-backend-service.default:3002' streamSecret: secretKeyRef: name: rafiki-secrets key: STREAM_SECRET
# Webhook configurationwebhook: url: https://your-wallet.com/webhooks/rafiki
# Key configurationkey: id: your-unique-key-id pvk: '' # Will auto-generate if empty
# Webhook signature secretwebhookSignatureSecret: secretKeyRef: name: rafiki-secrets key: SIGNATURE_SECRET
# Service configurationservice: - name: service type: ClusterIP ports: - port: 3000 targetPort: 3000 protocol: TCP name: open-payments - port: 3001 targetPort: 3001 protocol: TCP name: admin - port: 3002 targetPort: 3002 protocol: TCP name: connectorCreate frontend-values.yaml:
# Minimal frontend service configurationnodeEnv: productionlogLevel: info
# Service URLsserviceUrls: GRAPHQL_URL: http://rafiki-backend-service.default:3001/graphql OPEN_PAYMENTS_URL: https://your-domain.com/
# Port configurationport: 3010
# Service configurationservice: - name: service type: ClusterIP ports: - port: 3010 targetPort: 3010 protocol: TCP name: http
# Kratos configuration (if using authentication)kratos: enabled: falseBefore installing the services, create the required secrets:
kubectl create secret generic rafiki-secrets \ --from-literal=DATABASE_URL="postgresql://username:password@rafiki-postgresql:5432/rafiki" \ --from-literal=REDIS_URL="redis://rafiki-redis:6379" \ --from-literal=IDENTITY_SERVER_SECRET="your-identity-server-secret" \ --from-literal=COOKIE_KEY="your-cookie-signing-key" \ --from-literal=STREAM_SECRET="your-stream-secret" \ --from-literal=SIGNATURE_SECRET="your-webhook-signature-secret"Install each Rafiki service using the appropriate values file:
# Install auth servicehelm install rafiki-auth interledger/rafiki-auth -f auth-values.yaml
# Install backend servicehelm install rafiki-backend interledger/rafiki-backend -f backend-values.yaml
# Install frontend servicehelm install rafiki-frontend interledger/rafiki-frontend -f frontend-values.yamlIf you want to install to a specific namespace:
kubectl create namespace rafiki
helm install rafiki-auth interledger/rafiki-auth -f auth-values.yaml -n rafikihelm install rafiki-backend interledger/rafiki-backend -f backend-values.yaml -n rafikihelm install rafiki-frontend interledger/rafiki-frontend -f frontend-values.yaml -n rafikiCheck the status of your deployments:
# Check Helm releaseshelm list
# Check running podskubectl get pods
# Check deployed serviceskubectl get services
# Check logs for any issueskubectl logs -l app.kubernetes.io/name=rafiki-authkubectl logs -l app.kubernetes.io/name=rafiki-backendkubectl logs -l app.kubernetes.io/name=rafiki-frontendEach Rafiki service can be configured via environment variables through Helm values. Below are the complete environment variable configurations for each service:
Auth service
The Rafiki auth service is responsible for handling Open Payments authorization and grant management. It implements the Open Payments authorization server specification and manages access tokens, grants, and interactions. The auth service connects to a PostgreSQL database to store grant-related data and uses Redis for session management.
Ports exposed:
3003(admin) - Auth Admin API for managing grants and access tokens3006(auth) - Open Payments authorization server endpoint3007(introspection) - Access token introspection endpoint3009(interaction) - User interaction endpoint for grant flows
Required values
| Helm variable | Default | Description |
|---|---|---|
auth.postgresql.host,auth.postgresql.port,auth.postgresql.username,auth.postgresql.database,auth.postgresql.password | postgresql://postgres:password@localhost:5432/auth_development | The URL of the Postgres database storing your Open Payments grant data. For Helm, these components are provided individually. |
auth.server.domain | undefined | The public endpoint for your Rafiki instance’s public Open Payments routes. |
auth.cookieKey | undefined | The koa KeyGrip key that is used to sign cookies for an interaction session. |
auth.identityServer.domain | undefined | The URL of your IdP’s server, used by the authorization server to inform an Open Payments client of where to redirect the end-user to start interactions. |
auth.identityServer.secret | undefined | A shared secret between the authorization server and the IdP server; the authorization server will use the secret to secure its IdP-related endpoints. When the IdP server sends requests to the authorization server, the IdP server must provide the secret via an x-idp-secret header. |
auth.redis.host,auth.redis.port | redis://127.0.0.1:6379 | The connection URL for Redis. For Helm, these components are provided individually. |
Conditionally required values
| Helm value name | Default | Description |
|---|---|---|
auth.trustProxy | false | Must be set to true when running Rafiki behind a proxy. When true, the X-Forwarded-Proto header is used to determine if connections are secure. |
Optional values
| Helm value name | Default | Description |
|---|---|---|
auth.accessToken.deletionDays | 30 | The days until expired and/or revoked access tokens are deleted. |
auth.accessToken.expirySeconds | 600 (10 minutes) | The expiry time, in seconds, for access tokens. |
auth.adminApi.signatureVersion | 1 | The version of the request signing algorithm used to generate signatures. |
auth.adminAPI.signatureTtlSeconds | 30 | The TTL, in seconds, for which a request’s signature will be valid. |
auth.port.admin | 3003 | The port of your Rafiki Auth Admin API server. |
auth.port.auth | 3006 | The port of your Open Payments authorization server. |
auth.workers.cleanup | 1 | The number of workers processing expired or revoked access tokens. |
auth.enableManualMigrations | false | When true, you must run the auth Postgres database manually with the command npm run knex – migrate:latest –envproduction |
auth.interaction.incomingPayment | false | When true, incoming Open Payments grant requests are interactive |
auth.interactionExpirySeconds | 600 (10 minutes) | The time, in seconds, for which a user can interact with a grant request before the request expires. |
auth.port.interaction | 3009 | The port number of your Open Payments interaction-related APIs. |
auth.port.introspection | 3007 | The port of your Open Payments access token introspection server. |
auth.interaction.listAll | true | When true, grant requests that include a list-all action will require interaction. In these requests, the client asks to list resources that it did not create. |
auth.logLevel | info | Pino log level |
auth.nodeEnv | development | The type of node environment: development, test, or production. |
auth.interaction.quote | false | When true, quote grants are interactive. |
auth.redis.tlsCaFile | '' | Redis TLS config |
auth.redis.tlsCertFile | '' | Redis TLS config |
auth.redis.tlsKeyFile | '' | Redis TLS config |
auth.grant.waitSeconds | 5 | The wait time, in seconds, included in a grant request response (grant.continue). |
Backend service
The Rafiki backend service handles the core Open Payments functionality and business logic. It exposes the Open Payments resource server APIs for wallet addresses, incoming payments, outgoing payments, and quotes. The backend also includes an ILP connector for sending and receiving Interledger packets. It connects to PostgreSQL for storing Open Payments resources, Redis for caching, and optionally TigerBeetle for high-performance accounting.
Ports exposed:
3000(openPayments) - Open Payments resource server API3001(admin) - Backend Admin API and GraphQL endpoint3002(connector) - ILP connector for sending and receiving packets3005(autoPeering) - Auto-peering service (when enabled)
Required values
| Helm value name | Default | Description |
|---|---|---|
backend.serviceUrls.AUTH_SERVER_GRANT_URL | undefined | The endpoint on your Open Payments authorization server to grant a request. |
backend.serviceUrls.AUTH_SERVER_INTROSPECTION_URL | undefined | The endpoint on your Open Payments authorization server to introspect an access token. |
backend.postgresql.host,backend.postgresql.port,backend.postgresql.username,backend.postgresql.database,backend.postgresql.password | postgresql://postgres:password@localhost:5432/development | The Postgres database URL of the database storing your resource data. For Helm, these components are provided individually. |
backend.serviceUrls.EXCHANGE_RATES_URL | undefined | The endpoint your Rafiki instance uses to request exchange rates. |
backend.ilp.address | undefined | The ILP address of your Rafiki instance. |
backend.ilp.connectorUrl | undefined | The ILP connector address where ILP packets are received. |
backend.key.id | undefined | Your Rafiki instance’s client key ID. |
backend.serviceUrls.OPEN_PAYMENTS_URL | undefined | The public endpoint of your Open Payments resource server. |
backend.redis.host,backend.redis.port | redis://127.0.0.1:6379 | The Redis URL of the database handling ILP packet data. For Helm, these components are provided individually. |
backend.use.tigerbeetle | true | When true, a TigerBeetle database is used for accounting. When false, a Postgres database is used. |
backend.serviceUrls.WEBHOOK_URL | undefined | Your endpoint that consumes webhook events. |
Conditionally required values
| Helm value name | Default | Description |
|---|---|---|
backend.instance.name | undefined | Your Rafiki instance’s name used to communicate for auto-peering and/or telemetry. Required when auto-peering and/or telemetry is enabled |
backend.trustProxy | false | Must be set to true when running Rafiki behind a proxy. When true, the X-Forwarded-Proto header is used to determine if connections are secure. |
Optional values
| Helm value name | Default | Description |
|---|---|---|
backend.port.admin | 3001 | The port of your Backend Auth API server. |
backend.autoPeering.serverPort | 3005 | If auto-peering is enabled, the server will use this port. |
backend.port.connector | 3002 | The port of the ILP connector for sending packets via ILP over HTTP. |
backend.enable.autoPeering | false | When true, auto-peering is enabled. |
backend.enableManualMigrations | false | When true, you must run the database manually with the command npm run knex – migrate:latest –env production |
backend.enable.spspPaymentPointers | true | When true, the SPSP route is enabled. |
backend.lifetime.exchangeRate | 15_000 | The time, in milliseconds, the exchange rates you provide via the EXCHANGE_RATES_URL are valid. |
backend.idempotency.keyLockMs | 2000 | The TTL, in milliseconds, for idempotencyKey concurrency lock on GraphQL mutations on the Backend Admin API. |
backend.idempotency.keyTTL | 86400000 (24 hours) | The TTL, in milliseconds, for idempotencyKey on GraphQL mutations on the Backend Admin API. |
backend.incomingPayment.expiryMaxMs | 2592000000 (30 days) | The maximum into the future, in milliseconds, incoming payments expiry can be set to on creation. |
backend.workerIdle | 200 | The time, in milliseconds, that workers will wait until checking an empty queue again. |
backend.workers.incomingPayment | 1 | The number of workers processing incoming payment requests. |
backend.logLevel | info | Pino log level |
backend.nodeEnv | development | The type of node environment: development, test, or production. |
backend.port.openPayments | 3003 | The port of your Open Payments resource server. |
backend.workers.outgoingPayment | 4 | The number of workers processing outgoing payment requests. |
backend.key.file | undefined | The path to your Rafiki instance’s client private key. |
backend.lifetime.quote | 5 * 60_000 (5 minutes) | The time, in milliseconds, an Open Payments quote is valid for. |
backend.redis.tlsCaFile | '' | Redis TLS config |
backend.redis.tlsCertFile | '' | Redis TLS config |
backend.redis.tlsKeyFile | '' | Redis TLS config |
backend.quoteSignatureSecret | undefined | The secret to generate request header signatures for webhook event requests. |
backend.signatureVersion | 1 | The version number to generate request header signatures for webhook events. |
backend.ilp.slippage | 0.01 (1%) | The accepted ILP rate fluctuation. |
backend.ilp.streamSecret | undefined | The seed secret to generate shared STREAM secrets. |
backend.walletAddress.deactivationPaymentGratePeriodMs | 86400000 (24 hours) | The time into the future, in milliseconds, to set expiration of Open Payments incoming payments when deactivating a wallet address. |
backend.walletAddress.lookupTimeoutMs | 1500 | The time, in milliseconds, you have to create a missing wallet address before timeout. |
backend.walletAddress.pollingFrequencyMs | 100 | The frequency of polling while waiting for you to create a missing wallet address. |
backend.serviceUrls.WALLET_ADDRESS_URL | http://127.0.0.1:3001/.well-known/pay | Your Rafiki instance’s internal wallet address. |
backend.workers.walletAddress | 1 | The number of workers processing wallet address requests. |
backend.webhookMaxRetry | 10 | The maximum number of times your Rafiki instance’s backend retries sending a certain webhook event to your configured WEBHOOK_URL. |
backend.lifetime.webhook | 2000 (2 seconds) | The time, in milliseconds, that your Rafiki instance will wait for a 200 response from your webhook endpoint. If a 200 response is not received, Rafiki will time out and try to send the webhook event again. |
backend.workers.webhook | 1 | The number of workers processing webhook events. |
backend.withdrawalThrottleDelay | undefined | The delay in liquidity withdrawal processing. |
Frontend service
The Rafiki frontend service provides an administrative web interface for managing your Rafiki instance. It offers a user-friendly dashboard for monitoring and managing wallet addresses, payments, peers, and other Open Payments resources. The frontend communicates with the Backend Admin API to perform administrative operations.
Ports exposed:
3010(http) - Rafiki Admin web interface
Required Values
| Helm value name | Default | Description |
|---|---|---|
frontend.serviceUrls.GRAPHQL_URL | undefined | URL for Rafiki’s GraphQL Auth Admin API |
frontend.serviceUrls.OPEN_PAYMENTS_URL | undefined | Your Open Payments API endpoint |
frontend.port | undefined | Port from which to host the Rafiki Remix app |
Conditionally required values
The following values are required only when frontend.authEnabled is set to true.
| Helm value name | Default | Description |
|---|---|---|
frontend.kratos.adminUrl | undefined | The admin endpoint/container address for Kratos |
frontend.kratos.containerPublicUrl | undefined | The URL for you to access the Kratos Docker container from within the Docker network. This is used for backend calls to Kratos. |
frontend.kratos.browserPublicUrl | undefined | The URL for you to access the Kratos Docker container from a browser outside of the Docker network. This is used for calls from a browser (what you see in the Rafiki Admin UI) to the Kratos server on the backend. |
Optional values
| Helm value name | Default | Description |
|---|---|---|
frontend.authEnabled | true | When true, only authenticated users can be granted access to Rafiki Admin by an administrator |
frontend.quoteSignatureSecret | undefined | The signature secret used to authenticate requests to the Backend Admin API. |
frontend.signatureVersion | 1 | The signature version number used to authenticate requests to the Backend Admin API. |
frontend.enableInsecureMessageCookie | true | When set to true, t, or 1, cookie will be transmitted over insecure HTTP connection. Insecure message cookies are required for flash messages to work over HTTP. |
frontend.nodeEnv | production | The type of node environment: development, test, or production. |
frontend.logLevel | info | Pino log level |
To expose Rafiki services outside the cluster, you’ll need to configure ingress. Here’s an example using NGINX Ingress Controller:
If you don’t already have an ingress controller installed:
# Add the ingress-nginx repositoryhelm repo add ingress-nginx https://kubernetes.github.io/ingress-nginxhelm repo update
# Install the ingress controllerhelm install nginx-ingress ingress-nginx/ingress-nginx \ --set controller.publishService.enabled=trueAdd ingress configuration to your service values files:
# In backend-values.yamlingress: enabled: true className: nginx hosts: - host: rafiki-backend.your-domain.com paths: - path: / pathType: Prefix service: name: rafiki-backend-service port: 3000 tls: - secretName: rafiki-backend-tls hosts: - rafiki-backend.your-domain.com
# In auth-values.yamlingress: enabled: true className: nginx hosts: - host: rafiki-auth.your-domain.com paths: - path: / pathType: Prefix service: name: rafiki-auth-service port: 3006 tls: - secretName: rafiki-auth-tls hosts: - rafiki-auth.your-domain.comCreate DNS records pointing to your ingress controller’s external IP:
rafiki-backend.your-domain.comrafiki-auth.your-domain.comrafiki-frontend.your-domain.com
You can use an external PostgreSQL instance or deploy one using Helm:
# Add Bitnami repositoryhelm repo add bitnami https://charts.bitnami.com/bitnami
# Install PostgreSQLhelm install rafiki-postgresql bitnami/postgresql \ --set auth.postgresPassword=your-secure-password \ --set auth.database=rafiki \ --set primary.persistence.size=20GiDeploy Redis for caching and session management:
# Install Redishelm install rafiki-redis bitnami/redis \ --set auth.enabled=false \ --set master.persistence.size=8GiFor high-performance accounting, deploy TigerBeetle:
# Add TigerBeetle repositoryhelm repo add tigerbeetle https://tigerbeetle.github.io/helm-charts
# Install TigerBeetlehelm install rafiki-tigerbeetle tigerbeetle/tigerbeetle \ --set replicaCount=3 \ --set persistence.size=20GiTo upgrade your Rafiki services to newer versions:
# Update the Helm repositoryhelm repo update
# Upgrade each servicehelm upgrade rafiki-auth interledger/rafiki-auth -f auth-values.yamlhelm upgrade rafiki-backend interledger/rafiki-backend -f backend-values.yamlhelm upgrade rafiki-frontend interledger/rafiki-frontend -f frontend-values.yamlTo uninstall Rafiki services:
helm uninstall rafiki-authhelm uninstall rafiki-backendhelm uninstall rafiki-frontend
# Optionally uninstall dependencieshelm uninstall rafiki-postgresqlhelm uninstall rafiki-redishelm uninstall rafiki-tigerbeetleVerify that all services are running correctly:
# Check pod statuskubectl get pods -l app.kubernetes.io/name=rafiki-authkubectl get pods -l app.kubernetes.io/name=rafiki-backendkubectl get pods -l app.kubernetes.io/name=rafiki-frontend
# Check service endpointskubectl get endpoints
# Check for eventskubectl get events --sort-by=.metadata.creationTimestamp-
Verify database connectivity:
Terminal window kubectl logs -l app.kubernetes.io/name=rafiki-backend | grep -i database -
Check PostgreSQL status:
Terminal window kubectl get pods -l app.kubernetes.io/name=postgresqlkubectl logs -l app.kubernetes.io/name=postgresql -
Test database connection:
Terminal window kubectl run -it --rm debug --image=postgres:14 -- psql postgresql://username:password@rafiki-postgresql:5432/rafiki
-
Check Redis status:
Terminal window kubectl get pods -l app.kubernetes.io/name=rediskubectl logs -l app.kubernetes.io/name=redis -
Test Redis connectivity:
Terminal window kubectl run -it --rm debug --image=redis:7 -- redis-cli -h rafiki-redis ping
-
Verify service names and ports:
Terminal window kubectl get serviceskubectl describe service rafiki-backend-service -
Check DNS resolution:
Terminal window kubectl run -it --rm debug --image=busybox -- nslookup rafiki-backend-service
-
Check auth service logs:
Terminal window kubectl logs -l app.kubernetes.io/name=rafiki-auth -
Verify secrets are properly mounted:
Terminal window kubectl describe pod -l app.kubernetes.io/name=rafiki-auth -
Test auth endpoints:
Terminal window kubectl port-forward svc/rafiki-auth-service 3007:3007curl http://localhost:3007/healthz
-
Check ingress controller status:
Terminal window kubectl get pods -n ingress-nginxkubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller -
Verify ingress resources:
Terminal window kubectl get ingresskubectl describe ingress rafiki-backend-ingress -
Check TLS certificates:
Terminal window kubectl get secretskubectl describe secret rafiki-backend-tls
-
Check resource usage:
Terminal window kubectl top podskubectl top nodes -
Monitor pod metrics:
Terminal window kubectl describe pod -l app.kubernetes.io/name=rafiki-backend -
Scale services if needed:
Terminal window # Update replicaCount in values.yaml and upgradehelm upgrade rafiki-backend interledger/rafiki-backend -f backend-values.yaml
- Use strong passwords: Replace all default passwords with cryptographically secure values
- Enable TLS: Configure HTTPS for all external communications
- Network policies: Implement Kubernetes network policies to restrict pod-to-pod communication
- RBAC: Use Kubernetes Role-Based Access Control to limit cluster access
- Secrets management: Consider using external secret management solutions like HashiCorp Vault
- Image security: Use specific image tags and scan images for vulnerabilities
- Pod security: Configure pod security standards and security contexts
- Multi-replica deployments: Run multiple replicas of critical services
- Pod disruption budgets: Configure disruption budgets to maintain availability during updates
- Resource limits: Set appropriate CPU and memory limits
- Health checks: Configure proper readiness and liveness probes
- Load balancing: Use multiple ingress controller replicas
- Prometheus: Deploy Prometheus for metrics collection
- Grafana: Set up Grafana dashboards for visualization
- Logging: Implement centralized logging with ELK stack or similar
- Alerting: Configure alerting rules for critical issues
- Distributed tracing: Consider implementing distributed tracing for request flow analysis
PostgreSQL backup:
# Create a backup jobkubectl create job --from=cronjob/postgres-backup manual-backup-$(date +%Y%m%d-%H%M%S)
# Manual backupkubectl exec -it rafiki-postgresql-0 -- pg_dump -U postgres rafiki > backup.sqlTigerBeetle backup:
# Create volume snapshotskubectl create -f - <<EOFapiVersion: snapshot.storage.k8s.io/v1kind: VolumeSnapshotmetadata: name: tigerbeetle-snapshot-$(date +%Y%m%d-%H%M%S)spec: source: persistentVolumeClaimName: tigerbeetle-data-0 volumeSnapshotClassName: your-snapshot-classEOF- Resource allocation: Right-size CPU and memory requests/limits based on actual usage
- Connection pooling: Configure appropriate database connection pool sizes
- Caching: Optimize Redis configuration for your workload
- TigerBeetle tuning: Configure TigerBeetle cluster size based on expected transaction volume
- Rolling updates: Use rolling update strategies to maintain availability
- Blue-green deployments: Consider blue-green deployments for zero-downtime upgrades
- Database migrations: Plan for database schema migrations
- Backup before upgrade: Always backup data before major upgrades
- Testing: Test upgrades in staging environments first