# Cargas de trabajo Wasm





> [!IMPORTANT]
>
> Las cargas de trabajo Wasm están obsoletas y se eliminarán en una versión futura de Docker Desktop. Esta función ya no se mantiene activamente.

WebAssembly (Wasm) es una alternativa rápida y ligera a los contenedores Linux y Windows. Con Docker Desktop, puedes ejecutar cargas de trabajo Wasm junto a contenedores tradicionales.

Esta página proporciona información sobre cómo ejecutar aplicaciones Wasm junto con tus contenedores Linux en Docker.

> [!TIP]
>
> Obtén más información sobre los casos de uso y las ventajas y desventajas de Wasm en la [publicación del blog sobre la vista previa técnica de Docker Wasm](https://www.docker.com/blog/docker-wasm-technical-preview/).

## Activar las cargas de trabajo Wasm

Las cargas de trabajo Wasm requieren que la función [almacenamiento de imágenes de containerd](/desktop/features/wasm/containerd/) esté activada. Si aún no utilizas el almacenamiento de imágenes de containerd, las imágenes y contenedores preexistentes no estarán accesibles.

1. Dirígete a **Settings** en Docker Desktop.
2. En la pestaña **General**, selecciona la casilla **Use containerd for pulling and storing images**.
3. Ve a **Features in development** y selecciona la opción **Enable Wasm**.
4. Selecciona **Apply** para guardar la configuración.
5. En el cuadro de diálogo de confirmación, selecciona **Install** para instalar los entornos de ejecución (runtimes) de Wasm.

Docker Desktop descarga e instala los siguientes entornos de ejecución:
- `io.containerd.slight.v1`
- `io.containerd.spin.v2`
- `io.containerd.wasmedge.v1`
- `io.containerd.wasmtime.v1`
- `io.containerd.lunatic.v1`
- `io.containerd.wws.v1`
- `io.containerd.wasmer.v1`

## Ejemplos de uso

### Ejecutar una aplicación Wasm con `docker run`

El siguiente comando `docker run` inicia un contenedor Wasm en tu sistema:

```console
$ docker run \
  --runtime=io.containerd.wasmedge.v1 \
  --platform=wasi/wasm \
  secondstate/rust-example-hello
```

Después de ejecutar este comando, puedes visitar [http://localhost:8080/](http://localhost:8080/) para ver la salida "Hello world" de este módulo de ejemplo.

Si recibes un mensaje de error, consulta la [sección de resolución de problemas](#resolución-de-problemas) para obtener ayuda.

Ten en cuenta las opciones (flags) `--runtime` y `--platform` utilizadas en este comando:

- `--runtime=io.containerd.wasmedge.v1`: Informa al motor de Docker de que deseas utilizar el shim containerd de Wasm en lugar del entorno de ejecución estándar de contenedores Linux.
- `--platform=wasi/wasm`: Especifica la arquitectura de la imagen que deseas utilizar. Al aprovechar una arquitectura Wasm, no necesitas compilar imágenes independientes para las diferentes arquitecturas de máquina. El entorno de ejecución de Wasm se encarga del paso final de convertir el binario de Wasm en instrucciones de máquina.

### Ejecutar una aplicación Wasm con Docker Compose

La misma aplicación se puede ejecutar utilizando el siguiente archivo de Docker Compose:

```yaml
services:
  app:
    image: secondstate/rust-example-hello
    platform: wasi/wasm
    runtime: io.containerd.wasmedge.v1
```

Inicia la aplicación utilizando los comandos normales de Docker Compose:

   ```console
   $ docker compose up
   ```

### Ejecutar una aplicación multiservicio con Wasm

La red funciona de la misma manera que esperas con los contenedores Linux, lo que te brinda la flexibilidad de combinar aplicaciones Wasm con otras cargas de trabajo en contenedores, como una base de datos, en una sola pila (stack) de aplicaciones.

En el siguiente ejemplo, la aplicación Wasm utiliza una base de datos MariaDB que se ejecuta en un contenedor.

1. Clona el repositorio.

   ```console
   $ git clone https://github.com/second-state/microservice-rust-mysql.git
   Cloning into 'microservice-rust-mysql'...
   remote: Enumerating objects: 75, done.
   remote: Counting objects: 100% (75/75), done.
   remote: Compressing objects: 100% (42/42), done.
   remote: Total 75 (delta 29), reused 48 (delta 14), pack-reused 0
   Receiving objects: 100% (75/75), 19.09 KiB | 1.74 MiB/s, done.
   Resolving deltas: 100% (29/29), done.
   ```

2. Dirígete al proyecto clonado e inícialo utilizando Docker Compose.

   ```console
   $ cd microservice-rust-mysql
   $ docker compose up
   [+] Running 0/1
   ⠿ server Warning                                                                                                  0.4s
   [+] Building 4.8s (13/15)
   ...
   microservice-rust-mysql-db-1      | 2022-10-19 19:54:45 0 [Note] mariadbd: ready for connections.
   microservice-rust-mysql-db-1      | Version: '10.9.3-MariaDB-1:10.9.3+maria~ubu2204'  socket: '/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
   ```

   Si ejecutas `docker image ls` desde otra ventana de terminal, puedes ver la imagen de Wasm en tu almacenamiento de imágenes.

   ```console
   $ docker image ls
   REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
   server       latest    2c798ddecfa1   2 minutes ago   3MB
   ```

   Al inspeccionar la imagen, se muestra que tiene una plataforma `wasi/wasm`, una combinación de sistema operativo y arquitectura:

   ```console
   $ docker image inspect server | grep -A 3 "Architecture"
           "Architecture": "wasm",
           "Os": "wasi",
           "Size": 3001146,
           "VirtualSize": 3001146,
   ```

3. Abre la URL `http://localhost:8090` en un navegador y crea algunos pedidos de ejemplo. Todos ellos interactúan con el servidor Wasm.

4. Cuando hayas terminado, deten todo presionando `Ctrl+C` en la terminal en la que iniciaste la aplicación.

### Compilar y subir (push) un módulo Wasm

1. Crea un `Dockerfile` que compile tu aplicación Wasm.

   El procedimiento exacto varía según el lenguaje de programación que utilices.

2. En una etapa independiente en tu `Dockerfile`, extrae el módulo y establécelo como el `ENTRYPOINT`.

   ```dockerfile
   # syntax=docker/dockerfile:1
   FROM scratch
   COPY --from=build /build/hello_world.wasm /hello_world.wasm
   ENTRYPOINT [ "/hello_world.wasm" ]
   ```

3. Compila y sube la imagen especificando la arquitectura `wasi/wasm`. Buildx facilita hacer esto en un solo comando.

   ```console
   $ docker buildx build --platform wasi/wasm -t username/hello-world .
   ...
   => exporting to image                                                                             0.0s
   => => exporting layers                                                                            0.0s
   => => exporting manifest sha256:2ca02b5be86607511da8dc688234a5a00ab4d58294ab9f6beaba48ab3ba8de56  0.0s
   => => exporting config sha256:a45b465c3b6760a1a9fd2eda9112bc7e3169c9722bf9e77cf8c20b37295f954b    0.0s
   => => naming to docker.io/username/hello-world:latest                                            0.0s
   => => unpacking to docker.io/username/hello-world:latest                                         0.0s
   $ docker push username/hello-world
   ```

## Resolución de problemas

Esta sección contiene instrucciones sobre cómo resolver problemas comunes.

### Entorno de ejecución especificado desconocido

Si intentas ejecutar un contenedor Wasm sin el [almacenamiento de imágenes de containerd](/desktop/features/containerd/), se mostrará un error similar al siguiente:

```text
docker: Error response from daemon: Unknown runtime specified io.containerd.wasmedge.v1.
```

[Activa la función de containerd](/desktop/features/containerd/#enable-the-containerd-image-store) en la configuración de Docker Desktop e inténtalo de nuevo.

### Error al iniciar el shim: error al resolver la ruta del entorno de ejecución

Si utilizas una versión anterior de Docker Desktop que no soporta la ejecución de cargas de trabajo Wasm, verás un mensaje de error similar al siguiente:

```text
docker: Error response from daemon: failed to start shim: failed to resolve runtime path: runtime "io.containerd.wasmedge.v1" binary not installed "containerd-shim-wasmedge-v1": file does not exist: unknown.
```

Actualiza Docker Desktop a la última versión e inténtalo de nuevo.

## Problemas conocidos

- Es posible que Docker Compose no finalice de forma limpia al ser interrumpido. Como alternativa, limpia los procesos de `docker-compose` enviándoles un SIGKILL (`killall -9 docker-compose`).
- Las subidas (pushes) a Docker Hub pueden mostrar un error que indica `server message: insufficient_scope: authorization failed`, incluso después de haber iniciado sesión a través de Docker Desktop. Como alternativa, ejecuta `docker login` en la CLI.


