[{"data":1,"prerenderedAt":690},["ShallowReactive",2],{"navigation_docs":3,"-concepts-deploy":144,"-concepts-deploy-surround":685},[4,35,84,109,124,134,139],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Get Started","\u002Fget-started","1.get-started",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fget-started\u002Fintroduction","1.get-started\u002F1.introduction","i-lucide-house",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fget-started\u002Finstallation","1.get-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick start","\u002Fget-started\u002Fquickstart","1.get-started\u002F3.quickstart","i-lucide-rocket",{"title":25,"path":26,"stem":27,"icon":28},"Project structure","\u002Fget-started\u002Fproject-structure","1.get-started\u002F4.project-structure","i-lucide-folder-tree",{"title":30,"path":31,"stem":32,"icon":33},"Dashboard","\u002Fget-started\u002Fdashboard","1.get-started\u002F5.dashboard","i-lucide-layout-dashboard",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Concepts","\u002Fconcepts","2.concepts",[40,45,50,55,60,65,69,74,79],{"title":41,"path":42,"stem":43,"icon":44},"Architecture","\u002Fconcepts\u002Farchitecture","2.concepts\u002F1.architecture","i-lucide-layers",{"title":46,"path":47,"stem":48,"icon":49},"Machines","\u002Fconcepts\u002Fmachines","2.concepts\u002F2.machines","i-lucide-server",{"title":51,"path":52,"stem":53,"icon":54},"Colony & users","\u002Fconcepts\u002Fcolony","2.concepts\u002F3.colony","i-lucide-users",{"title":56,"path":57,"stem":58,"icon":59},"Transport","\u002Fconcepts\u002Ftransport","2.concepts\u002F4.transport","i-lucide-network",{"title":61,"path":62,"stem":63,"icon":64},"Configuration","\u002Fconcepts\u002Fconfiguration","2.concepts\u002F5.configuration","i-lucide-settings",{"title":66,"path":67,"stem":68,"icon":23},"Deploy","\u002Fconcepts\u002Fdeploy","2.concepts\u002F6.deploy",{"title":70,"path":71,"stem":72,"icon":73},"Groups","\u002Fconcepts\u002Fgroups","2.concepts\u002F7.groups","i-lucide-boxes",{"title":75,"path":76,"stem":77,"icon":78},"Templates","\u002Fconcepts\u002Ftemplates","2.concepts\u002F8.templates","i-lucide-package-plus",{"title":80,"path":81,"stem":82,"icon":83},"Existing projects","\u002Fconcepts\u002Fexisting-projects","2.concepts\u002F9.existing-projects","i-lucide-folder-open",{"title":85,"path":86,"stem":87,"children":88,"page":34},"Remote","\u002Fremote","3.remote",[89,94,99,104],{"title":90,"path":91,"stem":92,"icon":93},"Remote machines","\u002Fremote\u002Foverview","3.remote\u002F1.overview","i-lucide-cloud",{"title":95,"path":96,"stem":97,"icon":98},"Remote deploy","\u002Fremote\u002Fdeploy","3.remote\u002F2.deploy","i-lucide-send",{"title":100,"path":101,"stem":102,"icon":103},"CI","\u002Fremote\u002Fci","3.remote\u002F3.ci","i-lucide-workflow",{"title":105,"path":106,"stem":107,"icon":108},"Tunnels","\u002Fremote\u002Ftunnel","3.remote\u002F4.tunnel","i-lucide-cable",{"title":110,"path":111,"stem":112,"children":113,"page":34},"Security","\u002Fsecurity","4.security",[114,119],{"title":115,"path":116,"stem":117,"icon":118},"Security model","\u002Fsecurity\u002Fmodel","4.security\u002F1.model","i-lucide-shield",{"title":120,"path":121,"stem":122,"icon":123},"Known issues","\u002Fsecurity\u002Fknown-issues","4.security\u002F2.known-issues","i-lucide-triangle-alert",{"title":125,"path":126,"stem":127,"children":128,"page":34},"Reference","\u002Freference","5.reference",[129],{"title":130,"path":131,"stem":132,"icon":133},"CLI reference","\u002Freference\u002Fcli","5.reference\u002F1.cli","i-lucide-terminal",{"title":135,"path":136,"stem":137,"icon":138},"Changelog","\u002Fchangelog","changelog","i-lucide-history",{"title":140,"path":141,"stem":142,"icon":143},"Communities","\u002Fcommunities","communities","i-lucide-heart-handshake",{"id":145,"title":66,"body":146,"description":677,"extension":678,"links":679,"meta":680,"navigation":681,"path":67,"seo":682,"stem":68,"__hash__":684},"docs\u002F2.concepts\u002F6.deploy.md",{"type":147,"value":148,"toc":667},"minimark",[149,154,184,200,204,320,339,389,394,414,428,432,439,459,555,578,582,593,618,637,641,655,658,663],[150,151,153],"h2",{"id":152},"build","Build",[155,156,161],"pre",{"className":157,"code":158,"language":159,"meta":160,"style":160},"language-sh shiki shiki-themes material-theme-lighter github-light github-dark","ant haul                          # build for deployment \"local\"\nant haul dev                      # build for deployment \"dev\"\nant haul --release 20260101T120000Z\n","sh","",[162,163,164,172,178],"code",{"__ignoreMap":160},[165,166,169],"span",{"class":167,"line":168},"line",1,[165,170,171],{},"ant haul                          # build for deployment \"local\"\n",[165,173,175],{"class":167,"line":174},2,[165,176,177],{},"ant haul dev                      # build for deployment \"dev\"\n",[165,179,181],{"class":167,"line":180},3,[165,182,183],{},"ant haul --release 20260101T120000Z\n",[185,186,187,188,191,192,195,196,199],"p",{},"Compose projects are built with ",[162,189,190],{},"docker compose build","; everything else runs the\nselected builder. ",[162,193,194],{},"build: none"," has nothing to build and is rejected with a hint\nto use ",[162,197,198],{},"ant trail deploy",".",[150,201,203],{"id":202},"deploy-and-manage","Deploy and manage",[155,205,207],{"className":157,"code":206,"language":159,"meta":160,"style":160},"ant trail deploy                  # build + run (defaults to \"local\")\nant trail deploy dev\nant trail deploy local --no-caddy # skip local domain routing\nant trail deploy --image ghcr.io\u002Facme\u002Fapi:1.4.2 --machine prod --port 8080\n\nant trail status        [deployment] [--json]\nant trail logs          [deployment] [service] [-f] [--tail N]\nant trail restart       [deployment]\nant trail down          [deployment]\nant trail destroy       [deployment] --yes [--keep-images]\nant trail exec          [deployment] -- \u003Ccommand> [args...]\nant trail env           [deployment]     # resolved KEY=VALUE pairs\nant trail doctor        [deployment]     # docker, ports, ant.yaml\nant trail history                 # recorded deploys (--project, --machine, --limit, --json)\nant trail rollback                # redeploy the previous release (--to, --steps)\n\n# Machine resources (this host, or a nest with --machine):\nant nest containers     list | start NAME | stop NAME | restart NAME | rm NAME --yes\nant nest volume         list | rm NAME [--force] --yes\n",[162,208,209,214,219,224,230,237,243,249,255,261,267,273,279,285,291,297,302,308,314],{"__ignoreMap":160},[165,210,211],{"class":167,"line":168},[165,212,213],{},"ant trail deploy                  # build + run (defaults to \"local\")\n",[165,215,216],{"class":167,"line":174},[165,217,218],{},"ant trail deploy dev\n",[165,220,221],{"class":167,"line":180},[165,222,223],{},"ant trail deploy local --no-caddy # skip local domain routing\n",[165,225,227],{"class":167,"line":226},4,[165,228,229],{},"ant trail deploy --image ghcr.io\u002Facme\u002Fapi:1.4.2 --machine prod --port 8080\n",[165,231,233],{"class":167,"line":232},5,[165,234,236],{"emptyLinePlaceholder":235},true,"\n",[165,238,240],{"class":167,"line":239},6,[165,241,242],{},"ant trail status        [deployment] [--json]\n",[165,244,246],{"class":167,"line":245},7,[165,247,248],{},"ant trail logs          [deployment] [service] [-f] [--tail N]\n",[165,250,252],{"class":167,"line":251},8,[165,253,254],{},"ant trail restart       [deployment]\n",[165,256,258],{"class":167,"line":257},9,[165,259,260],{},"ant trail down          [deployment]\n",[165,262,264],{"class":167,"line":263},10,[165,265,266],{},"ant trail destroy       [deployment] --yes [--keep-images]\n",[165,268,270],{"class":167,"line":269},11,[165,271,272],{},"ant trail exec          [deployment] -- \u003Ccommand> [args...]\n",[165,274,276],{"class":167,"line":275},12,[165,277,278],{},"ant trail env           [deployment]     # resolved KEY=VALUE pairs\n",[165,280,282],{"class":167,"line":281},13,[165,283,284],{},"ant trail doctor        [deployment]     # docker, ports, ant.yaml\n",[165,286,288],{"class":167,"line":287},14,[165,289,290],{},"ant trail history                 # recorded deploys (--project, --machine, --limit, --json)\n",[165,292,294],{"class":167,"line":293},15,[165,295,296],{},"ant trail rollback                # redeploy the previous release (--to, --steps)\n",[165,298,300],{"class":167,"line":299},16,[165,301,236],{"emptyLinePlaceholder":235},[165,303,305],{"class":167,"line":304},17,[165,306,307],{},"# Machine resources (this host, or a nest with --machine):\n",[165,309,311],{"class":167,"line":310},18,[165,312,313],{},"ant nest containers     list | start NAME | stop NAME | restart NAME | rm NAME --yes\n",[165,315,317],{"class":167,"line":316},19,[165,318,319],{},"ant nest volume         list | rm NAME [--force] --yes\n",[185,321,322,323,326,327,330,331,334,335,338],{},"Lifecycle commands accept an optional deployment name and default to ",[162,324,325],{},"local",".\n",[162,328,329],{},"ant nest containers"," and ",[162,332,333],{},"ant nest volume"," are machine-scoped: they operate on\nthis host or, with ",[162,336,337],{},"--machine M",", on a remote nest.",[185,340,341,344,345,348,349,352,353,356,357,360,361,364,365,364,368,364,371,364,374,377,378,381,382,385,386,199],{},[162,342,343],{},"ant trail deploy --image REF"," runs a pre-built image on a machine (use\n",[162,346,347],{},"--from-tar"," to upload a ",[162,350,351],{},"docker save"," archive, ",[162,354,355],{},"--pull"," to fetch from a\nregistry, plus ",[162,358,359],{},"--app","\u002F",[162,362,363],{},"--name",", ",[162,366,367],{},"--env",[162,369,370],{},"--domain",[162,372,373],{},"--network",[162,375,376],{},"--restart",",\nand ",[162,379,380],{},"--publish-all","). ",[162,383,384],{},"ant trail rollback"," redeploys the previous release's image\nwithout rebuilding; it refuses compose projects, which may be redeployed with an\nexplicit ",[162,387,388],{},"--release",[390,391,393],"h3",{"id":392},"rolling-out","Rolling out",[185,395,396,397,400,401,405,406,409,410,413],{},"A local deploy can stage the new container before replacing the old one\n(",[162,398,399],{},"zero_downtime: true","). On a remote nest the worker always stages first: it\nstarts the new image on ephemeral ports with the deploy's ",[402,403,404],"strong",{},"read-only"," mounts\nand waits for the ",[162,407,408],{},"health_check",", then swaps. A deploy whose mounts are\n",[402,411,412],{},"writable"," (a live data volume, or a bind the app needs to boot) cannot be\nstaged safely and is replaced in place instead, with a post-start check that\nfails a container which exits immediately.",[185,415,416,419,420,423,424,427],{},[162,417,418],{},"ant trail destroy"," tears everything down. On this host: the container or stack,\nthe working directory under ",[162,421,422],{},"~\u002F.ant\u002Flocal",", and the images Ant built for the app\n(images built or pulled outside Ant are never removed; ",[162,425,426],{},"--keep-images"," keeps the\napp's images). On a machine: the container, compose project, or stack, plus its\nCaddy routes; the machine's images stay for the build cache.",[150,429,431],{"id":430},"reclaim-disk","Reclaim disk",[185,433,434,435,438],{},"Nothing is removed unless you ask. Categories are independent, and each has a\n",[162,436,437],{},"--skip-*"," counterpart:",[155,440,442],{"className":157,"code":441,"language":159,"meta":160,"style":160},"ant trail prune --all --skip-volumes   # everything except volumes\nant trail prune --images --dangling    # just those two\nant trail prune --images --dry-run     # show what would go\n",[162,443,444,449,454],{"__ignoreMap":160},[165,445,446],{"class":167,"line":168},[165,447,448],{},"ant trail prune --all --skip-volumes   # everything except volumes\n",[165,450,451],{"class":167,"line":174},[165,452,453],{},"ant trail prune --images --dangling    # just those two\n",[165,455,456],{"class":167,"line":180},[165,457,458],{},"ant trail prune --images --dry-run     # show what would go\n",[460,461,462,478],"table",{},[463,464,465],"thead",{},[466,467,468,472,475],"tr",{},[469,470,471],"th",{},"Category",[469,473,474],{},"Flag",[469,476,477],{},"Removes",[479,480,481,503,516,529,542],"tbody",{},[466,482,483,487,492],{},[484,485,486],"td",{},"Old app images",[484,488,489],{},[162,490,491],{},"--images",[484,493,494,495,498,499,502],{},"This app's tags beyond ",[162,496,497],{},"deploy.keep_images"," (or ",[162,500,501],{},"rollback.keep_releases","; default 10)",[466,504,505,508,513],{},[484,506,507],{},"Dangling images",[484,509,510],{},[162,511,512],{},"--dangling",[484,514,515],{},"Untagged intermediate layers",[466,517,518,521,526],{},[484,519,520],{},"Build cache",[484,522,523],{},[162,524,525],{},"--cache",[484,527,528],{},"The BuildKit cache",[466,530,531,534,539],{},[484,532,533],{},"Volumes",[484,535,536],{},[162,537,538],{},"--volumes",[484,540,541],{},"Unused volumes",[466,543,544,547,552],{},[484,545,546],{},"Stopped containers",[484,548,549],{},[162,550,551],{},"--stopped",[484,553,554],{},"Exited Ant-managed containers",[185,556,557,560,561,360,563,566,567,570,571,573,574,577],{},[162,558,559],{},"--keep-images N"," overrides the retention; ",[162,562,359],{},[162,564,565],{},"--deployment"," scope the\nimage category; ",[162,568,569],{},"--yes"," skips the confirmation. Every category has a ",[162,572,437],{},"\ncounterpart, and ",[162,575,576],{},"--dry-run"," prints what would be removed.",[150,579,581],{"id":580},"manage-one-volume","Manage one volume",[185,583,584,587,588,592],{},[162,585,586],{},"ant trail prune --volumes"," removes only ",[589,590,591],"em",{},"unused"," volumes. To see every volume\non a machine and remove a specific one:",[155,594,596],{"className":157,"code":595,"language":159,"meta":160,"style":160},"ant nest volume list               # name, driver, scope, in-use\nant nest volume list --json\nant nest volume rm api_data --yes           # refuse if a container uses it\nant nest volume rm api_data --yes --force   # remove despite a stopped container\n",[162,597,598,603,608,613],{"__ignoreMap":160},[165,599,600],{"class":167,"line":168},[165,601,602],{},"ant nest volume list               # name, driver, scope, in-use\n",[165,604,605],{"class":167,"line":174},[165,606,607],{},"ant nest volume list --json\n",[165,609,610],{"class":167,"line":180},[165,611,612],{},"ant nest volume rm api_data --yes           # refuse if a container uses it\n",[165,614,615],{"class":167,"line":226},[165,616,617],{},"ant nest volume rm api_data --yes --force   # remove despite a stopped container\n",[185,619,620,623,624,627,628,631,632,199],{},[162,621,622],{},"--force"," overrides a ",[402,625,626],{},"stopped"," container's reference; Docker still refuses to\nremove a volume a ",[402,629,630],{},"running"," container is using. The dashboard shows the same\nlist on a machine's page, with a remove button. See\n",[633,634,636],"a",{"href":635},"\u002Freference\u002Fcli#volume","Volume management",[150,638,640],{"id":639},"local-domains","Local domains",[185,642,643,644,647,648,651,652,199],{},"Domains are opt-in: add one with ",[162,645,646],{},"ant nest edit domain add"," (or the dashboard's\nDomains tab) and Caddy routes it to the running container. Opt out entirely with\n",[162,649,650],{},"--no-caddy",", or disable Caddy for the machine in ",[162,653,654],{},"config.json",[150,656,80],{"id":657},"existing-projects",[185,659,660,661,199],{},"Bringing a project, an image, or a machine that Ant did not create under\nmanagement (including the cutover recipe for a hand-managed compose stack) is\ncovered in ",[633,662,80],{"href":81},[664,665,666],"style",{},"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);}",{"title":160,"searchDepth":174,"depth":174,"links":668},[669,670,673,674,675,676],{"id":152,"depth":174,"text":153},{"id":202,"depth":174,"text":203,"children":671},[672],{"id":392,"depth":180,"text":393},{"id":430,"depth":174,"text":431},{"id":580,"depth":174,"text":581},{"id":639,"depth":174,"text":640},{"id":657,"depth":174,"text":80},"Build an image, run it locally, and reclaim disk.","md",null,{},{"icon":23},{"title":66,"description":683},"ant haul builds, ant trail deploys, and ant trail prune reclaims disk. Volumes can be managed individually.","cd_2DS-0rbGeqfsvu2c3vywZckfUEKsnXJ-P1R5pSAo",[686,688],{"title":61,"path":62,"stem":63,"description":687,"icon":64,"children":-1},"ant.yaml for a project, and ~\u002F.ant\u002Fconfig.json for the machine.",{"title":70,"path":71,"stem":72,"description":689,"icon":73,"children":-1},"Divide a codebase into shared networks, env, and secrets.",1791494556426]