<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Deployment on Lucille</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/</link><description>Recent content in Deployment on Lucille</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 09 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/index.xml" rel="self" type="application/rss+xml"/><item><title>Local Batch</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/local-batch/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/local-batch/</guid><description>&lt;h2 id="local-mode"&gt;Local Mode&lt;/h2&gt;
&lt;p&gt;In local mode, you start a single Java process at the command line, invoking the &lt;code&gt;main()&lt;/code&gt; method of &lt;code&gt;com.kmwllc.lucille.core.Runner&lt;/code&gt;. Alternatively, if you are using Lucille as a dependency in your own Java project, you call &lt;code&gt;Runner.run()&lt;/code&gt; from your code.&lt;/p&gt;
&lt;p&gt;All components (Connector, Workers, Indexer) run as threads in a single JVM. Communication uses in-memory queues. There is no external infrastructure required — no Kafka, no ZooKeeper, no separate processes.&lt;/p&gt;</description></item><item><title>Distributed Batch</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-batch/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-batch/</guid><description>&lt;h2 id="kafka-distributed-mode"&gt;Kafka-Distributed Mode&lt;/h2&gt;
&lt;p&gt;In distributed mode, each Lucille component runs as its own JVM process. All inter-component communication uses Kafka topics.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Large-scale batch ingests, multi-machine deployments, horizontal scaling.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;Before starting any Lucille component in distributed mode, ensure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kafka&lt;/strong&gt; is running and reachable from all machines that will run Lucille components&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kafka topics&lt;/strong&gt; are created for each pipeline referenced by your connectors (or auto-creation is enabled on the broker) — see &lt;a href="https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-batch/#kafka-topic-setup"&gt;Kafka Topic Setup&lt;/a&gt; for details&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workers and Indexer&lt;/strong&gt; are running for each pipeline referenced by your connectors — see &lt;a href="https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-batch/#starting-each-component"&gt;Starting Each Component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search backend&lt;/strong&gt; collection/index exists (Solr, OpenSearch, Elasticsearch, etc.)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ZooKeeper&lt;/strong&gt; is running (only if using &lt;code&gt;worker.maxRetries&lt;/code&gt; for poison-pill protection)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Same config file&lt;/strong&gt; is available to all Lucille processes (Runner, Workers, Indexer)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="start-order"&gt;Start Order&lt;/h2&gt;
&lt;p&gt;Start components in this order:&lt;/p&gt;</description></item><item><title>Distributed Streaming</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-streaming/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/distributed-streaming/</guid><description>&lt;h2 id="streaming-mode-connectorless"&gt;Streaming Mode (Connectorless)&lt;/h2&gt;
&lt;p&gt;In streaming mode, Lucille runs without a Runner or Connector. An external system places documents onto a Kafka source topic directly, and one or more Worker or WorkerIndexer processes consume and process them continuously — with no run boundary or completion accounting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Keeping a search index in sync with a live system (e.g., consuming from a CDC topic, Debezium, or any Kafka producer). The pipeline logic is identical to batch mode; only the execution model changes.&lt;/p&gt;</description></item><item><title>Hybrid Streaming</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/hybrid-streaming/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/hybrid-streaming/</guid><description>&lt;h2 id="hybrid-streaming-mode"&gt;Hybrid Streaming Mode&lt;/h2&gt;
&lt;p&gt;In hybrid streaming mode, Lucille runs one or more &lt;code&gt;WorkerIndexer&lt;/code&gt; processes that co-locate document processing and indexing in a single JVM. Like distributed streaming, there is no Runner or Connector — an external system places documents onto a Kafka source topic, and the WorkerIndexer processes consume, enrich, and index them continuously.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Streaming ingestion where you want the horizontal scalability of distributed mode but with simpler operations — fewer processes to manage, no separate Indexer deployment, and reduced network hops between processing and indexing.&lt;/p&gt;</description></item><item><title>Docker Compose</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/docker-compose/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/docker-compose/</guid><description>&lt;h2 id="docker-compose-deployment"&gt;Docker Compose Deployment&lt;/h2&gt;
&lt;p&gt;Docker Compose is the simplest way to run Lucille in distributed mode. The &lt;a href="https://github.com/kmwtechnology/lucille/tree/main/lucille-examples/lucille-distributed-example"&gt;lucille-distributed-example&lt;/a&gt; provides a complete working template. The key structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;services&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;zookeeper&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# Bundled with Kafka; required for Kafka&amp;#39;s internal coordination&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;image&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;...&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;kafka&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;depends_on&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;[&lt;/span&gt;&lt;span style="color:#000"&gt;zookeeper]&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;healthcheck&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;test&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;[&lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;,&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;kafka-topics.sh&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;,&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;--bootstrap-server=kafka:9092&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;,&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;--list&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;]&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;worker&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;depends_on&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;kafka&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;{&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;condition&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;service_healthy }&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;entrypoint&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;java -Dconfig.file=/conf/config.conf -cp &amp;#39;/target/lib/*&amp;#39;&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;com.kmwllc.lucille.core.Worker my-pipeline&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;indexer&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;depends_on&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;kafka&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;{&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;condition&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;service_healthy }&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;solr&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;{&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;condition&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;service_healthy }&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;healthcheck&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# Delegate healthcheck to the search backend — Runner waits for this before starting&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;test&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;curl -f &amp;#39;http://solr:8983/solr/...&amp;#39;&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;entrypoint&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;|&lt;/span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt; # Create the collection, then start the Indexer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt; curl &amp;#39;http://solr:8983/solr/admin/collections?action=CREATE&amp;amp;name=quickstart...&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt; java -Dconfig.file=/conf/config.conf -cp &amp;#39;/target/lib/*&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt; com.kmwllc.lucille.core.Indexer my-pipeline&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;runner&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;depends_on&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;kafka&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;{&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;condition&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;service_healthy }&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;indexer&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;{&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;condition&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;service_healthy } &lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# Ensures Indexer + backend are ready&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;entrypoint&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;:&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;java -Dconfig.file=/conf/config.conf -cp &amp;#39;/target/lib/*&amp;#39;&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#000"&gt;com.kmwllc.lucille.core.Runner -usekafka&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Key design points from the example:&lt;/p&gt;</description></item><item><title>Kubernetes</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/kubernetes/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/kubernetes/</guid><description>&lt;h2 id="kubernetes-deployment"&gt;Kubernetes Deployment&lt;/h2&gt;
&lt;p&gt;Lucille&amp;rsquo;s architecture maps naturally onto Kubernetes primitives.&lt;/p&gt;
&lt;h3 id="batch-jobs-as-kubernetes-cronjobs"&gt;Batch Jobs as Kubernetes CronJobs&lt;/h3&gt;
&lt;p&gt;For scheduled batch ingests, package Lucille as a container and run it as a &lt;code&gt;CronJob&lt;/code&gt;. When the run completes, the container exits — there is no long-running process to manage between runs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minimal Dockerfile:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;FROM&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#4e9a06"&gt;eclipse-temurin:17-jre&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;WORKDIR&lt;/span&gt;&lt;span style="color:#f8f8f8"&gt; &lt;/span&gt;&lt;span style="color:#4e9a06"&gt;/app&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# Copy all JARs (lucille-core + dependencies) from the Maven build output&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;COPY&lt;/span&gt; target/lib/ lib/&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# Copy your pipeline configuration&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;COPY&lt;/span&gt; conf/ conf/&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# The config file path is provided via an environment variable at runtime&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;ENV&lt;/span&gt; &lt;span style="color:#000"&gt;CONF&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87;font-weight:bold"&gt;ENTRYPOINT&lt;/span&gt; &lt;span style="color:#000;font-weight:bold"&gt;[&lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;,&lt;/span&gt; &lt;span style="color:#4e9a06"&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;,&lt;/span&gt; &lt;span style="color:#4e9a06"&gt;&amp;#34;java -Xmx4g -Dconfig.file=${CONF} -cp &amp;#39;lib/*&amp;#39; com.kmwllc.lucille.core.Runner&amp;#34;&lt;/span&gt;&lt;span style="color:#000;font-weight:bold"&gt;]&lt;/span&gt;&lt;span style="color:#a40000"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Build the image after running &lt;code&gt;mvn clean install&lt;/code&gt; in your project (which copies all dependencies to &lt;code&gt;target/lib/&lt;/code&gt;):&lt;/p&gt;</description></item><item><title>Production Operations</title><link>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/production-operations/</link><pubDate>Mon, 09 Jun 2025 00:00:00 +0000</pubDate><guid>https://kmwtechnology.github.io/lucille/docs-0.9.0/operations/deployment/production-operations/</guid><description>&lt;h2 id="memory-sizing"&gt;Memory Sizing&lt;/h2&gt;
&lt;p&gt;Rule of thumb: &lt;code&gt;worker.threads × (Stage resource usage)&lt;/code&gt;. A pipeline that loads a 500MB NLP model uses 500MB × number of Worker threads.&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Component&lt;/th&gt;
 &lt;th&gt;Typical Heap Size&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Runner (local, lightweight pipeline)&lt;/td&gt;
 &lt;td&gt;512MB–2GB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Runner (local, ML stages)&lt;/td&gt;
 &lt;td&gt;4GB–16GB per stage model × threads&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Worker (distributed, no ML)&lt;/td&gt;
 &lt;td&gt;512MB–1GB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Worker (distributed, with ML models)&lt;/td&gt;
 &lt;td&gt;2GB–8GB per model&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Indexer&lt;/td&gt;
 &lt;td&gt;512MB–1GB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Always set &lt;code&gt;-Xmx&lt;/code&gt; explicitly. Avoid letting Java use all available RAM.&lt;/p&gt;</description></item></channel></rss>