¿Qué es la redirección de puertos en Docker?
La redirección de puertos en Docker es una forma de hacer que una aplicación dentro de un contenedor Docker sea accesible desde el mundo exterior. Es como si abrieras una ventana en el contenedor para permitir que otros programas o dispositivos se comuniquen con él.
Por ejemplo, supongamos que tienes un contenedor Docker con un servidor web que se ejecuta en el puerto 80. Si quieres que el servidor web sea accesible desde la red externa, debes redirigir el puerto 80 del contenedor al puerto 8080 de la máquina anfitriona. De esta manera, cuando alguien ingrese la dirección IP de la máquina anfitriona seguida del puerto 8080 en su navegador, se mostrará el sitio web alojado en el contenedor Docker.
Ejemplo de enrutado de puertos utilizando la imagen de Nginx de docker
En este ocasión vamos a utilizar la imagen de docker nginx.
docker container run -d nginx
El parámetro
-d
del comandodocker container run
arranca el contenedor en mododetached
, por lo que el contenedor se mantiene en operación en segundo plano.
Al finalizar la descarga y el arranque del contenedor podemos ver que se encuentra en ejecución mediante docker container ls
. La salida sera algo parecido a lo siguiente.
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7480009dd72 nginx "/docker-entrypoint.…" 15 seconds ago Up 14 seconds 80/tcp modest_neumann
En la columna PORTS podemos ver que el puerto 80/tcp se encuentra expuesto dentro del contenedor, sin embargo este no es accesible desde fuera del contenedor.
¿Cómo obtener la dirección IP de un contenedor Docker?
Para obtener la dirección IP de nuestro contenedor utilizando el comando docker container inspect
, este comando nos regresará bastante información.
docker container inspect
Como solo estamos interesados en la información de la dirección IP, podemos utilizar pipe |
y grep
para solo mostrar la línea pertinente.
docker container inspect | grep IPAddress
La salida se ve algo así…
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
Si en el navegador abrimos esta dirección en mi caso http://172.17.0.2 veremos el mensaje de bienvenida del servidor web nginx.
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.
Thank you for using nginx.
Sin embargo como el contenedor esta alojado dentro de mi equipo, cuya dirección es localhost
, cuando intento abrir la dirección web http://localhost en el navegador, este no puede acceder a servidor web del contenedor. Si bien ambos funcionan sobre el puerto 80, cuando intento acceder al puerto 80 de mi equipo (host) este no apunta al mismo servicio http que el del contenedor.
¿Cómo enrutar el puerto 80 del host al puerto 80 de un contenedor?
Para enrutar puertos en Docker utilizamos el parámetro -p
del comando docker container run
. En el caso de nginx vamos a indicarle al parámetro -p
el valor 8080:80
, de forma que al acceder a http://localhost:8080 nos redirija al puerto 80 del contenedor que es en donde se encuentra resolviendo el servidor web.
docker container run -d -p 8080:80 nginx
Si entramos ahora a la dirección http://localhost:8080 podremos ver el servidor nginx ejecutándose.
¿Cómo asignar puertos aleatorios en Docker?
Cada contenedor puede tener una serie de puertos expuestos, si deseamos enrutar cada uno de estos puertos a un puerto del host podemos reemplazar el parámetro -p
por -P
, la diferencia es que este último no requiere de un valor ya que cuando se utiliza Docker asigna un puerto en el host para cada uno de los puertos expuestos por el contenedor. Este rango de puertos es conocido como los puertos efímeros, que dan del rango del número 30000 al 60000 (aproximadamente).
docker container run -d -P nginx
Si listamos los contenedores nuevamente docker container ls
nos daremos cuenta que hay un puerto autoasignado para enrutar el puerto 80 del contenedor. La salida se verá algo así:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d778010f104f nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:32768->80/tcp serene_turing
¿Cómo puedo cambiar la redirección de puertos en tiempo de ejecución?
- Identifica el contenedor cuya redirección de puertos deseas cambiar utilizando el comando docker ps.
- Detén el contenedor utilizando el comando docker stop <nombre_del_contenedor>.
- Utiliza el comando docker run con la opción -p para especificar la nueva redirección de puertos. Por ejemplo, si deseas redirigir el puerto 8080 del host al puerto 80 del contenedor, utiliza el siguiente comando:
docker run -p 8080:80 --name <nombre_del_contenedor> <nombre_de_la_imagen>
Donde <nombre_del_contenedor> es el nombre que deseas asignar al contenedor y <nombre_de_la_imagen> es el nombre de la imagen que deseas utilizar para crear el contenedor.
- Inicia el contenedor utilizando el comando docker start <nombre_del_contenedor>.
De esta manera, la redirección de puertos se actualizará para el contenedor especificado y se podrá acceder a la aplicación a través del nuevo puerto redirigido en la máquina host.
¿Puedo redireccionar varios puertos al mismo contenedor en Docker?
Sí, es posible redireccionar varios puertos al mismo contenedor en Docker. Para hacerlo, debes utilizar el parámetro -p varias veces, especificando los puertos que deseas redirigir y los puertos de destino dentro del contenedor.
Por ejemplo, si deseas redirigir el puerto 8080 del host al puerto 80 del contenedor y el puerto 3000 del host al puerto 3000 del contenedor, utiliza el siguiente comando:
docker run -p 8080:80 -p 3000:3000 nombre_del_contenedor
De esta manera, el contenedor será accesible a través de los puertos redirigidos en la máquina host. Puedes especificar tantas redirecciones de puertos como necesites utilizando el mismo formato.
Considera que al redireccionar varios puertos al mismo contenedor, debes asegurarte de que no haya conflictos entre las aplicaciones que se ejecutan en el contenedor y que los puertos estén disponibles para su uso.
¿Cómo configuro la redirección de puertos al iniciar un contenedor Docker?
Para configurar la redirección de puertos al iniciar un contenedor Docker, debes utilizar el parámetro -p con el comando docker run. El formato del comando es el siguiente:
docker run -p <puerto_host>:<puerto_contenedor> <nombre_de_la_imagen>
Donde:
- <puerto_host> es el número de puerto en la máquina host que se va a redirigir.
- <puerto_contenedor> es el número de puerto en el contenedor que se va a redirigir.
- <nombre_de_la_imagen> es el nombre de la imagen de Docker que deseas utilizar para crear el contenedor.
Por ejemplo, si deseas redirigir el puerto 8080 del host al puerto 80 del contenedor al iniciar un contenedor con la imagen nginx, utiliza el siguiente comando:
docker run -p 8080:80 nginx
De esta manera, el contenedor se iniciará con la redirección de puertos especificada y podrás acceder a la aplicación que se ejecuta en el contenedor a través del puerto redirigido en la máquina host.
Considera que al configurar la redirección de puertos al iniciar un contenedor, debes asegurarte de que los puertos que deseas redirigir estén disponibles para su uso en la máquina host y en el contenedor.
¿Puedo cambiar la redirección de puertos en tiempo de ejecución?
Es posible cambiar la redirección de puertos en tiempo de ejecución en Docker deteniendo y reiniciando el contenedor con la nueva redirección de puertos especificada.
- Identifica el contenedor cuya redirección de puertos deseas cambiar utilizando el comando docker ps.
- Detén el contenedor utilizando el comando docker stop <nombre_del_contenedor>.
- Utiliza el comando docker run con la opción -p para especificar la nueva redirección de puertos. Por ejemplo, si deseas redirigir el puerto 8080 del host al puerto 80 del contenedor, utiliza el siguiente comando:
docker run -p 8080:80 --name <nombre_del_contenedor> <nombre_de_la_imagen>
Donde <nombre_del_contenedor> es el nombre que deseas asignar al contenedor y <nombre_de_la_imagen> es el nombre de la imagen que deseas utilizar para crear el contenedor.
- Inicia el contenedor utilizando el comando docker start <nombre_del_contenedor>.
De esta manera, la redirección de puertos se actualizará para el contenedor especificado y se podrá acceder a la aplicación a través del nuevo puerto redirigido en la máquina host.
¿Cómo verifico si la redirección de puertos está funcionando correctamente en Docker?
Para verificar si la redirección de puertos está funcionando correctamente en Docker, puedes seguir estos pasos:
- Ejecuta el comando docker ps para obtener una lista de los contenedores en ejecución.
- Identifica el contenedor que deseas verificar y toma nota del puerto redirigido que has configurado utilizando la opción -p al iniciar el contenedor.
- Abre un navegador web y visita la URL http://localhost:<puerto_host>, donde <puerto_host> es el número de puerto que has especificado para redirigir en la máquina host. Por ejemplo, si has redirigido el puerto 8080 de la máquina host al puerto 80 del contenedor, deberás visitar http://localhost:8080 en el navegador.
- Si todo funciona correctamente, deberías ver la aplicación que se ejecuta dentro del contenedor en tu navegador.
Si tienes problemas para acceder a la aplicación, verifica que los puertos estén abiertos en la máquina host y en el contenedor, y que la redirección de puertos se haya configurado correctamente. También puedes revisar los registros de Docker utilizando el comando docker logs <nombre_del_contenedor> para obtener más información sobre cualquier error que se haya producido.
¿Qué puertos están disponibles para redireccionar en Docker?
En teoría, puedes redireccionar cualquier puerto disponible en Docker. Sin embargo, es importante tener en cuenta que algunos puertos ya están reservados para otros usos y no se deben utilizar para aplicaciones personalizadas.
Por lo general, se recomienda utilizar puertos en el rango de 49152 a 65535 para aplicaciones personalizadas en Docker. Estos puertos están reservados para uso privado y no deberían interferir con ningún otro servicio en el sistema.
Además, es importante tener en cuenta que algunos puertos pueden estar en uso por otros contenedores o servicios en la máquina host, por lo que es importante elegir puertos que no entren en conflicto con otros servicios. Para verificar qué puertos están en uso en tu sistema, puedes utilizar el comando netstat -tulpn
.
¿Cómo redirigir puertos específicos a diferentes contenedores en Docker?
Sí, es posible redirigir puertos específicos a diferentes contenedores en Docker. Esto se logra utilizando el parámetro -p
seguido del puerto en el host y el puerto dentro del contenedor, seguido del nombre del contenedor.
Por ejemplo, para redirigir el puerto 80 en el host al puerto 8080 en un contenedor llamado webserver1
y el puerto 81 en el host al puerto 8080 en un contenedor llamado webserver2
, se pueden utilizar los siguientes comandos:
docker run -d -p 80:8080 --name webserver1 webserver-image
docker run -d -p 81:8080 --name webserver2 webserver-image
En este ejemplo, el primer comando redirecciona el puerto 80 en el host al puerto 8080 en el contenedor webserver1, mientras que el segundo comando redirecciona el puerto 81 en el host al puerto 8080 en el contenedor webserver2.
¿Cómo redirecciono puertos desde un contenedor a otro en Docker?
Para redireccionar puertos desde un contenedor a otro en Docker, es necesario utilizar el parámetro -p
seguido del puerto dentro del contenedor y el nombre del contenedor desde donde se desea redireccionar el puerto.
Por ejemplo, si se tiene un contenedor llamado app1
que se ejecuta en el puerto 8080 y se desea redireccionar ese puerto al puerto 80 del contenedor app2
, se puede utilizar el siguiente comando:
docker run -d --name app2 -p 80:80 --link app1:app1 app2-image
En este ejemplo, el parámetro --link
se utiliza para crear un enlace entre los contenedores app1
y app2
, lo que permite que app2
acceda al puerto 8080 de app1
. Luego, el parámetro -p
se utiliza para redireccionar el puerto 80 de app2
al puerto 8080 de app1
.
Considera que este enfoque solo funcionará si los contenedores se ejecutan en la misma máquina Docker y si ambos contenedores están en la misma red de Docker. Además, también se debe tener en cuenta que el parámetro
--link
se ha marcado como obsoleto en Docker 1.13 y se recomienda utilizar las redes de Docker en su lugar.
¿Qué ocurre si un puerto ya está en uso en la máquina host al redirigirlo en Docker?
Si se intenta redirigir un puerto en Docker y ese puerto ya está en uso en la máquina host, Docker arrojará un error y no se podrá realizar la redirección.
Por ejemplo, si se intenta redirigir el puerto 80 del contenedor al puerto 80 de la máquina host, pero ese puerto ya está en uso por otro proceso en la máquina host, Docker arrojará un mensaje de error indicando que el puerto ya está en uso.
Para solucionar este problema, se puede utilizar un puerto diferente en la máquina host al momento de redirigirlo al contenedor. Por ejemplo, se podría redirigir el puerto 8080 de la máquina host al puerto 80 del contenedor.
Otra opción es detener el proceso que está utilizando el puerto en la máquina host y luego redirigir el puerto en Docker. Sin embargo, esto puede no ser viable en todos los casos y se debe tener cuidado al detener procesos en la máquina host, ya que esto puede afectar el funcionamiento de otros servicios o aplicaciones.