Docker Compose
This guide is an example of deploying Rafiki using Docker Compose with Nginx as a reverse proxy on a virtual machine (VM) in a cloud environment. This guide also uses Certbot to generate Let’s Encrypt TLS certificates to secure exposed ports using HTTPS.
Prerequisites
Domain and subdomains setup
We will map the Open Payments resource server to your domain, and the ILP Connector, Open Payments auth server, and Admin UI to subdomains. Using the DNS host of your choice, set up your domain and subdomains according to the following recommended convention:
service | function | URL | example |
---|---|---|---|
Open Payments resource server | Exposes the Open Payments APIs | DOMAIN | myrafiki.com |
ILP Connector | Exposes an ILP connector to send and receive ILP packets between peers | ilp.DOMAIN | ilp.myrafiki.com |
Open Payments auth server | Exposes a reference implementation of an Open Payments authorization server | auth.DOMAIN | auth.myrafiki.com |
Admin UI | Exposes an Admin UI to manage Rafiki | admin.DOMAIN | admin.myrafiki.com |
Deploy VM and install Docker
Deploy a general purpose VM with the following minimum specifications:
- OS: Linux distro
- RAM: 4GB
- vCPUs: 2
Install the following software on the VM:
Install Nginx and Certbot
Once you have provisioned the VM in your cloud environment, install Nginx along with Certbot:
sudo apt update && sudo apt install nginx certbot python3-certbot-nginx
Domain preparation
Generate the Let’s Encrypt certificates using Certbot:
certbot certonly --manual --preferred-challenges=dns --email EMAIL --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d DOMAIN
As Let’s Encrypt certificates are valid for 90 days, you must set up a cron process to renew the certificate on a regular schedule:
crontab -e0 3 * * * certbot renew
Update DNS records
Next update the DNS records (A records) to point to the static external IP address of the virtual machine:
service | URL | example |
---|---|---|
Open Payments resource server | DOMAIN | myrafiki.com |
ILP Connector | ilp.DOMAIN | ilp.myrafiki.com |
Open Payments auth server | auth.DOMAIN | auth.myrafiki.com |
Admin UI | admin.DOMAIN | admin.myrafiki.com |
Configure compose file
Update the variables in the following compose file with values relevant to your environment and system. Refer to the environment variables page for details.
name: 'my-rafiki'services: rafiki-auth: image: ghcr.io/interledger/rafiki-auth:<newest-version> container_name: rafiki-auth environment: AUTH_DATABASE_URL: {postgresql://...} AUTH_SERVER_URL: {https://auth.myrafiki.com} ADMIN_PORT: 3003 AUTH_PORT: 3006 INTROSPECTION_PORT: 3007 INTERACTION_PORT: 3009 COOKIE_KEY: {...} IDENTITY_SERVER_SECRET: {...} IDENTITY_SERVER_URL: {https://idp.mysystem.com} REDIS_URL: {redis://...} TRUST_PROXY: true depends_on: - postgres networks: - rafiki ports: - '3003:3003' - '3006:3006' - '3007:3007' - '3009:3009' restart: always
rafiki-backend: image: ghcr.io/interledger/rafiki-backend:<newest-version> container_name: rafiki-backend depends_on: - postgres - redis environment: AUTH_SERVER_GRANT_URL: {https://auth.myrafiki.com} AUTH_SERVER_INTROSPECTION_URL: {https://auth.myrafiki.com/3007} DATABASE_URL: {postgresql://...} ILP_ADDRESS: {test.myrafiki} ADMIN_PORT: 3001 CONNECTOR_PORT: 3002 OPEN_PAYMENTS_PORT: 3000 OPEN_PAYMENTS_URL: {https://myrafiki.com} REDIS_URL: {redis://...} WALLET_ADDRESS_URL: {https://myrafiki.com/rafiki-instance} WEBHOOK_URL: {https://mysystem.com/webhooks} EXCHANGE_RATES_URL: {https://mysystem.com/rates} ILP_CONNECTOR_URL: {https://ilp.myrafiki.com} INSTANCE_NAME: {'My ASE name'} TRUST_PROXY: true KEY_ID: ... USE_TIGERBEETLE: true TIGERBEETLE_CLUSTER_ID: 0 TIGERBEETLE_REPLICA_ADDRESSES: 10.5.0.50:4342 networks: - rafiki ports: - '3000:3000' - '3001:3001' - '3002:3002' privileged: true restart: always volumes: - ../temp/:/workspace/temp/
rafiki-frontend: image: ghcr.io/interledger/rafiki-frontend:<newest-version> container_name: rafiki-frontend depends_on: - rafiki-backend environment: PORT: 3005 GRAPHQL_URL: {https://myrafiki.com:3001} OPEN_PAYMENTS_URL: {https://myrafiki.com} KRATOS_CONTAINER_PUBLIC_URL: {http://kratos:4433} KRATOS_BROWSER_PUBLIC_URL: {https://admin.myrafiki.com/kratos} KRATOS_ADMIN_URL: {http://kratos:4434/admin} networks: - rafiki restart: always privileged: true ports: - '3005:3005'
tigerbeetle: image: ghcr.io/tigerbeetle/tigerbeetle:0.15.4 privileged: true volumes: - tigerbeetle-data:/var/lib/tigerbeetle networks: rafiki: ipv4_address: 10.5.0.50 entrypoint: - /bin/sh - -c - | set -ex DATA_FILE=/var/lib/tigerbeetle/cluster_0_replica_0.tigerbeetle set +e ls $$DATA_FILE DATA_FILE_EXISTS="$$?" set -e echo $$DATA_FILE_EXISTS if [ "$$DATA_FILE_EXISTS" != 0 ]; then ./tigerbeetle format --cluster=0 --replica=0 --replica-count=1 $$DATA_FILE; fi hostname -i ls /var/lib/tigerbeetle ./tigerbeetle start --addresses=0.0.0.0:4342 $$DATA_FILE
postgres: image: 'postgres:16' container_name: postgres environment: POSTGRES_USER: ... POSTGRES_PASSWORD: ... networks: - rafiki restart: unless-stopped volumes: - pg-data:/var/lib/postgresql/data - ../dbinit.sql:/docker-entrypoint-initdb.d/init.sql
redis: image: 'redis:7' restart: unless-stopped networks: - rafiki
kratos: image: 'oryd/kratos:v1.2.0' privileged: true ports: - '4433:4433' volumes: - ../entrypoint.sh:/entrypoint.sh - ../identity.schema.json:/etc/config/kratos/identity.schema.json - ./kratos.yml:/etc/config/kratos/kratos.yml entrypoint: ['/entrypoint.sh'] networks: - rafiki
networks: testnet: driver: bridge ipam: config: - subnet: 10.5.0.0/24 gateway: 10.5.0.1
volumes: pg-data: tigerbeetle-data:
Create Nginx config files
Create nginx configuration files for every exposed domain:
service | URL | example | Nginx config file |
---|---|---|---|
Open Payments resource server | DOMAIN | myrafiki.com | /etc/nginx/sites-available/open_payments_resource_server.config |
ILP Connector | ilp.DOMAIN | ilp.myrafiki.com | /etc/nginx/sites-available/ilp.config |
Open Payments auth server | auth.DOMAIN | auth.myrafiki.com | /etc/nginx/sites-available/open_payments_auth_server.config |
Admin UI | admin.DOMAIN | admin.myrafiki.com | /etc/nginx/sites-available/admin.config |
Open Payments Resource Server (backend
package)
Using the editor of your choice, save the following file as open_payments_resource_server.config
in the /etc/nginx/sites-available
directory on your VM:
server { server_name myrafiki.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/myrafiki.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myrafiki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / { proxy_http_version 1.1; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade ""; proxy_set_header Connection ""; proxy_set_header Host $server_name; proxy_set_header Accept-Encoding ""; proxy_cache_bypass $http_upgrade;
proxy_pass_request_headers on;
proxy_pass http://localhost:3000; }}
server { server_name myrafiki.com;
listen 80;
if ($host = myrafiki.com) { return 301 https://$host$request_uri; }
return 404;}
ILP Connector (backend
package)
Save the following file as ilp.config
in the /etc/nginx/sites-available
directory on your VM:
server { server_name ilp.myrafiki.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/ilp.myrafiki.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ilp.myrafiki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / { proxy_http_version 1.1; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade ""; proxy_set_header Connection ""; proxy_set_header Host $server_name; proxy_set_header Accept-Encoding ""; proxy_cache_bypass $http_upgrade;
proxy_pass_request_headers on;
proxy_pass http://localhost:3002; }}
server { server_name ilp.myrafiki.com;
listen 80;
if ($host = ilp.myrafiki.com) { return 301 https://$host$request_uri; }
return 404;}
Open Payments Auth Server (auth
package)
Save the following file as open_payments_auth_server.config
in the /etc/nginx/sites-available
directory on your VM:
server { server_name auth.myrafiki.com;
listen 443 ssl; ssl_certificate /etc/letsencrypt/live/auth.myrafiki.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/auth.myrafiki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / { proxy_http_version 1.1; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade ""; proxy_set_header Connection ""; proxy_set_header Host $server_name; proxy_set_header Accept-Encoding ""; proxy_cache_bypass $http_upgrade;
proxy_pass_request_headers on;
proxy_pass http://localhost:3006; }}
server { server_name auth.myrafiki.com;
listen 80;
if ($host = auth.myrafiki.com) { return 301 https://$host$request_uri; }
return 404;}
Admin (frontend
package)
Save the following file as admin.config
in the /etc/nginx/sites-available
directory on your VM:
server { server_name admin.myrafiki.com;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/admin.myrafiki.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/admin.myrafiki.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / { proxy_http_version 1.1; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade ""; proxy_set_header Connection ""; proxy_set_header Host $server_name; proxy_set_header Accept-Encoding ""; proxy_cache_bypass $http_upgrade;
proxy_pass_request_headers on;
proxy_pass http://localhost:3005; }}
server { server_name admin.myrafiki.com;
listen 80;
if ($host = admin.myrafiki.com) { return 301 https://$host$request_uri; }
return 404;}
Set up symbolic links
Once the Nginx configuration files have been created, set up symbolic links that will allow Nginx to read those files and redirect the local paths to the exposed domains and ports.
sudo ln -s /etc/nginx/sites-available/admin.conf /etc/nginx/sites-enabled/admin.conf
sudo ln -s /etc/nginx/sites-available/open_payments_auth_server.conf /etc/nginx/sites-enabled/open_payments_auth_server.conf
sudo ln -s /etc/nginx/sites-available/ilp.conf /etc/nginx/sites-enabled/ilp.conf
sudo ln -s /etc/nginx/sites-available/open_payments_resource_server.conf /etc/nginx/sites-enabled/open_payments_resource_server.conf
Deploy with Docker Compose
Deploy the configured Rafiki services with Docker Compose:
docker compose up -d