Apuntes de Kirby
  • 👀whoami
  • 🦉Redes
    • Introducción Redes
      • Organizaciones
      • Historia
      • Puntos de conexión
      • Métodos de acceso a la red
    • Clasificación de las redes
    • Topología de las red
    • Direccionamiento IP
      • IPv4
        • Subredes IPv4
        • Superredes IPv4
        • VLSM
      • IPv6
      • MAC
      • NAT
    • Enrutamiento estático
    • Enrutamiento dinámico
      • RIPv1 & RIPv2
      • Tablas de enrutamiento
      • 🚧Redes conmutadas
    • CML
      • 🚧1er CML lab
    • CISCO
      • ¿Qué son las VLAN?
        • Ejemplo 1 de VLAN
        • Ejemplo 2 de VLAN
      • Acceso y password
      • NAT / PAT
    • Firewalls
      • Tipos de firewalls
      • ZPF
        • Funcionamiento
        • Configurando un ZPF
      • Sophos Firewall XG
        • Sophos home
        • Aprendiendo a usar Sophos
      • pfSense
        • Instalando pfSense
        • OpenVPN en pfSense
        • Port Forward
        • Alias
    • Proxy
      • Squid en pfSense
        • Squid Proxy Server
        • SquidGuard Proxy
      • Proxy reverse Nginx
    • 🚧Suricata
  • 🐝Servicios
    • Servidores Web
      • Nginx
        • NGINX, hosts virtuales
        • Hosts virtuales basados en dominio
        • PHP-FPM
        • Nginx: PHP y MySQL
          • MySQLi - PHP
        • En Alpine linux
        • 🚧Proxy
    • Servidores de correo
      • Seguridad en el correo
      • Postfix
      • hMailServer
      • Clientes de correo
        • Mailutils
        • Mutt
    • Servidores de FTP
      • FileZilla
      • VSFTPD
      • FTP vía IIS
    • Servidores DNS
      • DNS - Windows Server 2016
      • DNS - Ubuntu Server 22.04
      • Systemd
    • Servidores DHCP
      • DHCP-Windows Server 2016
      • DHCP-Ubuntu Server 22.04
    • Servidores MySQL
    • 🚧Mensajería instantánea
      • Ejabberd
    • 🚧Imágenes - Vídeos
      • FFMPEG + YT-DLP
      • Plex
      • Jellyfin
      • Plesk
      • RTMP
      • SRT
    • Webmin + Virtualmin
  • NextCloud
  • 🔑Seguridad
    • NAS
      • Instalación Synology NAS en VirtualBox
        • Creación de volúmenes y su uso
        • Actualización Synology NAS
        • Creación de usuarios y carpetas compartidas
        • Funciones del panel de control
          • Acceso por SSH
          • Configuración de los servicios de archivos
          • Configuración de red
          • Copias de seguridad (restauración)
          • Seguridad
          • Personalizar páginas de inicio
          • Servicio de notificaciones
        • Centro de paquetes Synology
          • Servidores multimedia
          • Paquetes de utilidades
          • Cloud Sync
          • Hyper Backup
          • Synology Office
      • Truenas
        • Rsync en Truenas
      • OpenmediaVault
    • Backups
      • Rsync
        • Ejemplo de rsync
    • ¿Qué son las ACL?
    • SOPS/AGE
    • RAID
      • mdadm
  • 🐳Virtualización
    • Proxmox
      • Instalar en VMWare
      • Instalar en VirtualBox
      • Entorno Proxmox
      • Almacenamiento local
      • Añadir discos
      • Clonar
      • Qemu agent
      • Linux container - LXC
      • Clúster
      • Red Interna
      • 🚧Proxmox Backup
      • 🚧Otras consideraciones
    • Alpine Linux
    • Contenedores
      • Docker
        • YAML
        • Instalando Docker
        • Portainer
          • Instalando Portainer
          • Dentro de Portainer
        • Docker volumen
        • Docker compose
          • Docker: PHP y MySQL
          • Importar sitio web en Docker
          • Instalando Wordpress
      • Pi-hole
        • Instalando Pi-hole en Docker
        • Instalando Pi-hole en Debian
        • RDP
          • RDP - Docker
  • 🐞Misceláneas
    • Datos - codificación
    • IPTables
    • Túnel con Cloudflare
    • Servidor de video
    • Comandos de Linux
    • Anaconda & Spyder
    • CGI - NGINX
    • Arduino
      • Capítulo 0 Blink
      • Capítulo 1 Led
      • Capítulo 2 Botton & LED
  • ⁉️Interesante
    • Curioso
    • Ideas
Powered by GitBook
On this page
  • Directorios - volúmenes
  • Archivos de configuración
  • Creando el docker-compose desde Portainer
  • Links

Was this helpful?

Edit on GitHub
  1. Virtualización
  2. Contenedores
  3. Docker
  4. Docker compose

Docker: PHP y MySQL

docker-compose

PreviousDocker composeNextImportar sitio web en Docker

Last updated 4 months ago

Was this helpful?

Utilizaremos a modo de ejemplo la creación de varios contenedores relacionados entre sí, para levantar un sitio web programado con PHP, que se conecta a una DB en MySQL. De hecho, voy a utilizar una actividad llamada LoginRegister realizada en 1º año de Asix. Para ello necesitamos los servicios activos de:

  • Apache o Nginx para levantar el servicio web

  • MySql para la base de datos

  • PHP para el lenguaje de programación

  • Phpmyadmin, si me quiero conectar a un gestor de DB.

Veamos cómo levantar un docker-compose creando un archivo de configuración docker-compose.yml, dado que el docker-compose busca, por defecto, las instrucciones en el archivo docker-compose.yml.

Adicionalmente, tengamos en cuenta que docker lo tengo instalado en una VM con Ubuntu Desktop 22.04 LTS con Portainer y Docker-compose.

Directorios - volúmenes

Como vamos a crear los volúmenes de Docker para tener acceso directo a los contenidos en local, tenemos que crear los directorios y los contenidos necesarios. Los archivos importantes a tener en cuenta serían los ficheros de configuración de nginx y los .php de la aplicación web. Para ello, he creado un directorio con los contenidos necesarios:

Directorio

Contenido

LoginRegister

La aplicación web con sus archivos .php, .css, etc.

DB

La DB users1 que utiliza la aplicación web. Realmente no es necesario, lo hago por comodidad.

log

Para almacenar los log de nginx (error, access) y de php.

Nginx/conf.d

En este directorio guardamos el archivo de configuración: default.conf

La actividad LoginRegister tiene una estructura de archivos como se muestra en la imagen siguiente. Tener en cuenta que el directorio mysql no es necesario.

Archivos de configuración

Tenemos que preparar dos archivos de configuración:

  • default.conf

  • docker-compose.yml

Default.conf

En este archivo tenemos las siguientes directivas:

Listen - define qué dirección IP y qué puertos escucha el servicio. En este caso, Nginx escucha en el puerto 80 en todas las direcciones IPv4 e IPv6. Si establecemos el parámetro default_server le indicamos a Nginx que utilice este bloque server por defecto para las peticiones que coincidan con las direcciones IP y los puertos.

server_name - define los nombres de host de los que es responsable este bloque server. Establecer server_name a _ permite configurar Nginx para aceptar cualquier nombre de host para este bloque server.

root - establece la ruta del contenido web para este bloque server.

log - También hemos configurado los archivos para los log files, que utilizaremos también dentro de los volúmenes de docker.

Aquí dejo como ejemplo el archivo que he utilizado:

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    
    ## define root path
    root /var/www/html;
    
    ## define location php
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app: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 / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

Docker-compose.yml

Del mismo modo que existen los Dockerfile, donde se puede configurar el estado de un contenedor de manera declarativa, en docker-compose existe el equivalente: los archivos .yml.

Por tanto, un archivo de docker-compose es un archivo con extensión y formato yml. Para usarlo basta con crearlo y empezar a agregar el contenido.

El archivo tiene una estructura bastante fácil de entender. Comienza por especificar la versión de docker compose que se utilizará:

Después de la versión viene la sección de servicios. Puede haber tantos servicios como queramos: servidor web, base de datos, documentación, etc. Cada servicio cuenta con sus propias variables de configuración y sus respectivos valores.

version 3.8: Es muy importante indicar la versión de las instrucciones que vamos a utilizar. Docker evoluciona, pero siempre hay compatibilidad con las versiones anteriores.

app: Indica el nombre del servicio, que podría ser cualquiera. El nombre indica el tipo de servicio que estamos construyendo. Por ejemplo: MySQL, Nginx, etc.

Nombres de servicios: El nombre que usamos para cada servicio dentro de nuestro archivo yml nos sirve como referencia para su uso en otros servicios.

Por ejemplo, si llamamos a un servicio como db, entonces es db el nombre que debemos usar en otras aplicaciones para referirnos a un host o ubicación, incluso una base de datos. Veamos algunas de las variables de configuración (que se pueden consultar en documentación oficial de Docker).

image: establece la imagen a partir de la cual se generará el servicio, ideal cuando el servicio no necesita de una personalización muy complicada.

build: si necesitamos una imagen personalizada pudiera ser mejor usar un Dockerfile. La opción build nos permite indicar el directorio donde se encuentra. Indica dónde está el Dockerfile a utilizar para crear el contenedor. Si escribimos build . se considera que el Dockerfile está en el directorio actual.

command: sobre escribe el comando predeterminado del contenedor. Esta opción es ideal para ejecutar un comando cuando inicia un servicio, por ejemplo, un servidor web.

ports: nos dice los puertos externos e internos que se vincularán, siempre en el formato de host:contenedor. También podemos especificar los protocolos udp o tcp.

expose: también expone puertos. La diferencia con el comando ports es que los puertos solo estarán disponibles para los servicios vinculados, no para la máquina desde donde estamos ejecutando docker-compose.

depends_on: Si queremos que uno de nuestros servicios se ejecute después de otro. Por ejemplo, para que un servidor web funcione correctamente es necesario tener una base de datos que ya se encuentre en funcionamiento.

Por si no recuerdas lo que son las variables de entorno

Tanto Windows, Linux como Mac utilizan ciertos valores para almacenar información que pueden variar de un equipo a otro o de un usuario a otro. Son valores que hacen referencia a archivos, directorios y funciones comunes del sistema cuya ruta concreta puede variar, pero que otros programas necesitan poder conocer.

Un ejemplo de este tipo de variable puede ser:

  • la ubicación de un archivo en el sistema,

  • una lista de objetos, número de versión

Algunas de las variables de entorno más comunes son:

PATH: es la lista de directorios donde la Shell o intérprete busca los comandos.

PWD: nos muestra el directorio actual.

RANDOM: tiene la función de generar un número aleatorio.

HOSTNAME: nombre del sistema.

MACHTYPE: arquitectura del sistema.

HISTFILE: fichero donde se guarda la historia de comandos.

HOME: directorio home del usuario.

volumes: Se puede enviar partes de nuestro S.O a un servicio usando uno o varios volúmenes. Para esto usamos la sintaxis host:contenedor, donde Host puede ser una ubicación en tu sistema o también el nombre de un volumen que hayas creado con docker. Hace un mapeo entre el directorio del host y el directorio del contenedor. De este modo, cualquier cambio en el directorio local en el host, se hará de inmediato en el contenedor.

restart : Podemos aplicar políticas de reinicio a nuestros servicios. Puede tomar varios valores:

  • no: nunca reinicia el contenedor

  • always: siempre lo reinicia

  • on-failure: lo reinicia si el contenedor devuelve un estado de error

  • unless-stopped: lo reinicia en todos los casos excepto cuando se detiene

A continuación, un ejemplo del archivo docker-compose.yml que he utilizado:

# archivo docker-compose.yml

version: "3.8"
services:

  # PHP service
  app:
    image: php:8-fpm
    container_name: miAppPHP    
    volumes:
      - LoginRegister:/var/www/loginregister/
      - LoginRegister/log/php.log:/var/log/fpm-php.www.log
    networks:
      - app-network
  # MySQL database service
  db:
    image: mysql:8.0
    container_name: miAppMySQL
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 1234
    volumes:
      - LoginRegister/mysql/:/var/lib/mysql
      - LoginRegister/DB/:/DB/
    networks:
      - app-network

  # PHPMYADMIN
  phpmyadmin:
    image: phpmyadmin
    container_name: miAppPhpMyAdmin
    working_dir: /
    environment:
      PMA_ARBITRARY: 1      
    ports:
      - 8080:80
    networks:
      - app-network

  # Nginx service
  nginx:
    image: nginx
    container_name: miAppNginx
    ports:
      - 88:80
    volumes:
      - LoginRegister:/var/www/loginregister/
      - LoginRegister/nginx/conf.d:/etc/nginx/conf.d/
      - LoginRegister/log/nginx:/var/log/nginx/
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

Como podemos ver tenemos que utilizar la imagen de PHP, FPM - FastCGI Process Manager que es una implementación alternativa al PHP FastCGI con algunas características adicionales (la mayoría) útiles para sitios web con mucho tráfico.

Un par de características que posee:

  • Manejo avanzado para detener/arrancar procesos de forma fácil.

  • Posibilidad de iniciar hilos de procesos con diferentes uid/gid/chroot/environment, escuchar en diferentes puertos y usar distintos php.ini (remplazando).

Dentro de MySQL

En caso de tener que instalar directamente la DB podemos hacer lo siguiente, dentro del propio contenedor:

Acceder al mysql para crear y copiar la DB:

mysql –p –u root

Crear la DB:

mysql> create database users1;

Copiar la DB users.sql en la DB creada users1:

mysql -p -u root --password=1234 users1 < users.sql 

Algunos comandos básicos de MySQL:

use Database users;
show tables;
describe users;
select * from users1.users;

Creando el docker-compose desde Portainer

Ahora es que estamos en condiciones de crear nuestro docker-compose. Para ello nos vamos a Portainer.

Nos vamos a la herramienta stacks de Portainer, donde podremos crear nuestra "composición" de servicios. Recordemos que un stack es una colección de servicios que están relacionados con una aplicación, como por ejemplo, WordPress que incluye un contenedor de servidor web (como nginx o apache) y un contenedor de base de datos como MySQL.

Una vez en el apartado vamos a crear un nuevo stack:

Se nos abrirá una nueva página donde podemos aplicar diferentes opciones para crear una colección entre las que tenemos subir nuestro docker-compose.yml, usar un repositorio de git. Aquí utilizaremos el editor web:

En el editor web volcamos el contenido de nuestro archivo docker-compose.yml previamente creado. En caso de tener algún aparecerá una notificación en rojo que nos impedirá continuar

Una vez hecho esto, clicamos a deploy para crear y desplegar todos los contenedores. Si todo está correcto, nos crea la colección y podremos acceder a la misma y veremos algo como lo siguiente:

Podemos observar los diferentes contenedores involucrados en desplegar la aplicación web:

  • miAppPHP - es el contenedor de php

  • miAppPhpMyAdmin - el contenedor para el gestor de bases de datos

  • miAppNginx - el servidor web

  • miAppMySQL - La base de datos

Accediendo a PhpMyAdmin

Accediendo a la web

Links

environment: Permite establecer una lista de que estarán disponibles en nuestro servicio.

BASH_VERSION: versión de que estemos utilizando.

***

🐳
variables de entorno
Bash
https://docs.docker.com/compose/compose-file/build/
https://www.docker.com/blog/how-to-use-the-apache-httpd-docker-official-image/
https://academy.leewayweb.com/como-usar-docker-en-proyectos-php/
https://www.kodetop.com/crea-tu-ambiente-de-desarrollo-php-mysql-con-docker/
https://hub.docker.com/_/php/tags
https://access.redhat.com/documentation/es-es/red_hat_enterprise_linux/8/html/deploying_different_types_of_servers/setting-apache-http-server_deploying-different-types-of-servers
https://www.php.net/manual/es/install.fpm.php
https://docs.portainer.io/user/docker/stacks
Estructura de archivos .php de la aplicación web
Estructura de un archivo docker-compose.yml
En Portainer
Creamos un nuevo stack
Stack en Portainer
docker-compose.yml para crear el stack
Despliegue de contenedores
Accediendo a la base de datos en Phpmyadmin
El sitio web de prueba