stoffel CLI or Rust SDK; move to Compose when you want explicit service topology, container boundaries, persistent stores, or backend integration.
What the Docker stacks provide
The Compose files make the runtime topology explicit and runnable:Source files
From the Stoffel repository:Swap and adapt a Compose stack
Start by choosing the closest root Compose file, then copy it into your application or infrastructure repository before editing it. Do not patch the example in place and assume it now represents your app. The root files are runnable templates for Stoffel service roles; your app decides the bytecode, images, client services, network names, ports, identity material, storage, and backend settings. Use this adaptation order:- Choose the baseline stack. Use
docker-compose.ymlfor a basic HoneyBadger coordinator/party run,docker-compose.coordinator.reserve-index.ymlwhen your app has explicit client containers and client-slot assignment, adddocker-compose.coordinator.reserve-index.preproc.ymlwhen you need persistent preprocessing storage, or usedocker-compose.avss.ymlwhen you are exercising AVSS/local-store behavior. - Copy the Compose file and overlays. Keep the original root files as references. Edit an app-owned copy such as
compose.stoffel.ymlso your changes can live with the application deployment code. - Replace the program artifact. Build your application’s
.stflb, package or mount it into the runtime container, and updateSTOFFEL_PROGRAMto the in-container path. If the entrypoint changes, updateSTOFFEL_ENTRYtoo. - Replace the image build. Swap the example image or build context for the image that contains your app’s bytecode, runtime wrapper, entrypoint script, certificates, and any app-specific client binaries.
- Rewrite client services. Replace sample client containers and
STOFFEL_INPUTSvalues with your own input/output client services. Match each service to the client slots and output recipients expected by your Stoffel program. - Update network addresses. Rename the Compose network, service names, coordinator address, party addresses, and
STOFFEL_SERVERSentries so they match the hostnames your containers will actually resolve. Inside Compose, service names become DNS names; outside Compose, you may need routed hostnames, load balancers, or explicit published ports. - Change ports deliberately. Avoid copying host port mappings that collide with your backend or with multiple test networks on the same host. Keep container-internal ports aligned with service configuration, and change only the host-side published ports unless your runtime config also changes.
- Replace identities and secrets. Generate deployment-specific node/client identity material and use secret management or protected environment files for tokens. Do not reuse checked-in local fixtures outside local tests.
- Update volumes and stores. Replace example
ids/, bytecode, preprocessing, and local-store mounts with app-owned directories or managed volumes. Decide which data must persist across restarts and which should be ephemeral. - Select backend settings. Set
STOFFEL_MPC_BACKEND,STOFFEL_MPC_CURVE,STOFFEL_N_PARTIES, andSTOFFEL_THRESHOLDto match the bytecode manifest, security target, and number of parties you are operating. - Validate from the container network. Run the adapted Compose stack, then check coordinator reachability, party-to-party reachability, client submission, output delivery, logs, and persistent store behavior from the same network namespaces the services use.
For example, a private matchmaking app should not keep the sample client containers unchanged. It should package the matchmaking
.stflb, run participant clients that submit matchmaking payloads to the reserved client slots, expose only the coordinator/node endpoints those clients need, and mount identity and store paths owned by that deployment.
Switch from default programs to your program
The root Docker image ships with example bytecode under/app/programs/. The Compose files select one of those defaults with STOFFEL_PROGRAM, such as /app/programs/mpc_aes128_circuit.stflb for the HoneyBadger stack or /app/programs/avss_keygen.stflb for the AVSS stack. To run your own app, the path in STOFFEL_PROGRAM must point to a .stflb file that exists inside every party container.
Use one of these two patterns.
Package the bytecode into an app image
Use this for repeatable local testing, staging, or a developer-owned backend.- Build your app’s bytecode with the same backend family you plan to run:
- Add an app-owned Dockerfile that starts from your Stoffel runtime base image or repeats the runtime stage from the root
Dockerfile, then copies your bytecode into/app/programs/:
- Update your app-owned Compose file so every party uses that image and program path:
- Keep the backend settings aligned with the bytecode. A HoneyBadger-built program should run with
STOFFEL_MPC_BACKEND=honeybadger; an AVSS-built program should run withSTOFFEL_MPC_BACKEND=avssand the same curve selection you built for.
Mount the bytecode while iterating locally
Use this only for local development loops where you want to rebuild bytecode without rebuilding the runtime image.STOFFEL_PROGRAM must use the right-side path. If you run the stack from a different directory, update the host path or use an absolute path.
Program switching is not only a filename change. If your program uses client inputs or sends outputs to clients, also update the client containers, STOFFEL_INPUTS, STOFFEL_CLIENT_INDEX, STOFFEL_SERVERS, output decoding, and any coordinator settings such as expected input/output clients. If the entry function is not main, set STOFFEL_ENTRY to the function you want every party to execute.
Run a HoneyBadger Compose network
Usedocker-compose.yml when you want the HoneyBadger backend. The stack starts one coordinator and five MPC parties on the stoffel-net bridge. Each party receives STOFFEL_MPC_BACKEND=honeybadger, a party ID, coordinator address, node identity, RPC bind address, and the packaged program path.
From a Stoffel source checkout, first render the Compose configuration you are about to run:
STOFFEL_PROGRAM. If you do not set STOFFEL_PROGRAM, the stack uses /app/programs/mpc_aes128_circuit.stflb. If you do not set STOFFEL_MPC_BACKEND, the stack uses honeybadger.
To run your own HoneyBadger-compatible program, build or package your .stflb into the runtime image and point STOFFEL_PROGRAM at the in-container path:
Run the coordinator/client reserve-index stack
Use this stack when you want to see the off-chain coordinator path with explicit client containers:- one coordinator service on port
31415; - five MPC party services;
- node RPC endpoints on ports such as
16180through16184inside the Compose network; - two client containers that submit inputs to deterministic client indices;
- node and client certificates mounted from
ids/.
Run an AVSS local-store stack
Usedocker-compose.avss.yml when you want the AVSS backend. This stack starts five party containers on the stoffel-avss-net bridge, sets STOFFEL_MPC_BACKEND=avss for every party, and mounts a separate persistent local store volume for each party at /app/data.
From a Stoffel source checkout, first render the AVSS Compose configuration:
/app/programs/avss_keygen.stflb. It leaves STOFFEL_MPC_CURVE empty unless you set it, so the runtime uses its default AVSS curve behavior.
Select a curve or program with environment variables. For example, run the secp256k1 threshold-ECDSA fixture through AVSS:
STOFFEL_PARTY_ID, bind address, bootstrap address, and local-store volume distinct.
Inspect the running AVSS parties and logs:
-v only when you also want to remove the persistent local-store volumes:
Environment variables to understand
Use with your own backend
The Docker stacks are not only a local teaching aid. They are starting points that you adapt for a backend you control. For your own application, read the root Compose files and expect to heavily modify the Compose code and configuration rather than running the checked-in examples unchanged: build your app’s.stflb bytecode, mount or package it into the runtime image, configure coordinator and party addresses for your environment, wire your own client input/output services, and connect your app or client services to the exposed coordinator/node RPC endpoints.
Use Compose when you want to own the deployment shape yourself:
- local laptop or CI testing with the same service roles you plan to operate;
- a developer-owned backend where the coordinator, parties, and clients run as containers;
- staging environments that need persistent preprocessing or local stores;
- operator runbooks that should start from concrete services rather than SDK-local execution.
- several MPC node processes;
- a coordinator or bootstrap path;
- configured parties and threshold;
- client input submission;
- bytecode execution;
- explicit output reconstruction or delivery.
Current caveats
- These stacks are self-managed Compose deployments. They are suitable for local testing and developer-owned backend deployments, but they are not a managed hosting product.
- Some coordinator paths are HoneyBadger/BLS12-381-specific while AVSS is exercised by a separate local-store stack.
- The checked-in examples use fixed local subnets and local identity fixtures. Replace them with real identity, secret, network, and operations management when deploying outside a local test environment.
- The runtime image packages selected example bytecode and sample client behavior. For your app, build your own
.stflb, pointSTOFFEL_PROGRAMat it, and update the client/container code that submits inputs or receives outputs.