<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bart Guijt</title>
    <description>The latest articles on Forem by Bart Guijt (@bguijt).</description>
    <link>https://forem.com/bguijt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1255341%2Ffc6df971-4e21-4b38-ab0d-e7483d1b6874.jpeg</url>
      <title>Forem: Bart Guijt</title>
      <link>https://forem.com/bguijt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bguijt"/>
    <language>en</language>
    <item>
      <title>Howto: WASM runtimes in Docker / Colima</title>
      <dc:creator>Bart Guijt</dc:creator>
      <pubDate>Fri, 12 Jan 2024 18:37:15 +0000</pubDate>
      <link>https://forem.com/bguijt/howto-wasm-runtimes-in-docker-colima-52c2</link>
      <guid>https://forem.com/bguijt/howto-wasm-runtimes-in-docker-colima-52c2</guid>
      <description>&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;I could not find any guide how to add WASM container capability to Docker running on &lt;a href="https://github.com/abiosoft/colima"&gt;Colima&lt;/a&gt;. This guide provides a few Colima templates for exactly this, which adds &lt;a href="https://wasmedge.org"&gt;WasmEdge&lt;/a&gt;, &lt;a href="https://wasmtime.dev"&gt;Wasmtime&lt;/a&gt; and &lt;a href="https://wasmer.io"&gt;Wasmer&lt;/a&gt; runtime types.&lt;/p&gt;

&lt;h1&gt;
  
  
  Context
&lt;/h1&gt;

&lt;p&gt;Instead of installing &lt;a href="https://www.docker.com/products/docker-desktop/"&gt;Docker Desktop&lt;/a&gt; and &lt;a href="https://docs.docker.com/desktop/wasm/"&gt;enabling the WASM features&lt;/a&gt; I decided to see how I could add WASM runtime capabilities to a Colima setup. Colima is a great alternative to Docker Desktop if the licensing terms prevent you from using it.&lt;/p&gt;

&lt;p&gt;Forgive me for not explaining everything from scratch, I just finished the last (and best) template and I needed to write it down so I could share it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Three alternative Colima templates
&lt;/h1&gt;

&lt;p&gt;I created these three Colima templates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;colima-crun-wasmedge&lt;/code&gt;: Use the 'crun' runtime to launch WASM containers in WasmEdge;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;colima-runwasi-git&lt;/code&gt;: Use the &lt;a href="https://github.com/containerd/runwasi"&gt;Runwasi&lt;/a&gt; WASM shims in containerd to launch WASM containers in WasmEdge, Wasmtime or Wasmer, where the Runwasi shims are compiled from git master;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;colima-runwasi&lt;/code&gt;: Same as &lt;code&gt;colima-runwasi-git&lt;/code&gt;, but uses the latest releases of the Runwasi shims instead of building them.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  &lt;code&gt;colima-crun-wasmedge&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;This was my first trial of getting WASM containers to work. To enable running WASM loads, &lt;a href="https://github.com/containers/crun"&gt;crun&lt;/a&gt; needs to be compiled with WasmEdge (or Wasmtime) support. I could only get WasmEdge working, but the basic idea is the same.&lt;/p&gt;

&lt;p&gt;Here is the template (edit the Colima template with &lt;code&gt;$ colima template&lt;/code&gt;). I added comments to the parts relevant for the WASM config, other comments are removed for brevity:&lt;/p&gt;

&lt;h2&gt;
  
  
  Template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="na"&gt;disk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="na"&gt;arch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;
&lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;colima&lt;/span&gt;
&lt;span class="na"&gt;autoActivate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;forwardAgent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="c1"&gt;# I only tested this with 'docker', not 'containerd':&lt;/span&gt;
&lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;

&lt;span class="na"&gt;kubernetes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1.24.3+k3s1&lt;/span&gt;
  &lt;span class="na"&gt;k3sArgs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;dns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;dnsHosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host.docker.internal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host.lima.internal&lt;/span&gt;

&lt;span class="c1"&gt;# Added:&lt;/span&gt;
&lt;span class="c1"&gt;# - containerd-snapshotter: true (meaning containerd will be used for pulling images)&lt;/span&gt;
&lt;span class="c1"&gt;# - default-runtime / runtimes: crun (instead of the default 'runc')&lt;/span&gt;
&lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default-runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;crun&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;buildkit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;containerd-snapshotter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;runtimes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;crun&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/usr/local/bin/crun&lt;/span&gt;

&lt;span class="na"&gt;vmType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vz&lt;/span&gt;
&lt;span class="na"&gt;rosetta&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mountType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;virtiofs&lt;/span&gt;
&lt;span class="na"&gt;mountInotify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;cpuType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;

&lt;span class="c1"&gt;# This provisioning script installs WasmEdge and builds crun with wasmedge support:&lt;/span&gt;
&lt;span class="na"&gt;provision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;echo "Install system updates:"&lt;/span&gt;
      &lt;span class="s"&gt;apt-get update -y&lt;/span&gt;
      &lt;span class="s"&gt;apt-get upgrade -y&lt;/span&gt;
      &lt;span class="s"&gt;echo "Install WasmEdge and crun dependencies:"&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: packages curl git python3 already installed:&lt;/span&gt;
      &lt;span class="s"&gt;apt-get install -y make gcc build-essential pkgconf libtool libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev libgcrypt20-dev go-md2man autoconf automake criu xz-utils&lt;/span&gt;
      &lt;span class="s"&gt;apt-get clean -y&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing WasmEdge:"&lt;/span&gt;
      &lt;span class="s"&gt;curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | sudo bash -s -- -p /usr/local&lt;/span&gt;
      &lt;span class="s"&gt;echo&lt;/span&gt;
      &lt;span class="s"&gt;echo "`wasmedge -v` installed!"&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: I failed to configure Wasmtime properly - turned off for now:&lt;/span&gt;
      &lt;span class="s"&gt;#echo "Installing Wasmtime:"&lt;/span&gt;
      &lt;span class="s"&gt;#curl -sSf https://wasmtime.dev/install.sh | bash&lt;/span&gt;
      &lt;span class="s"&gt;#sudo cp .wasmtime/bin/* /usr/local/bin/&lt;/span&gt;
      &lt;span class="s"&gt;#rm -rf .wasmtime&lt;/span&gt;
      &lt;span class="s"&gt;#echo "`wasmtime -V` installed!"&lt;/span&gt;
      &lt;span class="s"&gt;echo "Install crun:"&lt;/span&gt;
      &lt;span class="s"&gt;git clone https://github.com/containers/crun&lt;/span&gt;
      &lt;span class="s"&gt;cd crun&lt;/span&gt;
      &lt;span class="s"&gt;./autogen.sh&lt;/span&gt;
      &lt;span class="s"&gt;#./configure --with-wasmedge --with-wasmtime&lt;/span&gt;
      &lt;span class="s"&gt;./configure --with-wasmedge&lt;/span&gt;
      &lt;span class="s"&gt;make&lt;/span&gt;
      &lt;span class="s"&gt;sudo make install&lt;/span&gt;
      &lt;span class="s"&gt;crun -v&lt;/span&gt;
      &lt;span class="s"&gt;echo "crun installed! Replacing runc with crun:"&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: replacing runc with crun is to simplify containerd config&lt;/span&gt;
      &lt;span class="s"&gt;TRC=`which runc`&lt;/span&gt;
      &lt;span class="s"&gt;sudo rm -rf $TRC&lt;/span&gt;
      &lt;span class="s"&gt;sudo cp `which crun` $TRC&lt;/span&gt;
      &lt;span class="s"&gt;echo "Configuring containerd:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo mkdir -p /etc/containerd/&lt;/span&gt;
      &lt;span class="s"&gt;containerd config default | sudo tee /etc/containerd/config.toml &amp;gt;/dev/null&lt;/span&gt;
      &lt;span class="s"&gt;echo "Restarting/reloading docker/containerd services:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl daemon-reload&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl restart containerd&lt;/span&gt;
      &lt;span class="s"&gt;# As soon as Colima writes its /etc/docker/daemon.json file (right after this provisioning script),&lt;/span&gt;
      &lt;span class="s"&gt;# it will also start the Docker daemon. If we stop Docker here, the changes will actually take effect:&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl stop docker&lt;/span&gt;

&lt;span class="na"&gt;sshConfig&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First colima start time is long
&lt;/h3&gt;

&lt;p&gt;It takes 1.5 minutes on my M1 max mac to start the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extra docker run parameters
&lt;/h3&gt;

&lt;p&gt;After starting Colima with this template, be aware that you need to supply some specific parameters (&lt;code&gt;--platform&lt;/code&gt; and &lt;code&gt;--annotation&lt;/code&gt;) to the &lt;code&gt;docker run&lt;/code&gt; command, e.g.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-dp&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--platform&lt;/span&gt; wasi/wasm32 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--annotation&lt;/span&gt; &lt;span class="s2"&gt;"run.oci.handler=wasm"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         michaelirwin244/wasm-example:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-dp&lt;/span&gt; 8080:8080 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--platform&lt;/span&gt; wasi/wasm32 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--annotation&lt;/span&gt; &lt;span class="s2"&gt;"module.wasm.image/variant=compat-smart"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         michaelirwin244/wasm-example:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stopping container waits for 10 seconds
&lt;/h3&gt;

&lt;p&gt;For some reason the SIGTERM signal is not honoured in the WASM runtime. Stop the container with a specified timeout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker stop &lt;span class="nt"&gt;-t&lt;/span&gt; 0 &amp;lt;container &lt;span class="nb"&gt;hash&lt;/span&gt;/name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;code&gt;colima-runwasi-git&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;My second attempt was to get the &lt;a href="https://github.com/containerd/runwasi"&gt;Runwasi&lt;/a&gt; shims working with Docker, since I did not like the necessary &lt;code&gt;--annotation&lt;/code&gt; parameter which are not needed for the 'official' Docker Desktop configuration. This template remedies that drawback.&lt;/p&gt;

&lt;p&gt;Here is the template (edit the Colima template with &lt;code&gt;$ colima template&lt;/code&gt;). I added comments to the parts relevant for the WASM config, other comments are removed for brevity:&lt;/p&gt;

&lt;h2&gt;
  
  
  Template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="na"&gt;disk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="na"&gt;arch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;
&lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;colima&lt;/span&gt;
&lt;span class="na"&gt;autoActivate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;forwardAgent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="c1"&gt;# I only tested this with 'docker', not 'containerd':&lt;/span&gt;
&lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;

&lt;span class="na"&gt;kubernetes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1.24.3+k3s1&lt;/span&gt;
  &lt;span class="na"&gt;k3sArgs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;dns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;dnsHosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host.docker.internal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host.lima.internal&lt;/span&gt;

&lt;span class="c1"&gt;# Added:&lt;/span&gt;
&lt;span class="c1"&gt;# - containerd-snapshotter: true (meaning containerd will be used for pulling images)&lt;/span&gt;
&lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;buildkit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;containerd-snapshotter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;vmType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vz&lt;/span&gt;
&lt;span class="na"&gt;rosetta&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mountType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;virtiofs&lt;/span&gt;
&lt;span class="na"&gt;mountInotify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;cpuType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;

&lt;span class="c1"&gt;# This provisioning script installs build dependencies, WasmEdge and builds the WASM runtime shims for containerd.&lt;/span&gt;
&lt;span class="c1"&gt;# NOTE: this takes a LOOONG time!&lt;/span&gt;
&lt;span class="na"&gt;provision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing system updates:"&lt;/span&gt;
      &lt;span class="s"&gt;apt-get update -y&lt;/span&gt;
      &lt;span class="s"&gt;apt-get upgrade -y&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing WasmEdge and runwasi build dependencies:"&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: packages curl, git and python3 already installed:&lt;/span&gt;
      &lt;span class="s"&gt;apt-get install -y make gcc build-essential pkgconf libtool libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev libgcrypt20-dev go-md2man autoconf automake criu pkg-config libdbus-glib-1-dev libelf-dev libclang-dev libzstd-dev protobuf-compiler xz-utils&lt;/span&gt;
      &lt;span class="s"&gt;apt-get clean -y&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Setting vars for this script:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Which WASM runtimes to install (wasmedge, wasmtime and wasmer are supported):&lt;/span&gt;
      &lt;span class="s"&gt;WASM_RUNTIMES="wasmedge wasmtime wasmer"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Location of the containerd config file:&lt;/span&gt;
      &lt;span class="s"&gt;CONTAINERD_CONFIG="/etc/containerd/config.toml"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Target location for the WASM runtimes and containerd shims ($TARGET/bin and $TARGET/lib):&lt;/span&gt;
      &lt;span class="s"&gt;TARGET="/usr/local"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Install rustup:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing rustup for building runwasi:"&lt;/span&gt;
      &lt;span class="s"&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain none -y&lt;/span&gt;
      &lt;span class="s"&gt;source "$HOME/.cargo/env"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Install selected WASM runtimes and containerd shims:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;[[ -z "${WASM_RUNTIMES// /}" ]] &amp;amp;&amp;amp; echo "No WASM runtimes selected - exiting!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;git clone https://github.com/containerd/runwasi&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing WASM runtimes and building containerd shims: ${WASM_RUNTIMES}:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo mkdir -p /etc/containerd/&lt;/span&gt;
      &lt;span class="s"&gt;containerd config default | sudo tee $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
      &lt;span class="s"&gt;for runtimeName in $WASM_RUNTIMES; do&lt;/span&gt;
        &lt;span class="s"&gt;case $runtimeName in&lt;/span&gt;
          &lt;span class="s"&gt;wasmedge)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing WasmEdge:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | sudo bash -s -- -p $TARGET&lt;/span&gt;
            &lt;span class="s"&gt;echo&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmedge -v` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;wasmtime)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing wasmtime:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://wasmtime.dev/install.sh | bash&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmtime/bin/* ${TARGET}/bin/&lt;/span&gt;
            &lt;span class="s"&gt;rm -rf .wasmtime&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmtime -V` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;wasmer)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing wasmer:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://get.wasmer.io | sh&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmer/bin/* ${TARGET}/bin/&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmer/lib/* ${TARGET}/lib/&lt;/span&gt;
            &lt;span class="s"&gt;rm -rf .wasmer&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmer -V` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;*)&lt;/span&gt;
            &lt;span class="s"&gt;echo "ERROR: WASM runtime $runtimeName is not supported!"&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
        &lt;span class="s"&gt;esac&lt;/span&gt;
        &lt;span class="s"&gt;cd runwasi&lt;/span&gt;
        &lt;span class="s"&gt;echo "Building containerd-shim-${runtimeName}:"&lt;/span&gt;
        &lt;span class="s"&gt;cargo build -p containerd-shim-${runtimeName} --release&lt;/span&gt;
        &lt;span class="s"&gt;echo "Installing containerd-shim-${runtimeName}-v1:"&lt;/span&gt;
        &lt;span class="s"&gt;sudo install ./target/release/containerd-shim-${runtimeName}-v1 ${TARGET}/bin&lt;/span&gt;
        &lt;span class="s"&gt;sudo ln -sf ${TARGET}/bin/containerd-shim-${runtimeName}-v1 ${TARGET}/bin/containerd-shim-${runtimeName}d-v1&lt;/span&gt;
        &lt;span class="s"&gt;sudo ln -sf ${TARGET}/bin/containerd-shim-${runtimeName}-v1 ${TARGET}/bin/containerd-${runtimeName}d&lt;/span&gt;
        &lt;span class="s"&gt;echo "containerd-shim-${runtimeName} installed."&lt;/span&gt;
        &lt;span class="s"&gt;cd ..&lt;/span&gt;
        &lt;span class="s"&gt;echo "[plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.${runtimeName}]" | sudo tee -a $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
        &lt;span class="s"&gt;echo "  runtime_type = \"io.containerd.${runtimeName}.v1\"" | sudo tee -a $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
      &lt;span class="s"&gt;done&lt;/span&gt;
      &lt;span class="s"&gt;echo "containerd WASM runtimes and shims installed."&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Restart the systemctl services to pick up the installed shims.&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: We need to 'stop' docker because at this point the actual daemon.json config is not yet provisioned:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;echo "Restarting/reloading docker/containerd services:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl daemon-reload&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl restart containerd&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl stop docker&lt;/span&gt;

&lt;span class="na"&gt;sshConfig&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First Colima start time is super long
&lt;/h3&gt;

&lt;p&gt;It takes a couple of minutes on my M1 max mac to start the container. Have some patience!&lt;/p&gt;

&lt;h3&gt;
  
  
  Stopping container waits for 10 seconds
&lt;/h3&gt;

&lt;p&gt;For some reason the SIGTERM signal is not honoured in the WASM runtime. Stop the container with a specified timeout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker stop &lt;span class="nt"&gt;-t&lt;/span&gt; 0 &amp;lt;container &lt;span class="nb"&gt;hash&lt;/span&gt;/name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;code&gt;colima-runwasi&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;This template is the same as the previous template, except it doesn't build the containerd shims, it downloads the latest releases. Starting Colima with this template for the first time takes less than 50 seconds on my M1 max machine.&lt;/p&gt;

&lt;p&gt;Here is the template (edit the Colima template with &lt;code&gt;$ colima template&lt;/code&gt;). I added comments to the parts relevant for the WASM config, other comments are removed for brevity:&lt;/p&gt;

&lt;h2&gt;
  
  
  Template
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
&lt;span class="na"&gt;disk&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12&lt;/span&gt;
&lt;span class="na"&gt;arch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;
&lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;colima&lt;/span&gt;
&lt;span class="na"&gt;autoActivate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;forwardAgent&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="c1"&gt;# I only tested this with 'docker', not 'containerd':&lt;/span&gt;
&lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker&lt;/span&gt;

&lt;span class="na"&gt;kubernetes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1.24.3+k3s1&lt;/span&gt;
  &lt;span class="na"&gt;k3sArgs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;

&lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;dns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;dnsHosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;host.docker.internal&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host.lima.internal&lt;/span&gt;

&lt;span class="c1"&gt;# Added:&lt;/span&gt;
&lt;span class="c1"&gt;# - containerd-snapshotter: true (meaning containerd will be used for pulling images)&lt;/span&gt;
&lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;features&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;buildkit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;containerd-snapshotter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;vmType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vz&lt;/span&gt;
&lt;span class="na"&gt;rosetta&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mountType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;virtiofs&lt;/span&gt;
&lt;span class="na"&gt;mountInotify&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="na"&gt;cpuType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;host&lt;/span&gt;

&lt;span class="c1"&gt;# Custom provision scripts for the virtual machine.&lt;/span&gt;
&lt;span class="na"&gt;provision&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;system&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing system updates:"&lt;/span&gt;
      &lt;span class="s"&gt;apt-get update -y&lt;/span&gt;
      &lt;span class="s"&gt;apt-get upgrade -y&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing dependency for wasmtime installer:"&lt;/span&gt;
      &lt;span class="s"&gt;apt-get install -y xz-utils&lt;/span&gt;
      &lt;span class="s"&gt;apt-get clean -y&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
    &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
      &lt;span class="s"&gt;[ -f /etc/docker/daemon.json ] &amp;amp;&amp;amp; echo "Already provisioned!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Setting vars for this script:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Which WASM runtimes to install (wasmedge, wasmtime and wasmer are supported):&lt;/span&gt;
      &lt;span class="s"&gt;WASM_RUNTIMES="wasmedge wasmtime wasmer"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Location of the containerd config file:&lt;/span&gt;
      &lt;span class="s"&gt;CONTAINERD_CONFIG="/etc/containerd/config.toml"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Target location for the WASM runtimes and containerd shims ($TARGET/bin and $TARGET/lib):&lt;/span&gt;
      &lt;span class="s"&gt;TARGET="/usr/local"&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Install selected WASM runtimes and containerd shims:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;[[ -z "${WASM_RUNTIMES// /}" ]] &amp;amp;&amp;amp; echo "No WASM runtimes selected - exiting!" &amp;amp;&amp;amp; exit 0&lt;/span&gt;
      &lt;span class="s"&gt;echo "Installing WASM runtimes and containerd shims: ${WASM_RUNTIMES}:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo mkdir -p /etc/containerd/&lt;/span&gt;
      &lt;span class="s"&gt;containerd config default | sudo tee $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
      &lt;span class="s"&gt;for runtimeName in $WASM_RUNTIMES; do&lt;/span&gt;
        &lt;span class="s"&gt;case $runtimeName in&lt;/span&gt;
          &lt;span class="s"&gt;wasmedge)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing WasmEdge:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | sudo bash -s -- -p $TARGET&lt;/span&gt;
            &lt;span class="s"&gt;echo&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmedge -v` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;wasmtime)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing wasmtime:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://wasmtime.dev/install.sh | bash&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmtime/bin/* ${TARGET}/bin/&lt;/span&gt;
            &lt;span class="s"&gt;rm -rf .wasmtime&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmtime -V` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;wasmer)&lt;/span&gt;
            &lt;span class="s"&gt;echo "Installing wasmer:"&lt;/span&gt;
            &lt;span class="s"&gt;curl -sSfL https://get.wasmer.io | sh&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmer/bin/* ${TARGET}/bin/&lt;/span&gt;
            &lt;span class="s"&gt;sudo cp .wasmer/lib/* ${TARGET}/lib/&lt;/span&gt;
            &lt;span class="s"&gt;rm -rf .wasmer&lt;/span&gt;
            &lt;span class="s"&gt;echo "`wasmer -V` installed!"&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
          &lt;span class="s"&gt;*)&lt;/span&gt;
            &lt;span class="s"&gt;echo "ERROR: WASM runtime $runtimeName is not supported!"&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
            &lt;span class="s"&gt;;;&lt;/span&gt;
        &lt;span class="s"&gt;esac&lt;/span&gt;
        &lt;span class="s"&gt;shimVersion=$(curl -s https://api.github.com/repos/containerd/runwasi/tags | grep tarball | grep "shim-${runtimeName}" | grep -Eo 'https://[^\"]*' | head -1 | tr "/" "\n" | tail -n 1)&lt;/span&gt;
        &lt;span class="s"&gt;shimUrl="https://github.com/containerd/runwasi/releases/download/containerd-shim-${runtimeName}/${shimVersion}/containerd-shim-${runtimeName}-`uname -m`.tar.gz"&lt;/span&gt;
        &lt;span class="s"&gt;echo "Installing runwasi shim version $shimVersion for $runtimeName runtime from ${shimUrl}:"&lt;/span&gt;
        &lt;span class="s"&gt;curl -sSfL $shimUrl | sudo tar xvz -C ${TARGET}/bin/&lt;/span&gt;
        &lt;span class="s"&gt;echo "[plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.${runtimeName}]" | sudo tee -a $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
        &lt;span class="s"&gt;echo "  runtime_type = \"io.containerd.${runtimeName}.v1\"" | sudo tee -a $CONTAINERD_CONFIG &amp;gt;/dev/null&lt;/span&gt;
      &lt;span class="s"&gt;done&lt;/span&gt;
      &lt;span class="s"&gt;echo "containerd WASM runtimes and shims installed."&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;# Restart the systemctl services to pick up the installed shims.&lt;/span&gt;
      &lt;span class="s"&gt;# NOTE: We need to 'stop' docker because at this point the actual daemon.json config is not yet provisioned:&lt;/span&gt;
      &lt;span class="s"&gt;#&lt;/span&gt;
      &lt;span class="s"&gt;echo "Restarting/reloading docker/containerd services:"&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl daemon-reload&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl restart containerd&lt;/span&gt;
      &lt;span class="s"&gt;sudo systemctl stop docker&lt;/span&gt;

&lt;span class="na"&gt;sshConfig&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;mounts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stopping container waits for 10 seconds
&lt;/h3&gt;

&lt;p&gt;For some reason the SIGTERM signal is not honoured in the WASM runtime. Stop the container with a specified timeout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker stop &lt;span class="nt"&gt;-t&lt;/span&gt; 0 &amp;lt;container &lt;span class="nb"&gt;hash&lt;/span&gt;/name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Putting it all together
&lt;/h1&gt;

&lt;p&gt;Let's go from Colima installation to running a WASM program in Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prepare Colima
&lt;/h2&gt;

&lt;p&gt;First, if you haven't done this already, install Colima:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;colima
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, change the default Colima template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;colima template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command opens (by default) a &lt;code&gt;vim&lt;/code&gt; editor with the default colima yaml template. In this editor, replace all contents with the template from &lt;code&gt;colima-runwasi&lt;/code&gt; above.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In &lt;code&gt;vim&lt;/code&gt;: Type the following key sequence to empty the template:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:%d&amp;lt;Enter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The screen must be empty now.&lt;/p&gt;

&lt;p&gt;Next, put &lt;code&gt;vim&lt;/code&gt; in &lt;code&gt;-- INSERT --&lt;/code&gt; mode by typing the &lt;code&gt;i&lt;/code&gt; key.&lt;br&gt;
Then, paste the contents of the &lt;code&gt;colima-runwasi&lt;/code&gt; template into the editor.&lt;/p&gt;

&lt;p&gt;Finally, save the template by typing the following key sequence:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ESC&amp;gt;:wq!&amp;lt;Enter&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;The Colima template is now configured to install WASM runtimes. Start Colima:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;colima start &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the speed of your machine, this takes approximately between 50 and 90 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install additional Docker plugins
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;docker-buildx docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to follow instructions for the installed Docker plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.docker/cli-plugins
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-sfn&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;brew &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/opt/docker-buildx/bin/docker-buildx ~/.docker/cli-plugins/docker-buildx
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-sfn&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;brew &lt;span class="nt"&gt;--prefix&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build a WASM image
&lt;/h2&gt;

&lt;p&gt;Check out a project with rust examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone https://github.com/second-state/rust-examples.git

Cloning into &lt;span class="s1"&gt;'rust-examples'&lt;/span&gt;...
remote: Enumerating objects: 338, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
remote: Counting objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;73/73&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
remote: Compressing objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;51/51&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
remote: Total 338 &lt;span class="o"&gt;(&lt;/span&gt;delta 42&lt;span class="o"&gt;)&lt;/span&gt;, reused 40 &lt;span class="o"&gt;(&lt;/span&gt;delta 20&lt;span class="o"&gt;)&lt;/span&gt;, pack-reused 265
Receiving objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;338/338&lt;span class="o"&gt;)&lt;/span&gt;, 54.27 KiB | 9.04 MiB/s, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Resolving deltas: 100% &lt;span class="o"&gt;(&lt;/span&gt;214/214&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, enter the &lt;code&gt;rust-examples/hello&lt;/code&gt; directory and build the wasm image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;rust-examples/hello
&lt;span class="nv"&gt;$ &lt;/span&gt;docker buildx build &lt;span class="nt"&gt;--provenance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--platform&lt;/span&gt; wasi/wasm32 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;-t&lt;/span&gt; secondstate/rust-example-hello &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;+] Building 3.6s &lt;span class="o"&gt;(&lt;/span&gt;15/15&lt;span class="o"&gt;)&lt;/span&gt; FINISHED
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;internal] load .dockerignore
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 2B
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;internal] load build definition from Dockerfile
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring dockerfile: 563B
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; resolve image config &lt;span class="k"&gt;for &lt;/span&gt;docker.io/docker/dockerfile:1
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;auth] docker/dockerfile:pull token &lt;span class="k"&gt;for &lt;/span&gt;registry-1.docker.io
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; CACHED docker-image://docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; resolve docker.io/docker/dockerfile:1@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;internal] load metadata &lt;span class="k"&gt;for &lt;/span&gt;docker.io/library/rust:1.64
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;auth] library/rust:pull token &lt;span class="k"&gt;for &lt;/span&gt;registry-1.docker.io
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;buildbase 1/3] FROM docker.io/library/rust:1.64@sha256:53ded1c919ea0dc23be959e28037238d8c321cd88fbac04d818f210031fccc3b
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; resolve docker.io/library/rust:1.64@sha256:53ded1c919ea0dc23be959e28037238d8c321cd88fbac04d818f210031fccc3b
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;internal] load build context
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; transferring context: 426B
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; CACHED &lt;span class="o"&gt;[&lt;/span&gt;buildbase 2/3] WORKDIR /src
 &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; CACHED &lt;span class="o"&gt;[&lt;/span&gt;buildbase 3/3] RUN &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt; bash
 =&amp;gt; [build 1/3] COPY Cargo.toml .
 =&amp;gt; [build 2/3] COPY src ./src
 =&amp;gt; [build 3/3] RUN cargo build --target wasm32-wasi --release
 =&amp;gt; exporting to image
 =&amp;gt; =&amp;gt; exporting layers
 =&amp;gt; =&amp;gt; exporting manifest sha256:506f9c13793e6fd5ce556e36130a7e6977b68720379a393b1a0d2acc23aef501
 =&amp;gt; =&amp;gt; exporting config sha256:1274e89bbbc5c385dae15ac1b768cf2acaae290172018a03efd2dae1d2f0e872
 =&amp;gt; =&amp;gt; naming to docker.io/secondstate/rust-example-hello:latest
 =&amp;gt; =&amp;gt; unpacking to docker.io/secondstate/rust-example-hello:latest
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the image's existence by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker images

REPOSITORY                       TAG       IMAGE ID       CREATED         SIZE
secondstate/rust-example-hello   latest    506f9c13793e   3 minutes ago   2.53MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, check its architecture to verify it is a WASM image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker inspect &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{{.Os}}/{{.Architecture}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         secondstate/rust-example-hello

wasi/wasm32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run the WASM image
&lt;/h2&gt;

&lt;p&gt;Run the WASM image with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--platform&lt;/span&gt; wasi/wasm32 &lt;span class="se"&gt;\&lt;/span&gt;
         &lt;span class="nt"&gt;--runtime&lt;/span&gt; io.containerd.wasmedge.v1 &lt;span class="se"&gt;\&lt;/span&gt;
         secondstate/rust-example-hello:latest

Hello WasmEdge!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;NOTE: The specified runtime above is &lt;code&gt;io.containerd.wasmedge.v1&lt;/code&gt;. You have three options here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;WasmEdge: &lt;code&gt;io.containerd.wasmedge.v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Wasmtime: &lt;code&gt;io.containerd.wasmtime.v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Wasmer: &lt;code&gt;io.containerd.wasmer.v1&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;If you are serious about using WASM containers in Docker / Colima, I suggest to use the last template &lt;code&gt;colima-runwasi&lt;/code&gt;. The other templates are merely evolutionary exercises in getting to know the Docker parts better.&lt;/p&gt;

&lt;p&gt;Let me know how this works for you!&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;p&gt;The information in this Howto is assembled from these links:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.tutorialworks.com/difference-docker-containerd-runc-crio-oci/"&gt;The differences between Docker, containerd, CRI-O and runc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/alternative-runtimes/#use-containerd-shims"&gt;Docker - Use containerd shims&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nigelpoulton.com/webassembly-and-containerd-how-it-works/"&gt;WebAssembly and containerd: How it works&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  EDITS
&lt;/h1&gt;

&lt;p&gt;14 FEB 2024 - added &lt;code&gt;xz-utils&lt;/code&gt; to list of install dependencies for wasmtime&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>colima</category>
      <category>docker</category>
      <category>containerd</category>
    </item>
  </channel>
</rss>
