# Containerizar una aplicación Deno


## Requisitos previos

- Tienes un [cliente git](https://git-scm.com/downloads). Los ejemplos de esta sección usan git por línea de comandos, pero puedes usar cualquier cliente.

## Descripción general

Durante mucho tiempo, Node.js ha sido el runtime de referencia para aplicaciones JavaScript del lado del servidor. Sin embargo, en los últimos años han surgido runtimes alternativos, incluido [Deno](https://deno.land/). Al igual que Node.js, Deno es un runtime de JavaScript y TypeScript, pero adopta un enfoque moderno con funciones de seguridad actuales, una biblioteca estándar integrada y soporte nativo para TypeScript.

¿Por qué desarrollar aplicaciones Deno con Docker? Tener varios runtimes para elegir es interesante, pero gestionar varios runtimes y sus dependencias de forma coherente en todos los entornos puede ser complicado. Ahí Docker resulta invaluable. Usar contenedores para crear y destruir entornos bajo demanda simplifica la gestión de runtimes y garantiza consistencia. Además, a medida que Deno sigue creciendo y evolucionando, Docker ayuda a establecer un entorno de desarrollo fiable y reproducible, reduciendo problemas de configuración y agilizando el flujo de trabajo.

## Obtener la aplicación de ejemplo

Clona la aplicación de ejemplo para usarla en esta guía. Abre una terminal, ve al directorio donde quieras trabajar y ejecuta el siguiente
comando para clonar el repositorio:

```console
$ git clone https://github.com/dockersamples/docker-deno.git && cd docker-deno
```

Ahora deberías tener el siguiente contenido en tu directorio `deno-docker`.

```text
├── deno-docker/
│ ├── compose.yml
│ ├── Dockerfile
│ ├── LICENSE
│ ├── server.ts
│ └── README.md
```

## Entender la aplicación de ejemplo

La aplicación de ejemplo es una aplicación Deno sencilla que usa el framework Oak para crear una API simple que devuelve una respuesta JSON. La aplicación escucha en el puerto 8000 y devuelve el mensaje `{"Status" : "OK"}` cuando accedes a la aplicación en un navegador.

```typescript
// server.ts
import { Application, Router } from "https://deno.land/x/oak@v12.0.0/mod.ts";

const app = new Application();
const router = new Router();

// Define a route that returns JSON
router.get("/", (context) => {
  context.response.body = { Status: "OK" };
  context.response.type = "application/json";
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log("Server running on http://localhost:8000");
await app.listen({ port: 8000 });
```

## Crear un Dockerfile

Antes de crear un Dockerfile, debes elegir una imagen base. Puedes usar la [imagen oficial de Docker para Deno](https://hub.docker.com/r/denoland/deno) o una Docker Hardened Image (DHI) del [catálogo de imágenes endurecidas](https://hub.docker.com/hardened-images/catalog).

Elegir DHI ofrece una imagen lista para producción, ligera y segura. Para más información, consulta [Docker Hardened Images](https://docs-docker.esdocu.com/dhi/).

**Uso de Docker Hardened Images**



Las Docker Hardened Images (DHI) están disponibles para Deno en el [catálogo de Docker Hardened Images](https://hub.docker.com/hardened-images/catalog/dhi/deno). Puedes hacer pull de las DHI directamente desde el registro `dhi.io`.

1. Inicia sesión en el registro DHI:

   ```console
   $ docker login dhi.io
   ```

2. Haz pull de la DHI de Deno como `dhi.io/deno:2`. La etiqueta (`2`) en este ejemplo se refiere a la última versión 2.x de Deno.

   ```console
   $ docker pull dhi.io/deno:2
   ```

Para otras versiones disponibles, consulta el [catálogo](https://hub.docker.com/hardened-images/catalog/dhi/deno).

```dockerfile
# Use the DHI Deno image as the base image
FROM dhi.io/deno:2

# Set the working directory
WORKDIR /app

# Copy server code into the container
COPY server.ts .

# Set permissions (optional but recommended for security)
USER deno

# Expose port 8000
EXPOSE 8000

# Run the Deno server
CMD ["run", "--allow-net", "server.ts"]
```

**Uso de la imagen oficial**



Usar la imagen oficial de Docker es sencillo. En el siguiente Dockerfile verás que la instrucción `FROM` usa `denoland/deno:latest` como imagen base.

Es la imagen oficial de Deno. [Está disponible en Docker Hub](https://hub.docker.com/r/denoland/deno).

```dockerfile
# Use the official Deno image
FROM denoland/deno:latest

# Set the working directory
WORKDIR /app

# Copy server code into the container
COPY server.ts .

# Set permissions (optional but recommended for security)
USER deno

# Expose port 8000
EXPOSE 8000

# Run the Deno server
CMD ["run", "--allow-net", "server.ts"]
```



Además de especificar la imagen base, el Dockerfile también:

- Establece el directorio de trabajo del contenedor en `/app`.
- Copia `server.ts` al contenedor.
- Establece el usuario `deno` para ejecutar la aplicación como usuario no root.
- Expone el puerto 8000 para permitir tráfico a la aplicación.
- Ejecuta el servidor Deno con la instrucción `CMD`.
- Usa la opción `--allow-net` para permitir acceso de red a la aplicación. El archivo `server.ts` usa el framework Oak para crear una API simple que escucha en el puerto 8000.

## Ejecutar la aplicación

Asegúrate de estar en el directorio `deno-docker`. Ejecuta el siguiente comando en una terminal para compilar y ejecutar la aplicación.

```console
$ docker compose up --build
```

Abre un navegador y visita la aplicación en [http://localhost:8000](http://localhost:8000). Verás el mensaje `{"Status" : "OK"}` en el navegador.

En la terminal, pulsa `ctrl`+`c` para detener la aplicación.

### Ejecutar la aplicación en segundo plano

Puedes ejecutar la aplicación desacoplada de la terminal añadiendo la opción `-d`.
Dentro del directorio `deno-docker`, ejecuta el siguiente comando
en una terminal.

```console
$ docker compose up --build -d
```

Abre un navegador y visita la aplicación en [http://localhost:8000](http://localhost:8000).

En la terminal, ejecuta el siguiente comando para detener la aplicación.

```console
$ docker compose down
```

## Resumen

En esta sección aprendiste a containerizar y ejecutar tu aplicación Deno
con Docker.

Información relacionada:

- [Referencia de Dockerfile](/reference/dockerfile/)
- [Archivo `.dockerignore`](/reference/dockerfile/#dockerignore-file)
- [Descripción general de Docker Compose](/compose/)
- [Referencia del archivo Compose](/reference/compose-file/)
- [Docker Hardened Images](/dhi/)

## Próximos pasos

En la siguiente sección aprenderás a desarrollar tu aplicación con
contenedores.

