# Publicar y exponer puertos





## Explicación

Si has estado siguiendo las guías hasta ahora, comprenderás que los contenedores proporcionan procesos aislados para cada componente de tu aplicación. Cada componente (un frontend de React, una API de Python y una base de datos Postgres) se ejecuta en su propio entorno aislado (sandbox), completamente separado de todo lo demás en tu máquina host. Este aislamiento es excelente para la seguridad y la gestión de dependencias, pero también significa que no puedes acceder a ellos directamente. Por ejemplo, no puedes acceder a la aplicación web en tu navegador.

Ahí es donde entra en juego la publicación de puertos.

### Publicar puertos

Publicar un puerto proporciona la capacidad de romper un poco el aislamiento de red configurando una regla de reenvío. Como ejemplo, puedes indicar que las solicitudes en el puerto `8080` de tu host deben reenviarse al puerto `80` del contenedor. La publicación de puertos ocurre durante la creación del contenedor utilizando la bandera `-p` (o `--publish`) con `docker run`. La sintaxis es:

```console
$ docker run -d -p HOST_PORT:CONTAINER_PORT nginx
```

- `HOST_PORT`: El número de puerto en tu máquina host donde deseas recibir tráfico
- `CONTAINER_PORT`: El número de puerto dentro del contenedor que está escuchando conexiones

Por ejemplo, para publicar el puerto `80` del contenedor en el puerto `8080` del host:

```console
$ docker run -d -p 8080:80 nginx
```

Ahora, cualquier tráfico enviado al puerto `8080` en tu máquina host se reenviará al puerto `80` dentro del contenedor.

> [!IMPORTANT]
>
> Cuando se publica un puerto, se publica en todas las interfaces de red de forma predeterminada. Esto significa que cualquier tráfico que llegue a tu máquina puede acceder a la aplicación publicada. Ten cuidado al publicar bases de datos o cualquier información confidencial. [Obtén más información sobre los puertos publicados aquí](/engine/network/#published-ports).

### Publicar en puertos efímeros

A veces, es posible que simplemente desees publicar el puerto pero no te importe qué puerto del host se utilice. En estos casos, puedes dejar que Docker elija el puerto por ti. Para hacerlo, simplemente omite la configuración `HOST_PORT`.

Por ejemplo, el siguiente comando publicará el puerto `80` del contenedor en un puerto efímero del host:

```console
$ docker run -p 80 nginx
```

Una vez que el contenedor esté funcionando, el uso de `docker ps` te mostrará el puerto elegido:

```console
docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                    NAMES
a527355c9c53   nginx         "/docker-entrypoint.…"   4 seconds ago    Up 3 seconds    0.0.0.0:54772->80/tcp    romantic_williamson
```

En este ejemplo, la aplicación está expuesta en el host en el puerto `54772`.

### Publicar todos los puertos

Al crear una imagen de contenedor, la instrucción `EXPOSE` se utiliza para indicar que la aplicación empaquetada utilizará el puerto especificado. Estos puertos no se publican de forma predeterminada.

Con la bandera `-P` o `--publish-all`, puedes publicar automáticamente todos los puertos expuestos en puertos efímeros. Esto es bastante útil cuando intentas evitar conflictos de puertos en entornos de desarrollo o pruebas.

Por ejemplo, el siguiente comando publicará todos los puertos expuestos configurados por la imagen:

```console
$ docker run -P nginx
```

## Pruébalo

En esta guía práctica, aprenderás cómo publicar puertos de contenedores utilizando tanto la CLI como Docker Compose para implementar una aplicación web.

### Usar la CLI de Docker

En este paso, ejecutarás un contenedor y publicarás su puerto utilizando la CLI de Docker.

1. [Descarga e instala](/get-started/get-docker/) Docker Desktop.

2. En una terminal, ejecuta el siguiente comando para iniciar un nuevo contenedor:

   ```console
   $ docker run -d -p 8080:80 docker/welcome-to-docker
   ```

   El primer `8080` se refiere al puerto del host. Este es el puerto en tu máquina local que se utilizará para acceder a la aplicación que se ejecuta dentro del contenedor. El segundo `80` se refiere al puerto del contenedor. Este es el puerto en el que escucha la aplicación dentro del contenedor para recibir conexiones entrantes. Por lo tanto, el comando vincula el puerto `8080` del host con el puerto `80` en el sistema del contenedor.

3. Verifica el puerto publicado yendo a la vista de **Containers** del Panel de Docker Desktop.

   ![Una captura de pantalla del Panel de Docker Desktop que muestra el puerto publicado](/get-started/docker-concepts/running-containers/publishing-ports/images/published-ports.webp?w=5000&border=true)

4. Abre el sitio web seleccionando el enlace en la columna **Port(s)** de tu contenedor o visitando [http://localhost:8080](http://localhost:8080) en tu navegador.

   ![Una captura de pantalla de la página de inicio del servidor web Nginx que se ejecuta en un contenedor](/get-started/docker-concepts/the-basics/images/access-the-frontend.webp?border=true)

### Usar Docker Compose

Este ejemplo iniciará la misma aplicación utilizando Docker Compose:

1. Crea un directorio nuevo y, dentro de ese directorio, crea un archivo `compose.yaml` con el siguiente contenido:

   ```yaml
   services:
     app:
       image: docker/welcome-to-docker
       ports:
         - 8080:80
   ```

   La configuración `ports` acepta diferentes tipos de sintaxis para la definición del puerto. En este caso, estás utilizando el mismo formato `HOST_PORT:CONTAINER_PORT` utilizado en el comando `docker run`.

2. Abre una terminal y navega al directorio que creaste en el paso anterior.

3. Utiliza el comando `docker compose up` para iniciar la aplicación.

4. Abre tu navegador en [http://localhost:8080](http://localhost:8080).

## Recursos adicionales

Si deseas profundizar en este tema, asegúrate de consultar los siguientes recursos:

- [Referencia de CLI de docker container port](/reference/cli/docker/container/port/)
- [Puertos publicados](/engine/network/#published-ports)

## Siguientes pasos

Ahora que comprendes cómo publicar y exponer puertos, estás listo para aprender cómo sobrescribir los valores predeterminados del contenedor utilizando el comando `docker run`.

[Sobrescribir los valores predeterminados del contenedor](/get-started/docker-concepts/running-containers/publishing-ports/overriding-container-defaults)


