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
An improperly configured cache will lead to lengthy compile times up to multiple hours long.
Linux
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.