# Renest on vast.ai.

> To restore a nest on vast.ai, start an instance from the Renest base image with its on-start script set (vast skips the image's own start-up in SSH mode, so without that script the instance can't be reached), upgrade the renest tool, and paste the restore command from your drive into /workspace. Filter offers by disk size and download speed and let the pre-flight check judge the GPU. If the instance turns out broken, destroy it, rent another and paste the same command.

Canonical page: https://renest.ai/docs-guide-vast.html

<h2 id="size">1 · Filter offers by disk, download speed and GPU, then let the pre-flight check decide</h2>

<p><strong>Disk space.</strong> On vast, you choose the disk size when you create the
instance, so get it right up front. Start from the nest's size, shown on its page in your
drive and in the ComfyUI panel's <em>Estimated size</em>. Add room for the Python environment
the restore installs from the lock, which for image and training stacks is often several
gigabytes on its own. The pre-flight check does this sum for the disk that holds the folder you restore into, and
checks any other disk the nest writes to (a model cache in your home folder, for example)
separately. If there isn't room, it stops with <code>Only … GiB free, and this nest needs
… GiB</code> before it starts downloading.</p>

<p><strong>The disk that needs the room is the one holding your <code>--dir</code>.</strong>
<code>--dir</code> has no default, and the command your drive gives you says
<code>--dir ./run</code>, which is relative to the folder you paste it in. This guide
pastes the command from <code>/workspace</code>, so the restore lands in
<code>/workspace/run</code>, on the instance's disk: size that disk for the nest.</p>

<p><strong>Download speed.</strong> A restore downloads the whole nest and then its
dependencies, so the offer's download speed matters more than it does for most rentals. The
pre-flight check measures the link against the size of what it's about to fetch. It warns on
a slow link and refuses one too slow to finish. Picking an offer with a high download speed
avoids that refusal. Machines in the same region as your bucket usually do better; see the
<a href="docs-practical-guide.html">field notes on storage, GPUs and prices</a>.</p>

<p><strong>GPU and driver.</strong> The card doesn't have to match the one the nest was packed
on. Before downloading, the pre-flight check compares the GPU architecture with the compiled
code in the nest, the host driver with the CUDA line in the dependency lock, and the video
memory the working run was seen using. It also checks whether the GPU can actually be used.
Filtering by reliability narrows the list; the check has the final say.</p>

<p>You can ask before you rent. On any computer with the tool installed, this checks whether
everything the nest does <em>not</em> carry can still be fetched, and needs no GPU:</p>

<pre>$ renest restore --grant grant.json --dir ./run --check-only</pre>

<h2 id="start">2 · Start from the Renest base image with the on-start script set, or from a template you already use</h2>

<h3>The Renest base image is a clean starting point with the tool preinstalled</h3>

<p>The base image is a minimal Ubuntu 22.04 (linux/amd64) image for restoring nests. It
contains the <code>renest</code> tool, <code>uv</code>, <code>s5cmd</code>, <code>curl</code>,
<code>jq</code>, <code>tar</code>, <code>sha256sum</code>, <code>sshd</code>, and the system
libraries that image and fine-tuning workflows commonly load at runtime. By design it has
<strong>no torch, no ComfyUI, no models, no CUDA toolkit and no Python on PATH</strong>. Your
nest brings its own Python version and packages, and the restore puts them back.</p>

<p><strong>Template link.</strong> Open the Renest template on vast.ai: https://cloud.vast.ai/?ref_id=627393&creator_id=627393&name=Renest%20nest-base%20-%20clean%20base%20for%20restoring%20nests This is the platform's referral link. The template has the
image, launch mode and on-start script below already set. The hosted Renest service is run by
the same people who make this image.</p>

<p>To set it up by hand, create a template with:</p>

<ul>
  <li><strong>Image path / tag:</strong>
  <pre>ghcr.io/renest-ai/nest-base:20260913</pre>
  vast needs the registry host (<code>ghcr.io</code>) for images outside Docker Hub. The image
  is public, so leave the registry login empty. Date tags are never overwritten: this one always
  points to digest
  <code>sha256:e31d287a7244cd04f527b03693a7b623c514ec828ae8a5a98072b20264f928d8</code>.</li>
  <li><strong>Launch mode:</strong> SSH. <strong>Docker options:</strong> <code>-p 22:22</code>.
  Add <code>-p 8188:8188</code> as well if you want to reach ComfyUI directly after the restore,
  instead of through an SSH tunnel.</li>
  <li><strong>On-start script (required; don't leave it empty):</strong>
  <pre>mkdir -p /workspace &amp;&amp; bash /opt/renest/onstart.sh</pre></li>
</ul>

<h3>vast won't boot this image into a reachable state without the on-start script</h3>

<p>In SSH and Jupyter launch modes, vast doesn't run the image's own start-up script (its
entrypoint). The base image deliberately ships without SSH host keys, so that a public image
doesn't give every instance the same keys. The on-start script generates the keys at first
boot and starts <code>sshd</code>. It also creates <code>/workspace</code> and prints the
host's driver version. Without the script, the instance shows as running but nothing listens
on port 22, and you can't connect.</p>

<p>The same applies to any image you bring yourself. If an image relies on its entrypoint to
start services, put the equivalent commands in the on-start script.</p>

<p>Three more things that are specific to vast:</p>

<ul>
  <li><strong>The first launch can be slow.</strong> The host has to download the image before
  the instance can be reached, and on a slow link that can take a long time. Give it time before
  deciding something is wrong; how long it takes says little about the image itself.</li>
  <li><strong>vast adds its own <code>/usr/bin/python3</code></strong>, and it is incomplete
  (no <code>venv</code>, no <code>ensurepip</code>). It doesn't come from the base image.
  Don't build a virtual environment on it. <code>uv</code> installs its own interpreter, and
  that is what the restore does anyway.</li>
  <li><strong>Environment variables from the image or template don't reach your SSH
  session.</strong> Don't put your access key in the template's environment variables: it
  won't be visible where you run <code>renest</code>, and it would sit in the template. Use the
  config file in step 4.</li>
</ul>

<p>Two limits of the base image to know before you rent:</p>

<ul>
  <li><strong>There is no C compiler.</strong> A workflow that compiles GPU kernels while it
  runs (some triton paths) won't run on this image. Runtime-level base images generally don't
  include one either.</li>
  <li><strong>It has no single licence.</strong> The image mixes Ubuntu packages (many
  GPL/LGPL), permissively licensed binaries, and the source-available <code>renest</code>
  tool, so its licence metadata says NOASSERTION. Notices, the written offer for source code
  and licence texts are in <code>/usr/share/doc/renest-floor/</code>. See the
  <a href="docs-source-offer.html">source code offer</a>.</li>
</ul>

<h3>Any other template works too</h3>

<p>Renest doesn't need our image. A vast PyTorch or CUDA template, or any Linux image with the
NVIDIA driver visible, is fine: install the tool in step 3 and the pre-flight check tells you
whether the machine is suitable. If the template has no <code>/workspace</code>, create it
(<code>mkdir -p /workspace</code>) or restore somewhere else with enough room.</p>

<h2 id="install">3 · Install the tool with uv, or upgrade it on the base image</h2>

<pre># no uv yet?
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ source &#126;/.bashrc
# then install renest (or upgrade an older copy)
$ uv tool install --upgrade renest
$ export PATH="$HOME/.local/bin:$PATH"</pre>

<p>Prefer <code>uv</code> over <code>pip</code> on vast. The <code>python3</code> vast adds
can't create environments, while <code>uv</code> brings its own. The <code>export</code> line
matters on a fresh instance; without it, <code>renest</code> answers <code>command not
found</code>. <code>--upgrade</code> moves an older install to the latest version and does
nothing on a clean machine.</p>

<p>On the base image, <code>renest</code> is already on PATH, but <strong>the copy baked into
the image (tag <code>20260913</code>) is older than the latest release</strong>. It has no
<code>renest start</code> and doesn't print the <em>What's next</em> lines described in step 7.
Upgrade it the moment you're connected. If you skip this, the <code>renest start</code> command
in step 7 doesn't exist:</p>

<pre>$ uv tool install --upgrade renest
$ renest --version</pre>

<h2 id="key">4 · An access key is needed to pack to your drive, not to restore</h2>

<p><strong>Restoring doesn't need a key.</strong> The restore code from your drive is itself
the credential. Packing with <code>--dest hosted</code> does need one, and so do
<code>renest list</code> and <code>renest export</code>. There is no <code>renest login</code>
command.</p>

<p>Create a key in the web console under <strong>Settings → Access</strong>: in the
<em>Access keys</em> section, choose <strong>New key</strong>. It is shown once. On the instance, write it into the tool's config file, which only you can
read:</p>

<pre>$ mkdir -p &#126;/.config/renest
$ ( umask 077; read -rsp "Access key: " k; echo
    printf '[auth]\ntoken = "%s"\n' "$k" &gt; &#126;/.config/renest/config.toml )</pre>

<p>Pasting at the prompt keeps the key out of your shell history, and <code>umask 077</code>
creates the file as 0600. If <code>config.toml</code> already has other settings, add the
<code>[auth]</code> section to it instead of overwriting it.</p>

<p>For a single session, you can use the <code>RENEST_TOKEN</code> environment variable instead,
set in the shell itself (<code>read -rsp "Access key: " RENEST_TOKEN; export
RENEST_TOKEN</code>), not in the template. If both are set, the environment variable wins.</p>

<p>Be clear about where the key now lives. A file on a rented instance stays on its disk after
you log out. Don't commit it or put it in a template, and <strong>revoke it in Settings → Access
when you're done with the instance</strong>. Your account key is the only credential this
path puts on the instance. Bucket keys never go there.</p>

<h2 id="pack">5 · Pack the run once it has worked</h2>

<p>Get the workflow rendering, or the training run finished, first. Renest captures only
setups that have already produced a result. Then:</p>

<pre>$ renest pack --dir /workspace --workflow workflow-api.json &#92;
    --out /workspace/nests --dest hosted</pre>

<ul>
  <li><code>--dir</code> (required): the folder that holds <code>ComfyUI/</code>.</li>
  <li><code>--out</code> (required for a real pack): where the nest is written on this
  machine. <code>--dry-run</code> prints the plan without it.</li>
  <li><code>--dest hosted</code>: also upload it to your drive. Without this flag, the nest
  exists only in <code>--out</code>. The access key is checked <em>before</em> packing
  starts.</li>
  <li><code>--workflow</code>: must be exported in API format (<em>Export (API)</em> in
  ComfyUI). For fine-tuning, use <code>--framework kohya|llamafactory --run-record
  run.json</code> instead.</li>
</ul>

<p>The <a href="docs-plugin-nest-this-run.html">ComfyUI panel</a> can pack to the instance's
disk too, but it doesn't upload, and on a rented machine it needs an SSH tunnel.</p>

<h2 id="restore">6 · Restore into /workspace with the command your drive gives you</h2>

<p>In your drive, open the nest and choose <strong>Restore</strong>. Pick how long the restore
code should last: <em>1 day</em>, <em>3 days</em> or <em>7 days</em>. Copy the pod
command, then paste it on the instance from <code>/workspace</code>, so that
<code>./run</code> lands where step 1 sized the disk:</p>

<pre>$ cd /workspace
$ cat &gt; grant.json &lt;&lt;'RENEST_GRANT'
&#123; …your restore code… &#125;
RENEST_GRANT
$ renest restore --grant grant.json --dir ./run</pre>

<p>Treat the code as a password. Anyone holding it can restore that version until it expires,
and you can revoke it from the drive at any time. It is <strong>not tied to a machine</strong>,
so if an instance turns out to be bad, the same code works on the next one.</p>

<p>The restore checks the machine first, downloads every file and checks it against its
recorded checksum, installs dependencies from the lock, then starts the app and runs the
packed workflow once. <strong>A restore has succeeded when that run produces output</strong>
(an image, or a non-empty training artifact), not merely when the command exits cleanly. If
the connection drops, run the same command again. Files already on disk that match their
checksums are kept.</p>

<h2 id="after">7 · After the restore, your image is in the output folder and ComfyUI starts with renest start</h2>

<p><strong>Where is my image, and how do I open ComfyUI?</strong> Those are the first two
questions after a restore. Short answers: the test image is in
<code>/workspace/run/ComfyUI/output</code>; start ComfyUI with
<code>renest start --dir /workspace/run</code>, then open it through an SSH tunnel from your
own computer. The full walk-through, for any machine, is
<a href="docs-after-restore.html">After the restore</a>.</p>

<p>The restore starts the app only for its own check, then stops it. Its closing lines are the
last thing it prints, below the JSON report: a <code>✅ Done</code> line followed by a
<strong>What's next:</strong> block. That block is built from this nest's own manifest, so its
commands and paths are the ones to use. For an image nest restored into
<code>/workspace/run</code> whose recorded start command listens on <code>127.0.0.1</code>, it
contains lines like these:</p>

<pre>[restore] What's next:
[restore]   · Start it yourself: cd /workspace/run/ComfyUI &amp;&amp; /workspace/run/.venv/bin/python main.py --listen 127.0.0.1.
[restore]   · That command listens on 127.0.0.1, which answers this machine only — right for the
            check that just ran, not for your browser. To reach it from outside, change that one
            value to 0.0.0.0 (or run `renest start --dir /workspace/run --listen 0.0.0.0`, which
            does it for you).
[restore]   · Started that way it listens on port 8188. On a rented GPU box, reaching it from your
            own browser also means exposing that port in your provider's panel — the check never
            did that for you.
[restore]   · Images render into /workspace/run/ComfyUI/output — that is where yours is.
[restore]   · The workflow that produced the test render: /workspace/run/.renest/staging/workflow.json.
            Drop it into the app to start from what worked.
[restore]   · Moving to another machine? The same restore command works there too — it reuses what is
            already fetched and carries on.
[restore]   · Or let the tool do it for you: renest start --dir /workspace/run</pre>

<p>If the recorded command names no address at all, the second and third lines are replaced
by one: <code>Started that way it listens on port 8188. On a rented GPU box, reaching it
from your own browser means it has to be listening on 0.0.0.0 and that port exposed in your
provider's panel — the check never did either for you.</code></p>

<p>In practice, for ComfyUI:</p>

<ul>
  <li><strong>Start it</strong> with <code>renest start --dir /workspace/run</code>. It runs
  exactly the command the block printed, from the same folder, with the restored Python
  environment. <code>--dry-run</code> prints the command and stops. To reach it without a
  tunnel, add <code>--listen 0.0.0.0</code>: it changes only the address that command already
  names. If the recorded command names no address, <code>--listen</code> refuses rather than
  invent a flag; then run the printed command yourself with <code>--listen 0.0.0.0</code>
  added:
  <pre>$ cd /workspace/run/ComfyUI
$ /workspace/run/.venv/bin/python main.py --listen 0.0.0.0 --port 8188</pre></li>
  <li><strong>Open it.</strong> The simplest way on vast is an SSH tunnel from your own
  computer, using the SSH address and port vast shows for the instance: <code>ssh -N -L
  8188:127.0.0.1:8188 root@&lt;instance-address&gt; -p &lt;ssh-port&gt;</code>, then browse to
  <code>http://127.0.0.1:8188</code>. If you added <code>-p 8188:8188</code> when you created
  the instance and started ComfyUI with <code>--listen 0.0.0.0</code>, vast maps the port to a
  random external port on the machine's public address, so connect to that port rather than to
  8188.</li>
  <li><strong>Find your images</strong> in the <code>output</code> folder the block names.</li>
  <li><strong>Drag the workflow file it names into ComfyUI</strong> to start from what
  worked.</li>
  <li><strong>For a fine-tuning nest,</strong> the block instead names the output file the nest
  was packed to produce, and the command to run the training again.</li>
</ul>

<p>If the block has no start command, that's because the nest doesn't record one. It
doesn't guess.</p>

<h2 id="broken">If the machine turns out broken, destroy it and paste the same command on another</h2>

<p>The restore code is not tied to a machine. If an instance misbehaves (the GPU disappears,
the app can't see CUDA, the download crawls), don't spend time repairing it: copy off anything
you want to keep, destroy it, start another instance from the same template, and paste the
same restore command from <code>/workspace</code>. Nothing is wrong with your nest, and the
code works until it expires or you revoke it. If it has expired, issue a new one from the
nest's <strong>Restore</strong> page.</p>

<h2 id="fail">When it stops, the message names the problem, and a replacement machine fixes most machine problems</h2>

<ul>
  <li><strong>You can't connect at all.</strong> Check that the on-start script is set and give
  the first launch time (see step 2). This happens before Renest is involved.</li>
  <li><strong>The pre-flight check refuses.</strong> You'll see a plain reason: not enough
  disk, a link too slow for the download, a driver too old for the lock's CUDA line, a GPU
  architecture the nest's compiled code doesn't support. Rent an offer that fits. On vast,
  disk size can't be changed afterwards, so a disk refusal means a new instance.
  <code>--force</code> goes ahead anyway, but only use it if you know better than the
  check.</li>
  <li><strong>A passed check doesn't guarantee the GPU is usable when the app starts.</strong>
  The check runs a full <code>nvidia-smi</code>. On a faulty host it warns with a line that
  begins <code>Full nvidia-smi failed here</code> and ends <code>replace the machine rather
  than re-downloading</code>. A host can also pass that check and still fail when the app
  starts, with <code>No CUDA GPUs are available</code>. Either way, nothing is wrong with your
  nest. Destroy that instance, start another, and paste the same restore command.</li>
  <li><strong>Anything else.</strong> If the tool prints an instruction, do that one thing and
  run the same command again. To turn a failed run into something you can read and paste into
  a ticket, run <code>renest support --dir ./run</code>. It never goes online and never
  uploads. Do this <em>before</em> you destroy the instance.</li>
</ul>

<h2 id="stop">Copy what you need, then destroy the instance</h2>

<p>An instance costs money for as long as it exists. Before you end it:</p>

<ol>
  <li>Copy off your outputs, and anything from <code>renest support</code> you want to keep.</li>
  <li>If you put an access key on the instance, revoke it in <strong>Settings →
  Access</strong>.</li>
  <li><strong>Stop</strong> still charges for the disk, and the GPU may be rented to someone
  else by the time you start it again. <strong>Destroy</strong> deletes the instance and
  everything on it. Your nest is safe either way: it's on your drive, and a restore code
  brings it back on the next instance.</li>
</ol>
