[{"data":1,"prerenderedAt":2073},["ShallowReactive",2],{"navigation_docs":3,"-docs-guides-deploying-to-production":968,"-docs-guides-deploying-to-production-surround":2068},[4,27,63,129,287,311,893,902,950,964],{"title":5,"path":6,"stem":7,"children":8,"order":10,"icon":11},"Overview","\u002Fdocs\u002Foverview","docs\u002F1.overview\u002Findex",[9,12,18,24],{"title":5,"path":6,"stem":7,"order":10,"icon":11},1,"i-lucide-info",{"title":13,"path":14,"stem":15,"order":16,"icon":17},"Getting Started","\u002Fdocs\u002Foverview\u002Fgetting-started","docs\u002F1.overview\u002F2.getting-started",2,"i-lucide-rocket",{"title":19,"path":20,"stem":21,"order":22,"icon":23},"Contributing","\u002Fdocs\u002Foverview\u002Fcontributing","docs\u002F1.overview\u002F3.contributing",3,"i-lucide-heart",{"title":5,"path":25,"stem":26,"order":10},"\u002Fdocs\u002Foverview\u002F_dir","docs\u002F1.overview\u002F_dir",{"title":28,"path":29,"stem":30,"children":31,"page":62},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F2.concepts",[32,37,42,47,53,59],{"title":33,"path":34,"stem":35,"order":10,"icon":36},"Events","\u002Fdocs\u002Fconcepts\u002Fevents","docs\u002F2.concepts\u002F1.events","i-lucide-zap",{"title":38,"path":39,"stem":40,"order":16,"icon":41},"Transports","\u002Fdocs\u002Fconcepts\u002Ftransports","docs\u002F2.concepts\u002F2.transports","i-lucide-network",{"title":43,"path":44,"stem":45,"order":22,"icon":46},"Module System","\u002Fdocs\u002Fconcepts\u002Fmodules","docs\u002F2.concepts\u002F3.modules","i-lucide-puzzle",{"title":48,"path":49,"stem":50,"order":51,"icon":52},"Flows","\u002Fdocs\u002Fconcepts\u002Fflows","docs\u002F2.concepts\u002F4.flows",4,"i-lucide-workflow",{"title":54,"path":55,"stem":56,"order":57,"icon":58},"Scheduler","\u002Fdocs\u002Fconcepts\u002Fscheduler","docs\u002F2.concepts\u002F5.scheduler",5,"i-lucide-clock",{"title":28,"path":60,"stem":61,"order":16},"\u002Fdocs\u002Fconcepts\u002F_dir","docs\u002F2.concepts\u002F_dir",false,{"title":64,"path":65,"stem":66,"children":67,"page":62},"Guides","\u002Fdocs\u002Fguides","docs\u002F3.guides",[68,73,77,81,85,89,93,98,104,110,116,122,126],{"title":69,"path":70,"stem":71,"order":10,"icon":72},"Creating a Go App","\u002Fdocs\u002Fguides\u002Fcreating-go-app","docs\u002F3.guides\u002F1.creating-go-app","i-lucide-terminal",{"title":74,"path":75,"stem":76},"E2E tests & demo videos","\u002Fdocs\u002Fguides\u002Fe2e-and-demo-videos","docs\u002F3.guides\u002F10.e2e-and-demo-videos",{"title":78,"path":79,"stem":80,"icon":17},"Deploying to production","\u002Fdocs\u002Fguides\u002Fdeploying-to-production","docs\u002F3.guides\u002F11.deploying-to-production",{"title":82,"path":83,"stem":84,"order":16,"icon":46},"Creating a Go Module","\u002Fdocs\u002Fguides\u002Fcreating-go-module","docs\u002F3.guides\u002F2.creating-go-module",{"title":86,"path":87,"stem":88,"order":22,"icon":36},"Adding Events","\u002Fdocs\u002Fguides\u002Fadding-events-to-go-module","docs\u002F3.guides\u002F3.adding-events-to-go-module",{"title":90,"path":91,"stem":92,"order":51,"icon":52},"FlowDSL to Service","\u002Fdocs\u002Fguides\u002Fflowdsl-to-redelay","docs\u002F3.guides\u002F4.flowdsl-to-redelay",{"title":94,"path":95,"stem":96,"order":57,"icon":97},"Choosing a Transport","\u002Fdocs\u002Fguides\u002Fchoosing-a-transport","docs\u002F3.guides\u002F5.choosing-a-transport","i-lucide-git-branch",{"title":99,"path":100,"stem":101,"order":102,"icon":103},"Module Browser (\u002Fmodules)","\u002Fdocs\u002Fguides\u002Fmodules-browser","docs\u002F3.guides\u002F6.modules-browser",6,"i-lucide-layout-dashboard",{"title":105,"path":106,"stem":107,"order":108,"icon":109},"Running Flows","\u002Fdocs\u002Fguides\u002Frunning-flows","docs\u002F3.guides\u002F7.running-flows",7,"i-lucide-play-circle",{"title":111,"path":112,"stem":113,"order":114,"icon":115},"Trace + Live Observability","\u002Fdocs\u002Fguides\u002Fobservability","docs\u002F3.guides\u002F8.observability",8,"i-lucide-activity",{"title":117,"path":118,"stem":119,"order":120,"icon":121},"Project AI Assistant","\u002Fdocs\u002Fguides\u002Fai-assistant","docs\u002F3.guides\u002F9.ai-assistant",9,"i-lucide-sparkles",{"title":123,"path":124,"stem":125},"Debug taps — trace live data through any node","\u002Fdocs\u002Fguides\u002Fdebug-taps","docs\u002F3.guides\u002F9.debug-taps",{"title":64,"path":127,"stem":128,"order":22},"\u002Fdocs\u002Fguides\u002F_dir","docs\u002F3.guides\u002F_dir",{"title":130,"path":131,"stem":132,"children":133,"page":62},"Reference","\u002Fdocs\u002Freference","docs\u002F4.reference",[134,139,143,148,153,158,163,168,172,177,182,187,193,199,205,210,215,219,225,230,236,242,247,253,259,263,267,273,278,284],{"title":135,"path":136,"stem":137,"order":10,"icon":138},"Go Framework","\u002Fdocs\u002Freference\u002Fgo-framework","docs\u002F4.reference\u002F01.go-framework","i-simple-icons-go",{"title":140,"path":141,"stem":142,"order":16,"icon":46},"Built-in Modules","\u002Fdocs\u002Freference\u002Fgo-modules","docs\u002F4.reference\u002F02.go-modules",{"title":144,"path":145,"stem":146,"order":22,"icon":147},"Domain Addon Modules","\u002Fdocs\u002Freference\u002Fgo-modules-addons","docs\u002F4.reference\u002F03.go-modules-addons","i-lucide-blocks",{"title":149,"path":150,"stem":151,"order":51,"icon":152},"Go Events","\u002Fdocs\u002Freference\u002Fgo-events","docs\u002F4.reference\u002F04.go-events","i-lucide-radio",{"title":154,"path":155,"stem":156,"order":57,"icon":157},"Email Module","\u002Fdocs\u002Freference\u002Fgo-module-email","docs\u002F4.reference\u002F05.go-module-email","i-lucide-mail",{"title":159,"path":160,"stem":161,"order":102,"icon":162},"Go Core & IR","\u002Fdocs\u002Freference\u002Fgo-core","docs\u002F4.reference\u002F06.go-core","i-lucide-cpu",{"title":164,"path":165,"stem":166,"order":108,"icon":167},"Module Definition Files","\u002Fdocs\u002Freference\u002Fgo-module-files","docs\u002F4.reference\u002F07.go-module-files","i-lucide-file-code",{"title":169,"path":170,"stem":171,"order":114,"icon":72},"CLI Reference","\u002Fdocs\u002Freference\u002Fgo-cli","docs\u002F4.reference\u002F08.go-cli",{"title":173,"path":174,"stem":175,"order":120,"icon":176},"Go Formats","\u002Fdocs\u002Freference\u002Fgo-formats","docs\u002F4.reference\u002F09.go-formats","i-lucide-file-json",{"title":178,"path":179,"stem":180,"order":181,"icon":152},"AsyncAPI Module","\u002Fdocs\u002Freference\u002Fgo-asyncapi","docs\u002F4.reference\u002F10.go-asyncapi",10,{"title":183,"path":184,"stem":185,"order":186,"icon":52},"Go FlowDSL","\u002Fdocs\u002Freference\u002Fgo-flowdsl","docs\u002F4.reference\u002F11.go-flowdsl",11,{"title":188,"path":189,"stem":190,"order":191,"icon":192},"FlowDSL Examples","\u002Fdocs\u002Freference\u002Fflowdsl-examples","docs\u002F4.reference\u002F12.flowdsl-examples",12,"i-lucide-file-code-2",{"title":194,"path":195,"stem":196,"order":197,"icon":198},"FlowDSL Sync","\u002Fdocs\u002Freference\u002Fflowdsl-sync","docs\u002F4.reference\u002F13.flowdsl-sync",13,"i-lucide-refresh-cw",{"title":200,"path":201,"stem":202,"order":203,"icon":204},"Node.js Framework","\u002Fdocs\u002Freference\u002Fjs-framework","docs\u002F4.reference\u002F14.js-framework",14,"i-simple-icons-nodedotjs",{"title":206,"path":207,"stem":208,"order":203,"icon":209},"Python Framework","\u002Fdocs\u002Freference\u002Fpy-framework","docs\u002F4.reference\u002F14.py-framework","i-simple-icons-python",{"title":211,"path":212,"stem":213,"order":214,"icon":204},"Node.js Events","\u002Fdocs\u002Freference\u002Fjs-events","docs\u002F4.reference\u002F15.js-events",15,{"title":216,"path":217,"stem":218,"order":214,"icon":209},"Python Events","\u002Fdocs\u002Freference\u002Fpy-events","docs\u002F4.reference\u002F15.py-events",{"title":220,"path":221,"stem":222,"order":223,"icon":224},"go-ai — LLM Providers, Guard, Ledger","\u002Fdocs\u002Freference\u002Fgo-ai","docs\u002F4.reference\u002F16.go-ai",16,"i-lucide-brain-circuit",{"title":226,"path":227,"stem":228,"order":229,"icon":41},"Infrastructure Modules","\u002Fdocs\u002Freference\u002Fgeneric-infra-modules","docs\u002F4.reference\u002F17.generic-infra-modules",17,{"title":231,"path":232,"stem":233,"order":234,"icon":235},"Flow Templates","\u002Fdocs\u002Freference\u002Fflow-templates","docs\u002F4.reference\u002F18.flow-templates",18,"i-lucide-library-big",{"title":237,"path":238,"stem":239,"order":240,"icon":241},"Assistant (chat + handoff)","\u002Fdocs\u002Freference\u002Fassistant","docs\u002F4.reference\u002F19.assistant",19,"i-lucide-messages-square",{"title":243,"path":244,"stem":245,"order":246,"icon":41},"Coordination","\u002Fdocs\u002Freference\u002Fcoordination","docs\u002F4.reference\u002F20.coordination",20,{"title":248,"path":249,"stem":250,"order":251,"icon":252},"Search (vector)","\u002Fdocs\u002Freference\u002Fsearch","docs\u002F4.reference\u002F21.search",21,"i-lucide-search",{"title":254,"path":255,"stem":256,"order":257,"icon":258},"Profiles","\u002Fdocs\u002Freference\u002Fprofiles","docs\u002F4.reference\u002F22.profiles",22,"i-lucide-bookmark",{"title":260,"path":261,"stem":262},"Flow-driven HTTP endpoints","\u002Fdocs\u002Freference\u002Fflow-driven-endpoints","docs\u002F4.reference\u002F23.flow-driven-endpoints",{"title":264,"path":265,"stem":266},"Deployments","\u002Fdocs\u002Freference\u002Fdeployments","docs\u002F4.reference\u002F24.deployments",{"title":268,"path":269,"stem":270,"order":271,"icon":272},"i18n (translations)","\u002Fdocs\u002Freference\u002Fi18n","docs\u002F4.reference\u002F25.i18n",25,"i-lucide-languages",{"title":274,"path":275,"stem":276,"order":277,"icon":152},"WebSockets","\u002Fdocs\u002Freference\u002Fwebsockets","docs\u002F4.reference\u002F26.websockets",26,{"title":279,"path":280,"stem":281,"order":282,"icon":283},"Localized content","\u002Fdocs\u002Freference\u002Flocalized-content","docs\u002F4.reference\u002F27.localized-content",27,"i-lucide-file-text",{"title":130,"path":285,"stem":286,"order":51},"\u002Fdocs\u002Freference\u002F_dir","docs\u002F4.reference\u002F_dir",{"title":288,"path":289,"stem":290,"children":291,"page":62},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F5.integrations",[292,296,300,304,308],{"title":293,"path":294,"stem":295,"order":10,"icon":52},"FlowDSL","\u002Fdocs\u002Fintegrations\u002Fflowdsl","docs\u002F5.integrations\u002F1.flowdsl",{"title":297,"path":298,"stem":299,"order":16,"icon":283},"OpenAPI","\u002Fdocs\u002Fintegrations\u002Fopenapi","docs\u002F5.integrations\u002F2.openapi",{"title":301,"path":302,"stem":303,"order":22,"icon":152},"AsyncAPI","\u002Fdocs\u002Fintegrations\u002Fasyncapi","docs\u002F5.integrations\u002F3.asyncapi",{"title":305,"path":306,"stem":307},"MCP Integration","\u002Fdocs\u002Fintegrations\u002Fmcp","docs\u002F5.integrations\u002F4.mcp",{"title":288,"path":309,"stem":310,"order":57},"\u002Fdocs\u002Fintegrations\u002F_dir","docs\u002F5.integrations\u002F_dir",{"title":312,"path":313,"stem":314,"children":315},"FlowDSL Node Catalog","\u002Fdocs\u002Fnodes","docs\u002F5.nodes\u002Findex",[316,317,321,325,329,333,337,341,345,349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417,421,425,429,433,437,441,445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749,753,757,761,765,769,773,777,781,785,789,793,797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865,869,873,877,881,885,889],{"title":312,"path":313,"stem":314},{"title":318,"path":319,"stem":320,"order":57},"Node Catalog","\u002Fdocs\u002Fnodes\u002F_dir","docs\u002F5.nodes\u002F_dir",{"title":322,"path":323,"stem":324},"Record Alert","\u002Fdocs\u002Fnodes\u002Falerts_record","docs\u002F5.nodes\u002Falerts_record",{"title":326,"path":327,"stem":328},"Log to API Log","\u002Fdocs\u002Fnodes\u002Fapilog_record","docs\u002F5.nodes\u002Fapilog_record",{"title":330,"path":331,"stem":332},"ClickHouse Exec","\u002Fdocs\u002Fnodes\u002Fclickhouse_exec","docs\u002F5.nodes\u002Fclickhouse_exec",{"title":334,"path":335,"stem":336},"ClickHouse Insert","\u002Fdocs\u002Fnodes\u002Fclickhouse_insert","docs\u002F5.nodes\u002Fclickhouse_insert",{"title":338,"path":339,"stem":340},"ClickHouse Query","\u002Fdocs\u002Fnodes\u002Fclickhouse_query","docs\u002F5.nodes\u002Fclickhouse_query",{"title":342,"path":343,"stem":344},"Array Op","\u002Fdocs\u002Fnodes\u002Fcore_array-ops","docs\u002F5.nodes\u002Fcore_array-ops",{"title":346,"path":347,"stem":348},"Assert","\u002Fdocs\u002Fnodes\u002Fcore_assert","docs\u002F5.nodes\u002Fcore_assert",{"title":350,"path":351,"stem":352},"Audit Emit","\u002Fdocs\u002Fnodes\u002Fcore_audit-emit","docs\u002F5.nodes\u002Fcore_audit-emit",{"title":354,"path":355,"stem":356},"Catch","\u002Fdocs\u002Fnodes\u002Fcore_catch","docs\u002F5.nodes\u002Fcore_catch",{"title":358,"path":359,"stem":360},"DateTime","\u002Fdocs\u002Fnodes\u002Fcore_datetime","docs\u002F5.nodes\u002Fcore_datetime",{"title":362,"path":363,"stem":364},"Dead Letter","\u002Fdocs\u002Fnodes\u002Fcore_dead-letter","docs\u002F5.nodes\u002Fcore_dead-letter",{"title":366,"path":367,"stem":368},"Delay","\u002Fdocs\u002Fnodes\u002Fcore_delay","docs\u002F5.nodes\u002Fcore_delay",{"title":370,"path":371,"stem":372},"ForEach","\u002Fdocs\u002Fnodes\u002Fcore_foreach","docs\u002F5.nodes\u002Fcore_foreach",{"title":374,"path":375,"stem":376},"Idempotency Key","\u002Fdocs\u002Fnodes\u002Fcore_idempotency-key","docs\u002F5.nodes\u002Fcore_idempotency-key",{"title":378,"path":379,"stem":380},"If","\u002Fdocs\u002Fnodes\u002Fcore_if","docs\u002F5.nodes\u002Fcore_if",{"title":382,"path":383,"stem":384},"Inspect","\u002Fdocs\u002Fnodes\u002Fcore_inspect","docs\u002F5.nodes\u002Fcore_inspect",{"title":386,"path":387,"stem":388},"JSON Merge","\u002Fdocs\u002Fnodes\u002Fcore_json-merge","docs\u002F5.nodes\u002Fcore_json-merge",{"title":390,"path":391,"stem":392},"JSON Schema Validate","\u002Fdocs\u002Fnodes\u002Fcore_json-schema-validate","docs\u002F5.nodes\u002Fcore_json-schema-validate",{"title":394,"path":395,"stem":396},"JSONPath Extract","\u002Fdocs\u002Fnodes\u002Fcore_jsonpath-extract","docs\u002F5.nodes\u002Fcore_jsonpath-extract",{"title":398,"path":399,"stem":400},"Log","\u002Fdocs\u002Fnodes\u002Fcore_log","docs\u002F5.nodes\u002Fcore_log",{"title":402,"path":403,"stem":404},"Math","\u002Fdocs\u002Fnodes\u002Fcore_math","docs\u002F5.nodes\u002Fcore_math",{"title":406,"path":407,"stem":408},"Merge","\u002Fdocs\u002Fnodes\u002Fcore_merge","docs\u002F5.nodes\u002Fcore_merge",{"title":410,"path":411,"stem":412},"Metric Counter","\u002Fdocs\u002Fnodes\u002Fcore_metric-counter","docs\u002F5.nodes\u002Fcore_metric-counter",{"title":414,"path":415,"stem":416},"Metric Gauge","\u002Fdocs\u002Fnodes\u002Fcore_metric-gauge","docs\u002F5.nodes\u002Fcore_metric-gauge",{"title":418,"path":419,"stem":420},"Mock","\u002Fdocs\u002Fnodes\u002Fcore_mock","docs\u002F5.nodes\u002Fcore_mock",{"title":422,"path":423,"stem":424},"No-op","\u002Fdocs\u002Fnodes\u002Fcore_noop","docs\u002F5.nodes\u002Fcore_noop",{"title":426,"path":427,"stem":428},"Object Omit","\u002Fdocs\u002Fnodes\u002Fcore_object-omit","docs\u002F5.nodes\u002Fcore_object-omit",{"title":430,"path":431,"stem":432},"Object Pick","\u002Fdocs\u002Fnodes\u002Fcore_object-pick","docs\u002F5.nodes\u002Fcore_object-pick",{"title":434,"path":435,"stem":436},"Parallel Fan-Out","\u002Fdocs\u002Fnodes\u002Fcore_parallel","docs\u002F5.nodes\u002Fcore_parallel",{"title":438,"path":439,"stem":440},"Raise","\u002Fdocs\u002Fnodes\u002Fcore_raise","docs\u002F5.nodes\u002Fcore_raise",{"title":442,"path":443,"stem":444},"Rate Limit Check","\u002Fdocs\u002Fnodes\u002Fcore_rate-limit-check","docs\u002F5.nodes\u002Fcore_rate-limit-check",{"title":446,"path":447,"stem":448},"Regex Extract","\u002Fdocs\u002Fnodes\u002Fcore_regex-extract","docs\u002F5.nodes\u002Fcore_regex-extract",{"title":450,"path":451,"stem":452},"Require Fields","\u002Fdocs\u002Fnodes\u002Fcore_require-fields","docs\u002F5.nodes\u002Fcore_require-fields",{"title":454,"path":455,"stem":456},"Rethrow","\u002Fdocs\u002Fnodes\u002Fcore_rethrow","docs\u002F5.nodes\u002Fcore_rethrow",{"title":458,"path":459,"stem":460},"Return","\u002Fdocs\u002Fnodes\u002Fcore_return","docs\u002F5.nodes\u002Fcore_return",{"title":462,"path":463,"stem":464},"HMAC Signature Verify","\u002Fdocs\u002Fnodes\u002Fcore_signature-verify","docs\u002F5.nodes\u002Fcore_signature-verify",{"title":466,"path":467,"stem":468},"String Op","\u002Fdocs\u002Fnodes\u002Fcore_string-ops","docs\u002F5.nodes\u002Fcore_string-ops",{"title":470,"path":471,"stem":472},"Subflow Invoke","\u002Fdocs\u002Fnodes\u002Fcore_subflow-invoke","docs\u002F5.nodes\u002Fcore_subflow-invoke",{"title":474,"path":475,"stem":476},"Switch","\u002Fdocs\u002Fnodes\u002Fcore_switch","docs\u002F5.nodes\u002Fcore_switch",{"title":478,"path":479,"stem":480},"Template Render","\u002Fdocs\u002Fnodes\u002Fcore_template-render","docs\u002F5.nodes\u002Fcore_template-render",{"title":482,"path":483,"stem":484},"Throttle","\u002Fdocs\u002Fnodes\u002Fcore_throttle","docs\u002F5.nodes\u002Fcore_throttle",{"title":486,"path":487,"stem":488},"Timeout","\u002Fdocs\u002Fnodes\u002Fcore_timeout","docs\u002F5.nodes\u002Fcore_timeout",{"title":490,"path":491,"stem":492},"Type Cast","\u002Fdocs\u002Fnodes\u002Fcore_type-cast","docs\u002F5.nodes\u002Fcore_type-cast",{"title":494,"path":495,"stem":496},"Webhook Respond","\u002Fdocs\u002Fnodes\u002Fcore_webhook-respond","docs\u002F5.nodes\u002Fcore_webhook-respond",{"title":498,"path":499,"stem":500},"File Delete","\u002Fdocs\u002Fnodes\u002Ffilesys_delete","docs\u002F5.nodes\u002Ffilesys_delete",{"title":502,"path":503,"stem":504},"Directory List","\u002Fdocs\u002Fnodes\u002Ffilesys_list","docs\u002F5.nodes\u002Ffilesys_list",{"title":506,"path":507,"stem":508},"File Read","\u002Fdocs\u002Fnodes\u002Ffilesys_read","docs\u002F5.nodes\u002Ffilesys_read",{"title":510,"path":511,"stem":512},"File Stat","\u002Fdocs\u002Fnodes\u002Ffilesys_stat","docs\u002F5.nodes\u002Ffilesys_stat",{"title":514,"path":515,"stem":516},"File Write","\u002Fdocs\u002Fnodes\u002Ffilesys_write","docs\u002F5.nodes\u002Ffilesys_write",{"title":518,"path":519,"stem":520},"FTP Delete","\u002Fdocs\u002Fnodes\u002Fftp_delete","docs\u002F5.nodes\u002Fftp_delete",{"title":522,"path":523,"stem":524},"FTP Download","\u002Fdocs\u002Fnodes\u002Fftp_download","docs\u002F5.nodes\u002Fftp_download",{"title":526,"path":527,"stem":528},"FTP List","\u002Fdocs\u002Fnodes\u002Fftp_list","docs\u002F5.nodes\u002Fftp_list",{"title":530,"path":531,"stem":532},"FTP Upload","\u002Fdocs\u002Fnodes\u002Fftp_upload","docs\u002F5.nodes\u002Fftp_upload",{"title":534,"path":535,"stem":536},"HTTP DELETE","\u002Fdocs\u002Fnodes\u002Fhttp_delete","docs\u002F5.nodes\u002Fhttp_delete",{"title":538,"path":539,"stem":540},"HTTP GET","\u002Fdocs\u002Fnodes\u002Fhttp_get","docs\u002F5.nodes\u002Fhttp_get",{"title":542,"path":543,"stem":544},"HTTP POST","\u002Fdocs\u002Fnodes\u002Fhttp_post","docs\u002F5.nodes\u002Fhttp_post",{"title":546,"path":547,"stem":548},"HTTP PUT","\u002Fdocs\u002Fnodes\u002Fhttp_put","docs\u002F5.nodes\u002Fhttp_put",{"title":550,"path":551,"stem":552},"HTTP Request","\u002Fdocs\u002Fnodes\u002Fhttp_request","docs\u002F5.nodes\u002Fhttp_request",{"title":554,"path":555,"stem":556},"Fill Translations","\u002Fdocs\u002Fnodes\u002Fi18n_fill-translations","docs\u002F5.nodes\u002Fi18n_fill-translations",{"title":558,"path":559,"stem":560},"Resolve Locale","\u002Fdocs\u002Fnodes\u002Fi18n_resolve-locale","docs\u002F5.nodes\u002Fi18n_resolve-locale",{"title":562,"path":563,"stem":564},"Translate","\u002Fdocs\u002Fnodes\u002Fi18n_translate","docs\u002F5.nodes\u002Fi18n_translate",{"title":566,"path":567,"stem":568},"Mongo AGGREGATE","\u002Fdocs\u002Fnodes\u002Fmongoops_aggregate","docs\u002F5.nodes\u002Fmongoops_aggregate",{"title":570,"path":571,"stem":572},"Mongo DELETE","\u002Fdocs\u002Fnodes\u002Fmongoops_delete","docs\u002F5.nodes\u002Fmongoops_delete",{"title":574,"path":575,"stem":576},"Mongo FIND","\u002Fdocs\u002Fnodes\u002Fmongoops_find","docs\u002F5.nodes\u002Fmongoops_find",{"title":578,"path":579,"stem":580},"Mongo FIND ONE","\u002Fdocs\u002Fnodes\u002Fmongoops_find-one","docs\u002F5.nodes\u002Fmongoops_find-one",{"title":582,"path":583,"stem":584},"Mongo INSERT","\u002Fdocs\u002Fnodes\u002Fmongoops_insert","docs\u002F5.nodes\u002Fmongoops_insert",{"title":586,"path":587,"stem":588},"Mongo UPDATE","\u002Fdocs\u002Fnodes\u002Fmongoops_update","docs\u002F5.nodes\u002Fmongoops_update",{"title":590,"path":591,"stem":592},"Postgres COPY FROM","\u002Fdocs\u002Fnodes\u002Fpostgres_copy-from","docs\u002F5.nodes\u002Fpostgres_copy-from",{"title":594,"path":595,"stem":596},"Postgres Exec","\u002Fdocs\u002Fnodes\u002Fpostgres_exec","docs\u002F5.nodes\u002Fpostgres_exec",{"title":598,"path":599,"stem":600},"Postgres Query","\u002Fdocs\u002Fnodes\u002Fpostgres_query","docs\u002F5.nodes\u002Fpostgres_query",{"title":602,"path":603,"stem":604},"Postgres Transaction","\u002Fdocs\u002Fnodes\u002Fpostgres_transaction","docs\u002F5.nodes\u002Fpostgres_transaction",{"title":606,"path":607,"stem":608},"RabbitMQ Consume","\u002Fdocs\u002Fnodes\u002Frabbitmq_consume","docs\u002F5.nodes\u002Frabbitmq_consume",{"title":610,"path":611,"stem":612},"RabbitMQ Declare","\u002Fdocs\u002Fnodes\u002Frabbitmq_declare","docs\u002F5.nodes\u002Frabbitmq_declare",{"title":614,"path":615,"stem":616},"RabbitMQ Publish","\u002Fdocs\u002Fnodes\u002Frabbitmq_publish","docs\u002F5.nodes\u002Frabbitmq_publish",{"title":618,"path":619,"stem":620},"Auth Login","\u002Fdocs\u002Fnodes\u002Fredelay_auth-login","docs\u002F5.nodes\u002Fredelay_auth-login",{"title":622,"path":623,"stem":624},"Require Permission","\u002Fdocs\u002Fnodes\u002Fredelay_auth-require-permission","docs\u002F5.nodes\u002Fredelay_auth-require-permission",{"title":626,"path":627,"stem":628},"Validate Token","\u002Fdocs\u002Fnodes\u002Fredelay_auth-validate-token","docs\u002F5.nodes\u002Fredelay_auth-validate-token",{"title":630,"path":631,"stem":632},"Render Email Template","\u002Fdocs\u002Fnodes\u002Fredelay_email-render-template","docs\u002F5.nodes\u002Fredelay_email-render-template",{"title":634,"path":635,"stem":636},"Send Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send","docs\u002F5.nodes\u002Fredelay_email-send",{"title":638,"path":639,"stem":640},"Send Templated Email","\u002Fdocs\u002Fnodes\u002Fredelay_email-send-templated","docs\u002F5.nodes\u002Fredelay_email-send-templated",{"title":642,"path":643,"stem":644},"Event Source","\u002Fdocs\u002Fnodes\u002Fredelay_event-source","docs\u002F5.nodes\u002Fredelay_event-source",{"title":646,"path":647,"stem":648},"Create Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-create-group","docs\u002F5.nodes\u002Fredelay_groups-create-group",{"title":650,"path":651,"stem":652},"Delete Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-delete-group","docs\u002F5.nodes\u002Fredelay_groups-delete-group",{"title":654,"path":655,"stem":656},"Resolve Permissions","\u002Fdocs\u002Fnodes\u002Fredelay_groups-resolve-permissions","docs\u002F5.nodes\u002Fredelay_groups-resolve-permissions",{"title":658,"path":659,"stem":660},"Update Group","\u002Fdocs\u002Fnodes\u002Fredelay_groups-update-group","docs\u002F5.nodes\u002Fredelay_groups-update-group",{"title":662,"path":663,"stem":664},"HTTP Endpoint","\u002Fdocs\u002Fnodes\u002Fredelay_http-endpoint","docs\u002F5.nodes\u002Fredelay_http-endpoint",{"title":666,"path":667,"stem":668},"JSON Stream Source","\u002Fdocs\u002Fnodes\u002Fredelay_json-stream-source","docs\u002F5.nodes\u002Fredelay_json-stream-source",{"title":670,"path":671,"stem":672},"JSON → Event","\u002Fdocs\u002Fnodes\u002Fredelay_json-to-event","docs\u002F5.nodes\u002Fredelay_json-to-event",{"title":674,"path":675,"stem":676},"Kafka Produce","\u002Fdocs\u002Fnodes\u002Fredelay_kafka-produce","docs\u002F5.nodes\u002Fredelay_kafka-produce",{"title":678,"path":679,"stem":680},"Create Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-create","docs\u002F5.nodes\u002Fredelay_links-create",{"title":682,"path":683,"stem":684},"Delete Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-delete","docs\u002F5.nodes\u002Fredelay_links-delete",{"title":686,"path":687,"stem":688},"Resolve Short Link","\u002Fdocs\u002Fnodes\u002Fredelay_links-resolve","docs\u002F5.nodes\u002Fredelay_links-resolve",{"title":690,"path":691,"stem":692},"LLM Chat","\u002Fdocs\u002Fnodes\u002Fredelay_llm-chat","docs\u002F5.nodes\u002Fredelay_llm-chat",{"title":694,"path":695,"stem":696},"LLM Embed","\u002Fdocs\u002Fnodes\u002Fredelay_llm-embed","docs\u002F5.nodes\u002Fredelay_llm-embed",{"title":698,"path":699,"stem":700},"LLM Guard","\u002Fdocs\u002Fnodes\u002Fredelay_llm-guard","docs\u002F5.nodes\u002Fredelay_llm-guard",{"title":702,"path":703,"stem":704},"LLM Tool Router","\u002Fdocs\u002Fnodes\u002Fredelay_llm-tool-router","docs\u002F5.nodes\u002Fredelay_llm-tool-router",{"title":706,"path":707,"stem":708},"NATS Publish","\u002Fdocs\u002Fnodes\u002Fredelay_nats-publish","docs\u002F5.nodes\u002Fredelay_nats-publish",{"title":710,"path":711,"stem":712},"Mark Notification Read","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-mark-read","docs\u002F5.nodes\u002Fredelay_notifications-mark-read",{"title":714,"path":715,"stem":716},"Send Notification","\u002Fdocs\u002Fnodes\u002Fredelay_notifications-send","docs\u002F5.nodes\u002Fredelay_notifications-send",{"title":718,"path":719,"stem":720},"Redis Stream XADD","\u002Fdocs\u002Fnodes\u002Fredelay_redis-stream-publish","docs\u002F5.nodes\u002Fredelay_redis-stream-publish",{"title":722,"path":723,"stem":724},"S3 Copy Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-copy-object","docs\u002F5.nodes\u002Fredelay_s3-copy-object",{"title":726,"path":727,"stem":728},"S3 Delete Many","\u002Fdocs\u002Fnodes\u002Fredelay_s3-delete-many","docs\u002F5.nodes\u002Fredelay_s3-delete-many",{"title":730,"path":731,"stem":732},"S3 Head Object","\u002Fdocs\u002Fnodes\u002Fredelay_s3-head-object","docs\u002F5.nodes\u002Fredelay_s3-head-object",{"title":734,"path":735,"stem":736},"S3 List Objects","\u002Fdocs\u002Fnodes\u002Fredelay_s3-list-objects","docs\u002F5.nodes\u002Fredelay_s3-list-objects",{"title":738,"path":739,"stem":740},"Create Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-create-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-create-schedule",{"title":742,"path":743,"stem":744},"Cron Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-cron-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-cron-trigger",{"title":746,"path":747,"stem":748},"Delete Schedule","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-delete-schedule","docs\u002F5.nodes\u002Fredelay_scheduler-delete-schedule",{"title":750,"path":751,"stem":752},"Interval Trigger","\u002Fdocs\u002Fnodes\u002Fredelay_scheduler-interval-trigger","docs\u002F5.nodes\u002Fredelay_scheduler-interval-trigger",{"title":754,"path":755,"stem":756},"Search Query","\u002Fdocs\u002Fnodes\u002Fredelay_search-query","docs\u002F5.nodes\u002Fredelay_search-query",{"title":758,"path":759,"stem":760},"Search Upsert","\u002Fdocs\u002Fnodes\u002Fredelay_search-upsert","docs\u002F5.nodes\u002Fredelay_search-upsert",{"title":762,"path":763,"stem":764},"Delete Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-delete","docs\u002F5.nodes\u002Fredelay_settings-delete",{"title":766,"path":767,"stem":768},"Get Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-get","docs\u002F5.nodes\u002Fredelay_settings-get",{"title":770,"path":771,"stem":772},"Set Setting","\u002Fdocs\u002Fnodes\u002Fredelay_settings-set","docs\u002F5.nodes\u002Fredelay_settings-set",{"title":774,"path":775,"stem":776},"Delete File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-delete","docs\u002F5.nodes\u002Fredelay_storage-delete",{"title":778,"path":779,"stem":780},"Download File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-download","docs\u002F5.nodes\u002Fredelay_storage-download",{"title":782,"path":783,"stem":784},"Generate Presigned URL","\u002Fdocs\u002Fnodes\u002Fredelay_storage-presign-url","docs\u002F5.nodes\u002Fredelay_storage-presign-url",{"title":786,"path":787,"stem":788},"Upload File","\u002Fdocs\u002Fnodes\u002Fredelay_storage-upload","docs\u002F5.nodes\u002Fredelay_storage-upload",{"title":790,"path":791,"stem":792},"Subworkflow","\u002Fdocs\u002Fnodes\u002Fredelay_subworkflow","docs\u002F5.nodes\u002Fredelay_subworkflow",{"title":794,"path":795,"stem":796},"Activate User","\u002Fdocs\u002Fnodes\u002Fredelay_users-activate","docs\u002F5.nodes\u002Fredelay_users-activate",{"title":798,"path":799,"stem":800},"Create Pending User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-pending","docs\u002F5.nodes\u002Fredelay_users-create-pending",{"title":802,"path":803,"stem":804},"Create User","\u002Fdocs\u002Fnodes\u002Fredelay_users-create-user","docs\u002F5.nodes\u002Fredelay_users-create-user",{"title":806,"path":807,"stem":808},"Delete User","\u002Fdocs\u002Fnodes\u002Fredelay_users-delete-user","docs\u002F5.nodes\u002Fredelay_users-delete-user",{"title":810,"path":811,"stem":812},"Find User By Email","\u002Fdocs\u002Fnodes\u002Fredelay_users-find-by-email","docs\u002F5.nodes\u002Fredelay_users-find-by-email",{"title":814,"path":815,"stem":816},"Get User","\u002Fdocs\u002Fnodes\u002Fredelay_users-get-user","docs\u002F5.nodes\u002Fredelay_users-get-user",{"title":818,"path":819,"stem":820},"List Users","\u002Fdocs\u002Fnodes\u002Fredelay_users-list-users","docs\u002F5.nodes\u002Fredelay_users-list-users",{"title":822,"path":823,"stem":824},"Update User","\u002Fdocs\u002Fnodes\u002Fredelay_users-update-user","docs\u002F5.nodes\u002Fredelay_users-update-user",{"title":826,"path":827,"stem":828},"Request Email Verification (legacy)","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request","docs\u002F5.nodes\u002Fredelay_verification-request",{"title":830,"path":831,"stem":832},"Request Email Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-email","docs\u002F5.nodes\u002Fredelay_verification-request-email",{"title":834,"path":835,"stem":836},"Request SMS Verification","\u002Fdocs\u002Fnodes\u002Fredelay_verification-request-sms","docs\u002F5.nodes\u002Fredelay_verification-request-sms",{"title":838,"path":839,"stem":840},"Verify Token","\u002Fdocs\u002Fnodes\u002Fredelay_verification-verify","docs\u002F5.nodes\u002Fredelay_verification-verify",{"title":842,"path":843,"stem":844},"Redis DEL","\u002Fdocs\u002Fnodes\u002Fredisops_del","docs\u002F5.nodes\u002Fredisops_del",{"title":846,"path":847,"stem":848},"Redis EXPIRE","\u002Fdocs\u002Fnodes\u002Fredisops_expire","docs\u002F5.nodes\u002Fredisops_expire",{"title":850,"path":851,"stem":852},"Redis GET","\u002Fdocs\u002Fnodes\u002Fredisops_get","docs\u002F5.nodes\u002Fredisops_get",{"title":854,"path":855,"stem":856},"Redis HGET","\u002Fdocs\u002Fnodes\u002Fredisops_hget","docs\u002F5.nodes\u002Fredisops_hget",{"title":858,"path":859,"stem":860},"Redis HSET","\u002Fdocs\u002Fnodes\u002Fredisops_hset","docs\u002F5.nodes\u002Fredisops_hset",{"title":862,"path":863,"stem":864},"Redis INCR","\u002Fdocs\u002Fnodes\u002Fredisops_incr","docs\u002F5.nodes\u002Fredisops_incr",{"title":866,"path":867,"stem":868},"Redis LPOP","\u002Fdocs\u002Fnodes\u002Fredisops_lpop","docs\u002F5.nodes\u002Fredisops_lpop",{"title":870,"path":871,"stem":872},"Redis LPUSH","\u002Fdocs\u002Fnodes\u002Fredisops_lpush","docs\u002F5.nodes\u002Fredisops_lpush",{"title":874,"path":875,"stem":876},"Redis PUBLISH","\u002Fdocs\u002Fnodes\u002Fredisops_publish","docs\u002F5.nodes\u002Fredisops_publish",{"title":878,"path":879,"stem":880},"Redis SET","\u002Fdocs\u002Fnodes\u002Fredisops_set","docs\u002F5.nodes\u002Fredisops_set",{"title":882,"path":883,"stem":884},"SFTP Download","\u002Fdocs\u002Fnodes\u002Fsftp_download","docs\u002F5.nodes\u002Fsftp_download",{"title":886,"path":887,"stem":888},"SFTP Upload","\u002Fdocs\u002Fnodes\u002Fsftp_upload","docs\u002F5.nodes\u002Fsftp_upload",{"title":890,"path":891,"stem":892},"Send SMS","\u002Fdocs\u002Fnodes\u002Fsms_send","docs\u002F5.nodes\u002Fsms_send",{"title":894,"path":895,"stem":896,"children":897,"page":62},"Rfcs","\u002Fdocs\u002Frfcs","docs\u002F6.rfcs",[898],{"title":899,"path":900,"stem":901},"RFC 0001 — Worker Assignment for Flow Deployments","\u002Fdocs\u002Frfcs\u002F0001-worker-assignment","docs\u002F6.rfcs\u002F0001-worker-assignment",{"title":903,"path":904,"stem":905,"children":906,"page":62},"Admin","\u002Fdocs\u002Fadmin","docs\u002F7.admin",[907,912,917,922,927,932,937,941,946],{"title":5,"path":908,"stem":909,"order":910,"icon":911},"\u002Fdocs\u002Fadmin\u002Foverview","docs\u002F7.admin\u002F00.overview",0,"i-lucide-compass",{"title":913,"path":914,"stem":915,"order":10,"icon":916},"Getting started","\u002Fdocs\u002Fadmin\u002Fgetting-started","docs\u002F7.admin\u002F01.getting-started","i-lucide-play",{"title":918,"path":919,"stem":920,"order":16,"icon":921},"Layered architecture","\u002Fdocs\u002Fadmin\u002Flayered-architecture","docs\u002F7.admin\u002F02.layered-architecture","i-lucide-layers",{"title":923,"path":924,"stem":925,"order":22,"icon":926},"Building a custom admin project","\u002Fdocs\u002Fadmin\u002Fbuilding-a-custom-admin-project","docs\u002F7.admin\u002F03.building-a-custom-admin-project","i-lucide-folder-plus",{"title":928,"path":929,"stem":930,"order":51,"icon":931},"Building admin modules","\u002Fdocs\u002Fadmin\u002Fbuilding-admin-modules","docs\u002F7.admin\u002F04.building-admin-modules","i-lucide-package-plus",{"title":933,"path":934,"stem":935,"order":57,"icon":936},"Base module reference","\u002Fdocs\u002Fadmin\u002Freference-base-modules","docs\u002F7.admin\u002F05.reference-base-modules","i-lucide-boxes",{"title":938,"path":939,"stem":940,"order":102,"icon":17},"Deployment","\u002Fdocs\u002Fadmin\u002Fdeployment","docs\u002F7.admin\u002F06.deployment",{"title":942,"path":943,"stem":944,"order":108,"icon":945},"Consuming the base layer (versioned)","\u002Fdocs\u002Fadmin\u002Fconsuming-the-base-layer","docs\u002F7.admin\u002F07.consuming-the-base-layer","i-lucide-package",{"title":947,"path":948,"stem":949,"order":108},"Admin UI","\u002Fdocs\u002Fadmin\u002F_dir","docs\u002F7.admin\u002F_dir",{"title":951,"path":952,"stem":953,"children":954,"page":62},"Services","\u002Fdocs\u002Fservices","docs\u002F8.services",[955,960],{"title":956,"path":957,"stem":958,"order":10,"icon":959},"Custom development & support services","\u002Fdocs\u002Fservices\u002Fcustom-development","docs\u002F8.services\u002F1.custom-development","i-lucide-briefcase",{"title":951,"path":961,"stem":962,"icon":959,"order":963},"\u002Fdocs\u002Fservices\u002F_dir","docs\u002F8.services\u002F_dir",80,{"title":965,"path":966,"stem":967,"order":910},"Dir","\u002Fdocs\u002F_dir","docs\u002F_dir",{"id":969,"title":78,"body":970,"description":2061,"extension":2062,"links":2063,"meta":2064,"navigation":2065,"path":79,"seo":2066,"stem":80,"__hash__":2067},"docs\u002Fdocs\u002F3.guides\u002F11.deploying-to-production.md",{"type":971,"value":972,"toc":2054},"minimark",[973,977,986,1044,1066,1071,1074,1167,1170,1174,1270,1273,1375,1378,1415,1419,1422,1551,1570,1618,1622,1625,1704,1725,1728,1761,1764,1783,1787,1793,1994,2050],[974,975,78],"h1",{"id":976},"deploying-to-production",[978,979,980,981,985],"p",{},"This is how the Redelay reference backend (",[982,983,984],"code",{},"api.redelay.com",") and the\ngymmer.com backend ship. The app repository owns three files, and nothing\noutside it is needed to build or deploy:",[987,988,989,1002],"table",{},[990,991,992],"thead",{},[993,994,995,999],"tr",{},[996,997,998],"th",{},"File",[996,1000,1001],{},"Job",[1003,1004,1005,1016,1026],"tbody",{},[993,1006,1007,1013],{},[1008,1009,1010],"td",{},[982,1011,1012],{},"Dockerfile",[1008,1014,1015],{},"Builds every binary from this checkout alone, fetching private framework modules over SSH",[993,1017,1018,1023],{},[1008,1019,1020],{},[982,1021,1022],{},"docker-swarm-stack.yml",[1008,1024,1025],{},"The swarm services: placement, healthchecks, rollout and rollback policy, Traefik labels",[993,1027,1028,1033],{},[1008,1029,1030],{},[982,1031,1032],{},".github\u002Fworkflows\u002Fdeploy-production.yml",[1008,1034,1035,1036,1039,1040,1043],{},"Push to ",[982,1037,1038],{},"production"," → build, push to the registry, ",[982,1041,1042],{},"docker stack deploy",", wait for the rollout",[978,1045,1046,1047,1051,1052,1055,1056,1059,1060,1065],{},"It relies on the app being ",[1048,1049,1050],"strong",{},"Mode B",": ",[982,1053,1054],{},"go.mod"," pins released framework\ntags with no ",[982,1057,1058],{},"replace"," (see\n",[1061,1062,1064],"a",{"href":1063},"\u002Fdocs\u002Fguides\u002Fcreating-go-app#depend-on-the-framework-versioned-mode-b-recommended","Creating a Go App → Mode B",").\nA build that relies on sibling checkouts breaks as soon as the siblings'\nbranches drift apart. The Redelay backend's own CI failed for seven\nweeks for exactly this reason before it moved to Mode B.",[1067,1068,1070],"h2",{"id":1069},"picking-up-framework-changes","Picking up framework changes",[978,1072,1073],{},"A deployed app gets framework changes only when you move a pin:",[1075,1076,1081],"pre",{"className":1077,"code":1078,"language":1079,"meta":1080,"style":1080},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# in the library: tag the change\ngit tag v0.44.0 && git push origin v0.44.0\n# in the app: move the pin, build, commit\ngo get github.com\u002Fredelay\u002Fgo-modules@v0.44.0\ngo mod tidy && go build .\u002F... && go test .\u002F...\n","bash","",[982,1082,1083,1091,1120,1125,1136],{"__ignoreMap":1080},[1084,1085,1087],"span",{"class":1086,"line":10},"line",[1084,1088,1090],{"class":1089},"sHwdD","# in the library: tag the change\n",[1084,1092,1093,1097,1101,1104,1108,1111,1114,1117],{"class":1086,"line":16},[1084,1094,1096],{"class":1095},"sBMFI","git",[1084,1098,1100],{"class":1099},"sfazB"," tag",[1084,1102,1103],{"class":1099}," v0.44.0",[1084,1105,1107],{"class":1106},"sMK4o"," &&",[1084,1109,1110],{"class":1095}," git",[1084,1112,1113],{"class":1099}," push",[1084,1115,1116],{"class":1099}," origin",[1084,1118,1119],{"class":1099}," v0.44.0\n",[1084,1121,1122],{"class":1086,"line":22},[1084,1123,1124],{"class":1089},"# in the app: move the pin, build, commit\n",[1084,1126,1127,1130,1133],{"class":1086,"line":51},[1084,1128,1129],{"class":1095},"go",[1084,1131,1132],{"class":1099}," get",[1084,1134,1135],{"class":1099}," github.com\u002Fredelay\u002Fgo-modules@v0.44.0\n",[1084,1137,1138,1140,1143,1146,1148,1151,1154,1157,1159,1161,1164],{"class":1086,"line":57},[1084,1139,1129],{"class":1095},[1084,1141,1142],{"class":1099}," mod",[1084,1144,1145],{"class":1099}," tidy",[1084,1147,1107],{"class":1106},[1084,1149,1150],{"class":1095}," go",[1084,1152,1153],{"class":1099}," build",[1084,1155,1156],{"class":1099}," .\u002F...",[1084,1158,1107],{"class":1106},[1084,1160,1150],{"class":1095},[1084,1162,1163],{"class":1099}," test",[1084,1165,1166],{"class":1099}," .\u002F...\n",[978,1168,1169],{},"Tagging a library never changes another project's build, because every\napp keeps its own pins. When several apps share the framework, starting a\nnew app on the same pin set as one already in production gives you a\nknown-good baseline.",[1067,1171,1173],{"id":1172},"the-dockerfile","The Dockerfile",[1075,1175,1179],{"className":1176,"code":1177,"language":1178,"meta":1080,"style":1080},"language-dockerfile shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","FROM golang:1.25 AS build\nWORKDIR \u002Fsrc\n\nENV GOPRIVATE=github.com\u002Fredelay\u002F*,github.com\u002Fflowdsl\u002F*,github.com\u002FFlowDSL\u002F*,github.com\u002Fdreplyai\u002F* \\\n    GOTOOLCHAIN=local CGO_ENABLED=0 GOOS=linux\n\nCOPY go.mod go.sum .\u002F\nRUN --mount=type=ssh \\\n    mkdir -p -m 0700 ~\u002F.ssh && \\\n    ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~\u002F.ssh\u002Fknown_hosts 2>\u002Fdev\u002Fnull && \\\n    git config --global url.\"git@github.com:redelay\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fredelay\u002F\" && \\\n    git config --global url.\"git@github.com:flowdsl\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fflowdsl\u002F\" && \\\n    git config --global url.\"git@github.com:dreplyai\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fdreplyai\u002F\" && \\\n    for i in 1 2 3; do go mod download && exit 0; sleep $((i * 15)); done; exit 1\n\nCOPY . .\nRUN GOWORK=off go build -trimpath -ldflags=\"-s -w\" -o \u002Fout\u002Fapi .\u002Fcmd\u002Fapi\n# … one `go build` per binary, then a slim runtime stage that copies \u002Fout\u002F*\n","dockerfile",[982,1180,1181,1186,1191,1197,1202,1207,1211,1216,1221,1226,1231,1236,1241,1246,1251,1255,1260,1265],{"__ignoreMap":1080},[1084,1182,1183],{"class":1086,"line":10},[1084,1184,1185],{},"FROM golang:1.25 AS build\n",[1084,1187,1188],{"class":1086,"line":16},[1084,1189,1190],{},"WORKDIR \u002Fsrc\n",[1084,1192,1193],{"class":1086,"line":22},[1084,1194,1196],{"emptyLinePlaceholder":1195},true,"\n",[1084,1198,1199],{"class":1086,"line":51},[1084,1200,1201],{},"ENV GOPRIVATE=github.com\u002Fredelay\u002F*,github.com\u002Fflowdsl\u002F*,github.com\u002FFlowDSL\u002F*,github.com\u002Fdreplyai\u002F* \\\n",[1084,1203,1204],{"class":1086,"line":57},[1084,1205,1206],{},"    GOTOOLCHAIN=local CGO_ENABLED=0 GOOS=linux\n",[1084,1208,1209],{"class":1086,"line":102},[1084,1210,1196],{"emptyLinePlaceholder":1195},[1084,1212,1213],{"class":1086,"line":108},[1084,1214,1215],{},"COPY go.mod go.sum .\u002F\n",[1084,1217,1218],{"class":1086,"line":114},[1084,1219,1220],{},"RUN --mount=type=ssh \\\n",[1084,1222,1223],{"class":1086,"line":120},[1084,1224,1225],{},"    mkdir -p -m 0700 ~\u002F.ssh && \\\n",[1084,1227,1228],{"class":1086,"line":181},[1084,1229,1230],{},"    ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~\u002F.ssh\u002Fknown_hosts 2>\u002Fdev\u002Fnull && \\\n",[1084,1232,1233],{"class":1086,"line":186},[1084,1234,1235],{},"    git config --global url.\"git@github.com:redelay\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fredelay\u002F\" && \\\n",[1084,1237,1238],{"class":1086,"line":191},[1084,1239,1240],{},"    git config --global url.\"git@github.com:flowdsl\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fflowdsl\u002F\" && \\\n",[1084,1242,1243],{"class":1086,"line":197},[1084,1244,1245],{},"    git config --global url.\"git@github.com:dreplyai\u002F\".insteadOf \"https:\u002F\u002Fgithub.com\u002Fdreplyai\u002F\" && \\\n",[1084,1247,1248],{"class":1086,"line":203},[1084,1249,1250],{},"    for i in 1 2 3; do go mod download && exit 0; sleep $((i * 15)); done; exit 1\n",[1084,1252,1253],{"class":1086,"line":214},[1084,1254,1196],{"emptyLinePlaceholder":1195},[1084,1256,1257],{"class":1086,"line":223},[1084,1258,1259],{},"COPY . .\n",[1084,1261,1262],{"class":1086,"line":229},[1084,1263,1264],{},"RUN GOWORK=off go build -trimpath -ldflags=\"-s -w\" -o \u002Fout\u002Fapi .\u002Fcmd\u002Fapi\n",[1084,1266,1267],{"class":1086,"line":234},[1084,1268,1269],{},"# … one `go build` per binary, then a slim runtime stage that copies \u002Fout\u002F*\n",[978,1271,1272],{},"Key points:",[1274,1275,1276,1293,1312,1329,1347,1356],"ul",{},[1277,1278,1279,1284,1285,1288,1289,1292],"li",{},[1048,1280,1281],{},[982,1282,1283],{},"--mount=type=ssh"," forwards the deploy key for that single ",[982,1286,1287],{},"RUN",", so the\nkey never lands in an image layer. A key added with ",[982,1290,1291],{},"COPY"," stays\nrecoverable from the layer even in a stage you throw away.",[1277,1294,1295,1302,1303,1306,1307,1311],{},[1048,1296,1297,1298,1301],{},"Use one ",[982,1299,1300],{},"insteadOf"," rule per private org."," A single rule for all of\n",[982,1304,1305],{},"https:\u002F\u002Fgithub.com\u002F"," would also send ",[1308,1309,1310],"em",{},"public"," dependencies over SSH.",[1277,1313,1314,1317,1318,1321,1322,1325,1326,1328],{},[1048,1315,1316],{},"Write the module path's case, not the repo's."," The module path\n",[982,1319,1320],{},"github.com\u002Fdreplyai\u002F…"," is lowercase even though the repo is\n",[982,1323,1324],{},"DreplyAI\u002F…",". ",[982,1327,1300],{}," matches the URL string exactly, so a rule written\nwith the repo's casing never fires.",[1277,1330,1331,1342,1343,1346],{},[1048,1332,1333,1334,1337,1338,1341],{},"Pin ",[982,1335,1336],{},"known_hosts"," with ",[982,1339,1340],{},"ssh-keyscan","."," Don't use\n",[982,1344,1345],{},"StrictHostKeyChecking=no",": with checking off, the build would hand its key\nto whatever answered on port 22.",[1277,1348,1349,1355],{},[1048,1350,1351,1352,1341],{},"Retry ",[982,1353,1354],{},"go mod download"," It makes hundreds of fetches, and one\nhiccup shouldn't fail an otherwise good build.",[1277,1357,1358,1363,1364,1367,1368,1371,1372,1341],{},[1048,1359,1360],{},[982,1361,1362],{},".dockerignore"," must exclude ",[982,1365,1366],{},".env*",", ",[982,1369,1370],{},"go.work"," and ",[982,1373,1374],{},"go.work.sum",[978,1376,1377],{},"Build it locally with a key file, the same way CI does:",[1075,1379,1381],{"className":1077,"code":1380,"language":1079,"meta":1080,"style":1080},"docker buildx build --ssh default=$HOME\u002F.ssh\u002Fid_ed25519 -t myapp-api .\n",[982,1382,1383],{"__ignoreMap":1080},[1084,1384,1385,1388,1391,1393,1396,1399,1403,1406,1409,1412],{"class":1086,"line":10},[1084,1386,1387],{"class":1095},"docker",[1084,1389,1390],{"class":1099}," buildx",[1084,1392,1153],{"class":1099},[1084,1394,1395],{"class":1099}," --ssh",[1084,1397,1398],{"class":1099}," default=",[1084,1400,1402],{"class":1401},"sTEyZ","$HOME",[1084,1404,1405],{"class":1099},"\u002F.ssh\u002Fid_ed25519",[1084,1407,1408],{"class":1099}," -t",[1084,1410,1411],{"class":1099}," myapp-api",[1084,1413,1414],{"class":1099}," .\n",[1067,1416,1418],{"id":1417},"the-swarm-stack","The swarm stack",[978,1420,1421],{},"Three settings decide whether the service recovers on its own:",[1075,1423,1427],{"className":1424,"code":1425,"language":1426,"meta":1080,"style":1080},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","x-deploy-policy: &deploy-policy\n  restart_policy:\n    condition: any        # not on-failure, and no max_attempts\n    delay: 5s\n  update_config:\n    parallelism: 1\n    order: start-first\n    failure_action: rollback\n    monitor: 120s         # how long a new task must stay healthy\n  rollback_config:\n    order: start-first\n    failure_action: pause\n","yaml",[982,1428,1429,1445,1453,1466,1476,1483,1494,1504,1514,1527,1534,1542],{"__ignoreMap":1080},[1084,1430,1431,1435,1438,1442],{"class":1086,"line":10},[1084,1432,1434],{"class":1433},"swJcz","x-deploy-policy",[1084,1436,1437],{"class":1106},":",[1084,1439,1441],{"class":1440},"s7zQu"," &",[1084,1443,1444],{"class":1095},"deploy-policy\n",[1084,1446,1447,1450],{"class":1086,"line":16},[1084,1448,1449],{"class":1433},"  restart_policy",[1084,1451,1452],{"class":1106},":\n",[1084,1454,1455,1458,1460,1463],{"class":1086,"line":22},[1084,1456,1457],{"class":1433},"    condition",[1084,1459,1437],{"class":1106},[1084,1461,1462],{"class":1099}," any",[1084,1464,1465],{"class":1089},"        # not on-failure, and no max_attempts\n",[1084,1467,1468,1471,1473],{"class":1086,"line":51},[1084,1469,1470],{"class":1433},"    delay",[1084,1472,1437],{"class":1106},[1084,1474,1475],{"class":1099}," 5s\n",[1084,1477,1478,1481],{"class":1086,"line":57},[1084,1479,1480],{"class":1433},"  update_config",[1084,1482,1452],{"class":1106},[1084,1484,1485,1488,1490],{"class":1086,"line":102},[1084,1486,1487],{"class":1433},"    parallelism",[1084,1489,1437],{"class":1106},[1084,1491,1493],{"class":1492},"sbssI"," 1\n",[1084,1495,1496,1499,1501],{"class":1086,"line":108},[1084,1497,1498],{"class":1433},"    order",[1084,1500,1437],{"class":1106},[1084,1502,1503],{"class":1099}," start-first\n",[1084,1505,1506,1509,1511],{"class":1086,"line":114},[1084,1507,1508],{"class":1433},"    failure_action",[1084,1510,1437],{"class":1106},[1084,1512,1513],{"class":1099}," rollback\n",[1084,1515,1516,1519,1521,1524],{"class":1086,"line":120},[1084,1517,1518],{"class":1433},"    monitor",[1084,1520,1437],{"class":1106},[1084,1522,1523],{"class":1099}," 120s",[1084,1525,1526],{"class":1089},"         # how long a new task must stay healthy\n",[1084,1528,1529,1532],{"class":1086,"line":181},[1084,1530,1531],{"class":1433},"  rollback_config",[1084,1533,1452],{"class":1106},[1084,1535,1536,1538,1540],{"class":1086,"line":186},[1084,1537,1498],{"class":1433},[1084,1539,1437],{"class":1106},[1084,1541,1503],{"class":1099},[1084,1543,1544,1546,1548],{"class":1086,"line":191},[1084,1545,1508],{"class":1433},[1084,1547,1437],{"class":1106},[1084,1549,1550],{"class":1099}," pause\n",[1552,1553,1556,1565,1566,1569],"callout",{"color":1554,"icon":1555},"warning","i-lucide-triangle-alert",[1048,1557,1558,1559,1337,1562,1341],{},"Don't use ",[982,1560,1561],{},"on-failure",[982,1563,1564],{},"max_attempts"," If a node reboots and\nreaches the registry over Tailscale, image pulls fail until Tailscale is up.\nA capped policy uses up its attempts in that window and leaves the service\nat ",[1048,1567,1568],{},"0 replicas with no retry",". Swarm won't reschedule it. redelay.com and\nflowdsl.com were down for about 45 hours this way in September 2026.",[1274,1571,1572,1584,1605],{},[1277,1573,1574,1579,1580,1583],{},[1048,1575,1576],{},[982,1577,1578],{},"monitor"," is what makes ",[982,1581,1582],{},"failure_action: rollback"," work. Without it, a\ntask that crashes after its first healthcheck still counts as a successful\nupdate.",[1277,1585,1586,1589,1590,1593,1594,1597,1598,1601,1602,1341],{},[1048,1587,1588],{},"Give every service a real healthcheck."," Distroless images have no\n",[982,1591,1592],{},"wget"," or ",[982,1595,1596],{},"curl",", so ship a small static ",[982,1599,1600],{},"\u002Fhealthcheck"," binary that\nrequests ",[982,1603,1604],{},"$HEALTH_URL",[1277,1606,1607,1610,1611,1613,1614,1617],{},[1048,1608,1609],{},"Keep the stack name stable."," ",[982,1612,1042],{}," under a new name starts\na ",[1308,1615,1616],{},"second"," stack, and both then claim the same Traefik hosts.",[1067,1619,1621],{"id":1620},"the-workflow","The workflow",[978,1623,1624],{},"The workflow runs on a self-hosted runner on the swarm manager:",[1626,1627,1628,1646,1660,1672,1681,1698],"ol",{},[1277,1629,1630,1633,1634,1636,1637,1640,1641,1643,1644,1341],{},[1048,1631,1632],{},"Guard."," Fail if the checkout contains a ",[982,1635,1370],{},", a ",[982,1638,1639],{},".env",", or any\n",[982,1642,1058],{}," in ",[982,1645,1054],{},[1277,1647,1648,1651,1652,1655,1656,1659],{},[1048,1649,1650],{},"Find the deploy key."," Probe the candidate keys with ",[982,1653,1654],{},"git ls-remote","\nagainst one repo per private org, and use the first key that can read all\nof them. A repository or org variable (",[982,1657,1658],{},"GO_MODULES_SSH_KEY",") can override\nthe choice.",[1277,1661,1662,1337,1665,1668,1669,1341],{},[1048,1663,1664],{},"Build and push",[982,1666,1667],{},"docker\u002Fsetup-buildx-action"," using\n",[982,1670,1671],{},"driver-opts: network=host",[1277,1673,1674,1677,1678,1680],{},[1048,1675,1676],{},"Deploy."," Run ",[982,1679,1042],{}," with secrets sourced from an env\nfile on the manager (never from the repo).",[1277,1682,1683,1686,1687,1690,1691,1593,1694,1697],{},[1048,1684,1685],{},"Wait for the rollout."," Poll each service's ",[982,1688,1689],{},"UpdateStatus.State",". Fail\non ",[982,1692,1693],{},"rollback_*",[982,1695,1696],{},"paused",", and print the task errors and recent logs.",[1277,1699,1700,1703],{},[1048,1701,1702],{},"Run a health check"," against the public URL, then clean up the registry\n(keep the last 5 tags).",[1552,1705,1706,1712,1713,1716,1717,1720,1721,1724],{"color":1554,"icon":1555},[1048,1707,1708,1711],{},[982,1709,1710],{},"network=host"," is required when the registry is on a Tailscale address.","\nWith the default ",[982,1714,1715],{},"docker-container"," driver, BuildKit runs on the Docker\nbridge, and the bridge can't route to ",[982,1718,1719],{},"100.x"," addresses. The build succeeds\nand then the push fails after minutes of retries with\n",[982,1722,1723],{},"dial tcp 100.x.x.x:5000: i\u002Fo timeout",", which looks like a registry outage.",[978,1726,1727],{},"Two GitHub quirks:",[1274,1729,1730,1746],{},[1277,1731,1732,1742,1743,1341],{},[1048,1733,1734,1735,1738,1739,1341],{},"Pass ",[982,1736,1737],{},"--ssh default=\u003Ckey path>",", not plain ",[982,1740,1741],{},"default"," A runner installed\nas a service has no ",[982,1744,1745],{},"$SSH_AUTH_SOCK",[1277,1747,1748,1751,1752,1754,1755,1758,1759,1341],{},[1048,1749,1750],{},"The workflow file must exist on the default branch."," Otherwise GitHub\nnever registers it: pushes to ",[982,1753,1038],{}," start nothing and\n",[982,1756,1757],{},"workflow_dispatch"," returns 404. Commit it to the default branch as well,\neven though it only triggers on ",[982,1760,1038],{},[978,1762,1763],{},"Deploying is then:",[1075,1765,1767],{"className":1077,"code":1766,"language":1079,"meta":1080,"style":1080},"git push origin main:production        # or your integration branch\n",[982,1768,1769],{"__ignoreMap":1080},[1084,1770,1771,1773,1775,1777,1780],{"class":1086,"line":10},[1084,1772,1096],{"class":1095},[1084,1774,1113],{"class":1099},[1084,1776,1116],{"class":1099},[1084,1778,1779],{"class":1099}," main:production",[1084,1781,1782],{"class":1089},"        # or your integration branch\n",[1067,1784,1786],{"id":1785},"monitoring","Monitoring",[978,1788,1789,1790,1792],{},"Probe the ",[1048,1791,1310],{}," URL with the Prometheus blackbox exporter. That covers\nevery failure a user would see: 0 replicas, a missing Traefik router, TLS,\nDNS, or app 5xx errors.",[1075,1794,1796],{"className":1424,"code":1795,"language":1426,"meta":1080,"style":1080},"- job_name: public-sites\n  metrics_path: \u002Fprobe\n  params: {module: [http_2xx]}\n  static_configs:\n    - targets: ['https:\u002F\u002Fapi.example.com\u002Fapi\u002Fv1\u002Fhealth']\n      labels: {project: myapp, service: api}\n  relabel_configs:\n    - {source_labels: [__address__], target_label: __param_target}\n    - {source_labels: [__param_target], target_label: instance}\n    - {target_label: __address__, replacement: blackbox-exporter:9115}\n",[982,1797,1798,1811,1821,1845,1852,1875,1906,1913,1942,1968],{"__ignoreMap":1080},[1084,1799,1800,1803,1806,1808],{"class":1086,"line":10},[1084,1801,1802],{"class":1106},"-",[1084,1804,1805],{"class":1433}," job_name",[1084,1807,1437],{"class":1106},[1084,1809,1810],{"class":1099}," public-sites\n",[1084,1812,1813,1816,1818],{"class":1086,"line":16},[1084,1814,1815],{"class":1433},"  metrics_path",[1084,1817,1437],{"class":1106},[1084,1819,1820],{"class":1099}," \u002Fprobe\n",[1084,1822,1823,1826,1828,1831,1834,1836,1839,1842],{"class":1086,"line":22},[1084,1824,1825],{"class":1433},"  params",[1084,1827,1437],{"class":1106},[1084,1829,1830],{"class":1106}," {",[1084,1832,1833],{"class":1433},"module",[1084,1835,1437],{"class":1106},[1084,1837,1838],{"class":1106}," [",[1084,1840,1841],{"class":1099},"http_2xx",[1084,1843,1844],{"class":1106},"]}\n",[1084,1846,1847,1850],{"class":1086,"line":51},[1084,1848,1849],{"class":1433},"  static_configs",[1084,1851,1452],{"class":1106},[1084,1853,1854,1857,1860,1862,1864,1867,1870,1872],{"class":1086,"line":57},[1084,1855,1856],{"class":1106},"    -",[1084,1858,1859],{"class":1433}," targets",[1084,1861,1437],{"class":1106},[1084,1863,1838],{"class":1106},[1084,1865,1866],{"class":1106},"'",[1084,1868,1869],{"class":1099},"https:\u002F\u002Fapi.example.com\u002Fapi\u002Fv1\u002Fhealth",[1084,1871,1866],{"class":1106},[1084,1873,1874],{"class":1106},"]\n",[1084,1876,1877,1880,1882,1884,1887,1889,1892,1895,1898,1900,1903],{"class":1086,"line":102},[1084,1878,1879],{"class":1433},"      labels",[1084,1881,1437],{"class":1106},[1084,1883,1830],{"class":1106},[1084,1885,1886],{"class":1433},"project",[1084,1888,1437],{"class":1106},[1084,1890,1891],{"class":1099}," myapp",[1084,1893,1894],{"class":1106},",",[1084,1896,1897],{"class":1433}," service",[1084,1899,1437],{"class":1106},[1084,1901,1902],{"class":1099}," api",[1084,1904,1905],{"class":1106},"}\n",[1084,1907,1908,1911],{"class":1086,"line":108},[1084,1909,1910],{"class":1433},"  relabel_configs",[1084,1912,1452],{"class":1106},[1084,1914,1915,1917,1919,1922,1924,1926,1929,1932,1935,1937,1940],{"class":1086,"line":114},[1084,1916,1856],{"class":1106},[1084,1918,1830],{"class":1106},[1084,1920,1921],{"class":1433},"source_labels",[1084,1923,1437],{"class":1106},[1084,1925,1838],{"class":1106},[1084,1927,1928],{"class":1099},"__address__",[1084,1930,1931],{"class":1106},"],",[1084,1933,1934],{"class":1433}," target_label",[1084,1936,1437],{"class":1106},[1084,1938,1939],{"class":1099}," __param_target",[1084,1941,1905],{"class":1106},[1084,1943,1944,1946,1948,1950,1952,1954,1957,1959,1961,1963,1966],{"class":1086,"line":120},[1084,1945,1856],{"class":1106},[1084,1947,1830],{"class":1106},[1084,1949,1921],{"class":1433},[1084,1951,1437],{"class":1106},[1084,1953,1838],{"class":1106},[1084,1955,1956],{"class":1099},"__param_target",[1084,1958,1931],{"class":1106},[1084,1960,1934],{"class":1433},[1084,1962,1437],{"class":1106},[1084,1964,1965],{"class":1099}," instance",[1084,1967,1905],{"class":1106},[1084,1969,1970,1972,1974,1977,1979,1982,1984,1987,1989,1992],{"class":1086,"line":181},[1084,1971,1856],{"class":1106},[1084,1973,1830],{"class":1106},[1084,1975,1976],{"class":1433},"target_label",[1084,1978,1437],{"class":1106},[1084,1980,1981],{"class":1099}," __address__",[1084,1983,1894],{"class":1106},[1084,1985,1986],{"class":1433}," replacement",[1084,1988,1437],{"class":1106},[1084,1990,1991],{"class":1099}," blackbox-exporter:9115",[1084,1993,1905],{"class":1106},[1075,1995,1997],{"className":1424,"code":1996,"language":1426,"meta":1080,"style":1080},"- alert: public_site_down\n  expr: probe_success{job=\"public-sites\"} == 0\n  for: 3m\n  labels: {severity: critical}\n",[982,1998,1999,2011,2021,2031],{"__ignoreMap":1080},[1084,2000,2001,2003,2006,2008],{"class":1086,"line":10},[1084,2002,1802],{"class":1106},[1084,2004,2005],{"class":1433}," alert",[1084,2007,1437],{"class":1106},[1084,2009,2010],{"class":1099}," public_site_down\n",[1084,2012,2013,2016,2018],{"class":1086,"line":16},[1084,2014,2015],{"class":1433},"  expr",[1084,2017,1437],{"class":1106},[1084,2019,2020],{"class":1099}," probe_success{job=\"public-sites\"} == 0\n",[1084,2022,2023,2026,2028],{"class":1086,"line":22},[1084,2024,2025],{"class":1433},"  for",[1084,2027,1437],{"class":1106},[1084,2029,2030],{"class":1099}," 3m\n",[1084,2032,2033,2036,2038,2040,2043,2045,2048],{"class":1086,"line":51},[1084,2034,2035],{"class":1433},"  labels",[1084,2037,1437],{"class":1106},[1084,2039,1830],{"class":1106},[1084,2041,2042],{"class":1433},"severity",[1084,2044,1437],{"class":1106},[1084,2046,2047],{"class":1099}," critical",[1084,2049,1905],{"class":1106},[2051,2052,2053],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":1080,"searchDepth":16,"depth":16,"links":2055},[2056,2057,2058,2059,2060],{"id":1069,"depth":16,"text":1070},{"id":1172,"depth":16,"text":1173},{"id":1417,"depth":16,"text":1418},{"id":1620,"depth":16,"text":1621},{"id":1785,"depth":16,"text":1786},"Ship a Redelay Go backend to Docker Swarm — a Mode B image built with SSH-forwarded private modules, a swarm stack that survives node reboots, and a push-to-deploy GitHub Actions workflow that fails on an automatic rollback.","md",null,{},{"icon":17},{"title":78,"description":2061},"nxeFHqCeYUew9xaK6SvBhFkQyUKrBgP6oyLhAn_f3hc",[2069,2071],{"title":74,"path":75,"stem":76,"description":2070,"children":-1},"One Playwright harness drives the real Redelay \u002F AsyncShop stack for two jobs — browser E2E tests and branded demo videos for the docs and website. How it works, how to run it in Docker, and how to add a test or a video for FlowDSL, Redelay, or AsyncShop\u002FAsyncCart.",{"title":82,"path":83,"stem":84,"description":2072,"order":16,"icon":46,"children":-1},"Step-by-step guide to creating a new module for the redelay go-framework.",1790332227933]