====== 4.c Despliegue avanzado en Servidor: Redes y Proxy ======
===== Gestión de Redes =====
Docker permite crear redes aisladas entre los distintos contenedores. De esa forma , si un contenedor es atacado, no se tendrá acceso por red al resto de los contenedores sino únicamente a los de su propia red.
^ Orden ^ Explicación ^
| [[https://docs.docker.com/engine/reference/commandline/network_create/|docker network create]] | Crea una red |
| [[https://docs.docker.com/engine/reference/commandline/network_rm/|docker network rm]] | Borrar una red |
| [[https://docs.docker.com/engine/reference/commandline/network_ls/|docker network ls]] | Ver las redes que hay |
| [[https://docs.docker.com/engine/reference/commandline/network_connect/|docker network connect]] | Conecta un contenedor a una red |
| [[https://docs.docker.com/engine/reference/commandline/network_disconnect/|docker network disconnect]] | Desconecta un contenedor de una red |
Para trabajar con redes, lo que debemos hacer es
* Primero crear la red:
docker network create nombreDeLaRed
* Conectar un contenedor a esa red
docker network connect nombreDeLaRed nombreDelContenedor
* También podemos conectar la red al contenedor al usar ''docker container run'' con la opción ''--network=nombreDeLaRed''
docker container run \
-dit \
-v /opt/mariadb:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-p 4000:3306 \
--network nombreDeLaRed \
--name prueba_mariadb \
mariadb:10.1
\\
\\
\\
===== Proxy con Nginx =====
¿Recuerdas la cabecera ''Host'' de HTTP? Servía para indicar a que //servidor web// iba dirigida la petición ya que en una misma máquina se ponían varios servidores web.
Pues vamos ahora a configurar Docker para que todos los servidores compartan el mismo puerto (el 80). Para ello vamos a usar un servidor proxy llamado Nginx. Obviamente, Nginx va estar dentro de otro contenedor de Docker. La imagen a usar es [[https://hub.docker.com/r/nginxproxy/nginx-proxy|nginxproxy/nginx-proxy con tag 2675]].
Para arrancar el servidor usamos la siguiente orden:
sudo docker container run \
-dit \
-p 80:80 \
--restart always \
-v /var/run/docker.sock:/tmp/docker.sock:ro \
--name nginx-proxy \
nginxproxy/nginx-proxy:2675
Como vemos no tiene nada de especial excepto la línea ''-v /var/run/docker.sock:/tmp/docker.sock:ro'' pero solo decir que es para que Nginx pueda acceder al Docker real de la máquina real.
Y ahora , ¿Como arrancamos nuestro servidores web? Pues simplemente hay que añadir dos parámetros y quitar uno.
* Y hay que quitar el parámetro de ''-p puertoExterno:puertoInterno'' ya que ahora el contenedor no se va a exponer al exterior.
* Hay que añadir:
* ''-e VIRTUAL_PORT=puertoInterno'': Siendo **puertoInterno** donde está escuchando nuestro servidor Web. Esa información la sabremos por la documentación
* ''-e VIRTUAL_HOST=nombreDominio'': Siendo **nombreDominio** el nombre del dominio que queremos que gestione el servidor que estamos arrancando.
Veamos el siguiente ejemplo:
sudo docker container run \
-dit \
-v /home/alumno/lorenzo/httpd:/var/www/html \
-e VIRTUAL_PORT=80
-e VIRTUAL_HOST=lorenzo.preproducciondaw.cip.fpmislata.com \
--name lorenzo_apache \
php:8.1-apache-bullseye
Vemos que el servidor está escuchando en el puerto 80 y va a gestionar las peticiones del dominio //lorenzo.preproducciondaw.cip.fpmislata.com// que lleguen a Nginx.
Los servidores de Base de datos u otros contenedores que no son el servidor web no tienen que hacer nada especial por usar Nginx ya que no se accede a ellos a través del proxy sino directamente a ellos o únicamente de forma interna.
Mas información:
* [[https://cloud.google.com/community/tutorials/nginx-reverse-proxy-docker|Running an NGINX Reverse Proxy with Docker and Let's Encrypt on Google Compute Engine]]
* [[http://jasonwilder.com/blog/2014/03/25/automated-nginx-reverse-proxy-for-docker/|Automated Nginx Reverse Proxy for Docker]]
* [[https://tevinjeffrey.me/how-to-setup-nginx-proxy-and-lets-encrypt-with-docker/|How to setup NGINX with automatic HTTPS in Docker]]
* [[https://medium.com/@francoisromain/host-multiple-websites-with-https-inside-docker-containers-on-a-single-server-18467484ab95|Host multiple websites with HTTPS on a single server]]
===== docker compose =====
¿Y como usamos docker compose cuando usamos nginx-proxy?
Pues lo único que hay que indicar es que usemos la red en la que está nginx-proxy.
En nuestro caso nginx-proxy ha creado la red ''nginx-proxy-network'':
Para levantar el proxy usamos el siguiente script:
docker network create nginx-proxy-network
docker container stop nginx-proxy
docker container rm nginx-proxy
docker container run --detach \
--name nginx-proxy \
--publish 80:80 \
--volume /var/run/docker.sock:/tmp/docker.sock:ro \
--network nginx-proxy-network \
nginxproxy/nginx-proxy:2675
Y nuestro ''docker-compose.yml'' deberá indicar que usemos esa red:
services:
web:
build: .
container_name: web-lorenzo
environment:
VIRTUAL_HOST: lorenzo.preproducciondaw.cip.fpmislata.com
networks:
- proxy_red
networks:
proxy_red:
external:
name: nginx-proxy-network
En la linea 13 decimos la red que realmente vamos a usar que es ''nginx-proxy-network'' ya que es en la que está usando nginx-proxy. Pero en la línea 11 la damos un "alias" a esa red y la llamamos ''proxy_red'' porque esa es la red que vamos a indicar en la línea 8 que vamos a usar.
===== El fichero hosts =====
Ahora para que funcione el proxy con nginx ya no podemos acceder a la máquina real con la IP sino que habrá que usar el nombre de dominio. Si no tenemos acceso a un nombre de dominio real, podemos simular nosotros uno modificando el fichero ''hosts'' de la máquina donde vayamos a hacer la petición.
El fichero hosts simplemente contiene IPs y nombre e dominio que usará nuestro ordenador. De esa forma simularemos tener un dominio.
En los siguientes artículos se explica como modificar el fichero hosts
* [[https://es.wikipedia.org/wiki/Archivo_hosts|Archivo hosts]]
* [[https://www.siteground.es/kb/archivo-hosts/|¿Cómo se usa el archivo “hosts”?]]
\\
\\
\\