Skip to main content

Deploying Marlowe Runtime

In this tutorial, you will deploy Marlowe Runtime with Docker in a Nix environment.

Prerequisites

To follow this tutorial, you need to:

  • Have a single or multi-user installation of nix
  • Working installation of Docker

Configure binary caches

caution

An improperly configured cache will lead to lengthy compile times up to multiple hours long.

Linux

caution

ARM-based architecture is not supported at this time. This includes Apple M1 and M2 machines.

non-NixOS Install

If you are running Nix as a single user, edit the /etc/nix/nix.conf file.

substituters        = https://cache.iog.io https://iohk.cachix.org https://cache.nixos.org/
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=

Restart the Nix daemon after updating /etc/nix/nix.conf.

NixOS Install

If running this directly from an installation of NixOS, configure the following options:

nix.settings = {
substituters = [ "https://cache.iog.io" "https://iohk.cachix.org" ];
trusted-public-keys = [ "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" "iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo=" ];
};

Restart the Nix daemon after updating /etc/nix/nix.conf.

sudo launchctl stop org.nixos.nix-daemon
sudo launchctl start org.nixos.nix-daemon

Start a Nix Shell

Nix is the recommended method of starting an environment to run all the steps below.

nix develop github:input-output-hk/marlowe-starter-kit/bd47580781bd06c924e05dc434c0a824ef207aae

Select a network

For most purposes within tutorials, the two testnets used are preprod and preview. Generally preprod is preferred because it has fewer transactions and takes less time for the node to sync.

Set the network environment variable to the desired testnet:

export NETWORK=preprod

Connect to Marlowe Runtime

Create a docker compose YAML file that contains all Marlowe related services and dependencies.

Alternatively, use the one found from the marlowe-starter-kit.

version: "2.2"

services:

node:
environment:
- NETWORK=${NETWORK:?err}
healthcheck:
interval: 10s
retries: 10
test: socat -u OPEN:/dev/null UNIX-CONNECT:/ipc/node.socket
timeout: 5s
image: inputoutput/cardano-node:8.1.2
restart: unless-stopped
volumes:
- shared:/ipc
- node-db:/data

postgres:
environment:
- POSTGRES_LOGGING=true
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- TZ=UTC
healthcheck:
interval: 10s
retries: 5
test: pg_isready -U postgres
timeout: 5s
image: postgres:11.5-alpine
logging:
driver: json-file
options:
max-file: '10'
max-size: 200k
restart: unless-stopped
volumes:
- postgres:/var/lib/postgresql/data
- ./networks/${NETWORK:?err}/init.sql:/docker-entrypoint-initdb.d/init.sql
command:
- '-c'
- 'max_connections=1000'
- '-c'
- 'superuser_reserved_connections=5'
- '-c'
- 'huge_pages=try'
- '-c'
- 'max_wal_size=6GB'
- '-c'
- 'max_locks_per_transaction=256'
- '-c'
- 'max_pred_locks_per_transaction=256'
- '-c'
- 'work_mem=32MB'
- '-c'
- 'maintenance_work_mem=256MB'
ports:
- 5432:5432

chain-indexer:
environment:
- NODE_CONFIG=/node/config.json
- DB_NAME=chain_${NETWORK:?err}
- DB_USER=postgres
- DB_PASS=postgres
- DB_HOST=postgres
- CARDANO_NODE_SOCKET_PATH=/ipc/node.socket
- HTTP_PORT=3781
depends_on:
node:
condition: service_healthy
postgres:
condition: service_healthy
image: ghcr.io/input-output-hk/marlowe-chain-indexer:0.0.5
user: 0:0
restart: unless-stopped
volumes:
- shared:/ipc
- ./networks/${NETWORK:?err}/node:/node

chain-sync:
environment:
- NODE_CONFIG=/node/config.json
- HOST=0.0.0.0
- PORT=3715
- QUERY_PORT=3716
- JOB_PORT=3720
- DB_NAME=chain_${NETWORK:?err}
- DB_USER=postgres
- DB_PASS=postgres
- DB_HOST=postgres
- CARDANO_NODE_SOCKET_PATH=/ipc/node.socket
- HTTP_PORT=3782
depends_on:
chain-indexer:
condition: service_started
postgres:
condition: service_healthy
image: ghcr.io/input-output-hk/marlowe-chain-sync:0.0.5
user: 0:0
restart: unless-stopped
volumes:
- shared:/ipc
- ./networks/${NETWORK:?err}/node:/node

indexer:
environment:
- DB_NAME=chain_${NETWORK:?err}
- DB_USER=postgres
- DB_PASS=postgres
- DB_HOST=postgres
- MARLOWE_CHAIN_SYNC_HOST=chain-sync
- MARLOWE_CHAIN_SYNC_PORT=3715
- MARLOWE_CHAIN_SYNC_QUERY_PORT=3716
- MARLOWE_CHAIN_SYNC_COMMAND_PORT=3720
- HTTP_PORT=3783
depends_on:
chain-sync:
condition: service_started
postgres:
condition: service_healthy
image: ghcr.io/input-output-hk/marlowe-indexer:0.0.5
restart: unless-stopped

sync:
environment:
- HOST=0.0.0.0
- MARLOWE_SYNC_PORT=3724
- MARLOWE_HEADER_SYNC_PORT=3725
- MARLOWE_QUERY_PORT=3726
- DB_NAME=chain_${NETWORK:?err}
- MARLOWE_CHAIN_SYNC_HOST=chain-sync
- MARLOWE_CHAIN_SYNC_QUERY_PORT=3716
- DB_USER=postgres
- DB_PASS=postgres
- DB_HOST=postgres
- HTTP_PORT=3784
depends_on:
indexer:
condition: service_started
postgres:
condition: service_healthy
image: ghcr.io/input-output-hk/marlowe-sync:0.0.5
restart: unless-stopped

tx:
environment:
- HOST=0.0.0.0
- PORT=3723
- MARLOWE_CHAIN_SYNC_HOST=chain-sync
- MARLOWE_CHAIN_SYNC_PORT=3715
- MARLOWE_CHAIN_SYNC_QUERY_PORT=3716
- MARLOWE_CHAIN_SYNC_COMMAND_PORT=3720
- CONTRACT_HOST=contract
- CONTRACT_QUERY_PORT=3728
- HTTP_PORT=3785
depends_on:
- chain-sync
- contract
image: ghcr.io/input-output-hk/marlowe-tx:0.0.5
restart: unless-stopped

contract:
environment:
- HOST=0.0.0.0
- PORT=3727
- QUERY_PORT=3728
- TRANSFER_PORT=3729
- STORE_DIR=/store
- HTTP_PORT=3787
volumes:
- marlowe-contract-store:/store
image: ghcr.io/input-output-hk/marlowe-contract:0.0.5
restart: unless-stopped

proxy:
environment:
- HOST=0.0.0.0
- PORT=3700
- TRACED_PORT=3701
- TX_HOST=tx
- TX_PORT=3723
- CONTRACT_HOST=contract
- LOAD_PORT=3727
- CONTRACT_QUERY_PORT=3728
- TRANSFER_PORT=3729
- SYNC_HOST=sync
- MARLOWE_SYNC_PORT=3724
- MARLOWE_HEADER_SYNC_PORT=3725
- MARLOWE_QUERY_PORT=3726
- HTTP_PORT=3786
depends_on:
- sync
- tx
- contract
image: ghcr.io/input-output-hk/marlowe-proxy:0.0.5
restart: unless-stopped
ports:
- 3700:3700
- 3701:3701

web-server:
environment:
- PORT=3780
- RUNTIME_HOST=proxy
- RUNTIME_PORT=3701
depends_on:
- proxy
image: ghcr.io/input-output-hk/marlowe-web-server:0.0.5
restart: unless-stopped
ports:
- 3780:3780

volumes:
node-db: null
postgres: null
shared: null
marlowe-contract-store: null

Run docker ps -a to see a list of the running containers.

Check the service is healthy by running curl -sSI localhost:3780/healthcheck . If all the containers are running, this should return a 200 response.