Para una mejor comprensión del siguiente material, se recomienda que primero lea la
publicación anteriorConsidere un ejemplo de desarrollo de un entorno local que consiste en un grupo de Nginx + PHP + MySql + phpMyAdmin. Este paquete es muy popular y puede satisfacer una serie de necesidades estándar de un desarrollador ordinario.
Como en la publicación anterior, el énfasis se desplazará hacia la utilidad docker-compose que la ventana acoplable en su forma más pura.
¡Entonces vamos!
Comencemos con docker-compose.yml, que está en una carpeta proxy separada:
docker-compose.yml para nginx-proxyversion: '3.0' services: proxy: image: jwilder/nginx-proxy ports: - 80:80 volumes: - /var/run/docker.sock:/tmp/docker.sock:ro networks: - proxy networks: proxy: driver: bridge
El archivo presentado describe la configuración para crear un contenedor con el nombre
proxy en función de la
imagen: imagen jwilder / nginx-proxy y crear una red con el mismo nombre. La directiva de
redes indica a qué redes está conectado el contenedor, en este ejemplo, esta es nuestra red proxy.
Al crear una red, la directiva driver: bridge podría omitirse. Un controlador de puente es el controlador predeterminado. Este contenedor se comunicará a través de la red con otros contenedores.
La imagen jwilder / nginx-proxy es básica y está tomada, y el
Docker Hub también proporciona una descripción bastante extensa y detallada de su uso. El principio de funcionamiento de nginx-proxy es bastante simple: accede a la información sobre la ejecución de contenedores a través de un socket docker reenviado, analiza la presencia de una variable de entorno con el nombre VIRTUAL_HOST y redirige las solicitudes del host especificado al contenedor para el que está configurada esta variable de entorno.
Iniciamos el proxy con el comando docker-compose up -d ya conocido, observamos el siguiente resultado:
Creating network "proxy_proxy" with driver "bridge" Creating proxy_proxy_1 ... done
Esta conclusión nos informa que al principio se creó la red proxy_proxy y luego se creó el contenedor proxy_proxy_1. El nombre de la red se obtiene del nombre de la carpeta en la que se encontraba el archivo docker-compose.yml, tengo un proxy y el nombre de la red del mismo nombre.
Si ingresa el
comando docker network ls , veremos una lista de redes de docker en nuestro sistema y una de ellas debería ser proxy_proxy.
El nombre del contenedor se basa en el mismo principio que el nombre de la carpeta más el nombre y el número del servicio, lo que permite que los contenedores con nombres similares no se dupliquen.
Usando la directiva nombre_contenedor, puede especificar el nombre del contenedor explícitamente, pero creo que esta es una función bastante inútil. Esto se discutirá con más detalle en las siguientes publicaciones.
Cree un segundo docker-compose.yml con el siguiente contenido:
docker-compose.yml para otros servicios version: '3.0' services: nginx: image: nginx environment: - VIRTUAL_HOST=site.local depends_on: - php volumes: - ./docker/nginx/conf.d/default.nginx:/etc/nginx/conf.d/default.conf - ./html/:/var/www/html/ networks: - frontend - backend php: build: context: ./docker/php volumes: - ./docker/php/php.ini:/usr/local/etc/php/php.ini - ./html/:/var/www/html/ networks: - backend mysql: image: mysql:5.7 volumes: - ./docker/mysql/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: root networks: - backend phpmyadmin: image: phpmyadmin/phpmyadmin:latest environment: - VIRTUAL_HOST=phpmyadmin.local - PMA_HOST=mysql - PMA_USER=root - PMA_PASSWORD=root networks: - frontend - backend networks: frontend: external: name: proxy_proxy backend:
¿Qué se anuncia aquí?
Se enumeran cuatro servicios: nginx, php, mysql y phpmyadmin. Y dos redes. Una red proxy, denominada frontend, se anuncia como una red externa y una nueva red interna de backend. El controlador para él no está especificado, como escribí anteriormente, se utilizará el controlador predeterminado del tipo de puente.
nginx
Todo debería quedar claro aquí. Usamos la imagen básica con el Docker Hub. La variable de entorno es necesaria para que el proxy funcione y le indica en qué dirección debe estar accesible el contenedor. La opción depend_on indica la dependencia de este contenedor en el contenedor php. Esto significa que el contenedor php se lanzará por adelantado, y luego se lanzará el contenedor nginx que depende de él. A continuación, reenviamos la configuración de nuestro nginx. Será un poco más bajo y montará la carpeta con html. También notamos que el contenedor tiene acceso a dos redes a la vez. Debe comunicar ambos proxies desde la red frontend y php desde la red back-end. En principio, sería posible insertar todos los contenedores en la misma red frontend, pero adhiero que tal separación es más correcta.
default.nginx server { listen 80; server_name_in_redirect off; access_log /var/log/nginx/host.access.log main; root /var/www/html/; location / { try_files $uri /index.php$is_args$args; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } location ~ /\.ht { deny all; } }
default.nginx es una configuración para nginx que se reenvía al contenedor. El punto clave aquí es la directiva
php fastcgi_pass: 9000 . Establece la dirección del servidor FastCGI. La dirección se puede especificar como nombre de dominio o dirección IP y puerto.
php: 9000 : el nombre del servicio es la dirección del servidor FastCGI. Nginx que accede a php recibirá la dirección IP del contenedor en el que se ejecuta php. El puerto 9000 es un puerto estándar, se declara al crear el contenedor base. Este puerto está disponible para nginx a través de la red, pero no está disponible en la máquina host, ya que no se reenvió.
php
Es inusual que una imagen no esté indicada. En cambio, construye su propia imagen directamente desde el archivo de redacción. La directiva de contexto apunta a la carpeta en la que se encuentra el Dockerfile.
Dockerfile FROM php:7.3.2-fpm RUN apt-get update && apt-get install -y \ libzip-dev \ zip \ && docker-php-ext-configure zip --with-libzip \ && docker-php-ext-install zip \ && docker-php-ext-install mysqli COPY --from=composer:latest /usr/bin/composer /usr/bin/composer WORKDIR /var/www/html
El Dockerfile establece que la compilación usa la imagen básica de php: 7.3.2-fpm, luego se ejecutan los comandos para instalar las extensiones de php. A continuación, el compositor se copia de otra imagen base y se establece el directorio de trabajo para el proyecto. Consideraré los problemas de ensamblaje con más detalle en otras publicaciones.
Además, el archivo php.ini y la carpeta html con nuestro proyecto se lanzan dentro del contenedor.
Tenga en cuenta que php se encuentra en la red de fondo y, por ejemplo, el proxy ya no puede acceder a él.
mysql
La imagen base de mysql se toma con la etiqueta 5.7, que es responsable de la versión de mysql. La carpeta ./docker/mysql/data se usa para almacenar archivos de base de datos (ni siquiera necesita crearla, se crea al inicio). Y a través de las variables de entorno, la contraseña se establece para el usuario root, también root.
La base de datos se encuentra en la red de back-end, lo que le permite mantenerse en contacto con php. La imagen base utiliza el puerto estándar 3306. Está disponible en la red acoplable para php, pero no está disponible en la máquina host. Si reenvía este puerto, puede conectarse a él, por ejemplo, desde el mismo PHPSTORM. Pero si la interfaz phpmyadmin es suficiente para usted, entonces no puede hacer esto.
phpmyadmin
La imagen oficial de phpmyadmin. Las variables de entorno usan VIRTUAL_HOST para interactuar con el proxy, similar a nginx. Acceso PMA_USER y PMA_PASSWORD a la base de datos. Y PMA_HOST la base de datos del host en sí. Pero esto no es localhost, como suele ser el caso, sino mysql. Es decir la comunicación con la base de datos está disponible por el nombre de su servicio, es decir mysql. El contenedor phpmyadmin puede comunicarse con la base de datos, ya que tiene una conexión a la red frontend.
Iniciamos los servicios con el comando habitual: docker-compose -d.
Vemos el siguiente resultado:
Lanzamiento de servicio Creating network "lesson2_backend" with the default driver Building php Step 1/4 : FROM php:7.3.2-fpm ---> 9343626a0f09 Step 2/4 : RUN apt-get update && apt-get install -y libzip-dev zip && docker-php-ext-configure zip --with-libzip && docker-php-ext-install zip && docker-php-ext-install mysqli ---> Using cache ---> 5e4687b5381f Step 3/4 : COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ---> Using cache ---> 81b9c665be08 Step 4/4 : WORKDIR /var/www/html ---> Using cache ---> 3fe8397e92e6 Successfully built 3fe8397e92e6 Successfully tagged lesson2_php:latest Pulling mysql (mysql:5.7)... 5.7: Pulling from library/mysql fc7181108d40: Already exists 787a24c80112: Already exists a08cb039d3cd: Already exists 4f7d35eb5394: Already exists 5aa21f895d95: Already exists a742e211b7a2: Already exists 0163805ad937: Already exists 62d0ebcbfc71: Pull complete 559856d01c93: Pull complete c849d5f46e83: Pull complete f114c210789a: Pull complete Digest: sha256:c3594c6528b31c6222ba426d836600abd45f554d078ef661d3c882604c70ad0a Status: Downloaded newer image for mysql:5.7 Creating lesson2_php_1 ... done Creating lesson2_mysql_1 ... done Creating lesson2_phpmyadmin_1 ... done Creating lesson2_nginx_1 ... done
Vemos que al principio se crea la red lesson2_backend, luego se ensambla la imagen php, luego se pueden descargar las imágenes que aún no están en el sistema (pull) y se inician los servicios descritos.
El toque final, para que todo funcione, esta adición a los hosts o sites.local y phpmyadmin.local dominios.
El contenido de index.php puede ser el siguiente:
Aquí comprobamos que la conexión de la extensión php - mysqli, que se agregó durante el ensamblaje del Dockerfile, es correcta.
Y tenga en cuenta que para la conexión con el contenedor, se utiliza el nombre del servicio: mysql.
La estructura de todo el proyecto fue la siguiente:
Estructura del proyecto habr/lesson2$ tree . ├── docker │ ├── mysql │ │ └── data │ ├── nginx │ │ └── conf.d │ │ └── default.nginx │ └── php │ ├── Dockerfile │ └── php.ini ├── docker-compose.yml ├── html │ └── index.php └── proxy └── docker-compose.yml