Primera Parte de mi Serie de Tutoriales Symfony, instalar Symfony y Docker. Llevo tiempo queriendo hacer algo de Symfony, si habéis trabajado en laravel o seguido alguno de nuestros tutoriales veréis que es muy similar.
Al final la serie de symfony tendrá un git compartido donde uniré todos los tutoriales que vaya sacando de Symfony.
Pre requisitos
- Algo de experiencia con Symfony, Twig, y ORMs (especificamente Doctrine, o conocer Laravel y Blade, veréis que cambia la forma de escribirlo, pero no la forma de hacerlo).
- Recomendamos tener conocimientos de Docker (como lo que es un contenedor, image, network, and service).
- Composer instalado globalmente.
- Docker Desktop.
- La herramienta Symfony CLI.
Empecemos con Docker
Volviendo al tema, vamos a desarrollar, usaremos docker porque así será mas sencillo de usar en cualquier máquina estos contenedores, que son entornos de ejecución pequeños y ligeros. Los contenedores hacen un uso compartido del kernel del sistema operativo subyacente, pero, por lo demás, se ejecutan de forma aislada unos de otros.
Al integrar Docker en tu proyecto Symfony, puedes estar seguro de que siempre que tu aplicación se esté ejecutando, el entorno y su configuración serán los mismos, independientemente de dónde esté implementada.
En este artículo, te mostraré cómo usar Docker con un proyecto Symfony. Nginx se utilizará como servidor web, PHP-FPM procesará las solicitudes PHP y MySQL será la base de datos completando el backend.
Doy por hecho que ya hemos creado nuestro directorio y tenemos la consola abierta y lista para empezar, usaremos docker compose ya que queremos instalar varios servicios:
mkdir symfony-test cd symfony-test touch docker-compose.yml
En nuestro archivo docker-compose.yml introducimos:
version: '3.8' services:
Los servicios son en realidad son los contenedores.
En las siguientes secciones, describiremos los contenedores para nuestra base de datos MySQL, PHP y el servidor web Nginx.
Definir el contenedor de la base de datos.
Para definir el contenedor de la base de datos, en docker-compose.yml, actualizaremos los servicios y añadiremos el contenedor para la base de datos:
services: database: container_name: database image: mysql:8.0 command: --default-authentication-plugin=caching_sha2_password environment: MYSQL_ROOT_PASSWORD: symfony MYSQL_DATABASE: symfony-test MYSQL_USER: symfony MYSQL_PASSWORD: symfony ports: - '4306:3306' volumes: - ./mysql:/var/lib/mysql
container_name establece el nombre del contenedor cuando se ejecuta, en lugar de que Docker Compose lo genere automáticamente.
image le permite a Docker saber a partir de qué imagen queremos construir el contenedor. En este caso, hemos especificado mysql:8.0 porque queremos usar la versión 8 de MySQL.
El comando especifica el complemento de autenticación que utilizará MySQL para autenticar a los usuarios. Usando environment, podemos especificar variables de entorno como el nombre, el usuario y la contraseña de la base de datos, así como la contraseña del usuario root.
Necesitamos un puerto para conectarnos a nuestra base de datos. Usando la clave de puertos, especificamos un puerto en nuestra máquina de desarrollo local y lo asignamos a un puerto en el contenedor que se usará para manejar las conexiones de la base de datos.
Finalmente especificamos el volume , en este caso, declaramos un volume para que nuestra base de datos no se pierda cuando los contenedores se destruyan o reconstruyan.
Definir el contenedor PHP
A diferencia del contenedor de base de datos, necesitamos especificar algunas instrucciones adicionales para configurar nuestro contenedor PHP. Para hacer esto, construiremos el contenedor PHP a partir de un Dockerfile. En el directorio raíz, symfony-test, crea un directorio llamado php. Luego, en symfony-test/php, crea un archivo llamado Dockerfile.
Nota: este archivo no tiene extensión.
mkdir php touch php/Dockerfile
Luego, el symfony-test/php/Dockerfile, deberá contener este código;
FROM php:8.2-fpm RUN apt update \ && apt install -y zlib1g-dev g++ git libicu-dev zip libzip-dev zip \ && docker-php-ext-install intl opcache pdo pdo_mysql \ && pecl install apcu \ && docker-php-ext-enable apcu \ && docker-php-ext-configure zip \ && docker-php-ext-install zip WORKDIR /var/www/symfony-test RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer RUN curl -sS https://get.symfony.com/cli/installer | bash
Aquí aparte de instalar la última versión de php, instalaremos las librerias de las que depende Symfony, el directorio donde estará nuestro contenedor, así como composer y Symfony CLI.
Ahora tenemos que añadirlo a nuestro docker-compose.yml justo después de la base de datos:
php: container_name: php build: context: ./php ports: - '9000:9000' volumes: - ./app:/var/www/symfony-test depends_on: - database
Este contenedor es diferente al de la base de datos, en vez de una imagen especificamos un «contexto» en el que basarse, que es nuestro Dockerfile, mapeamos puertos y volumen donde se ejecutará nuestra aplicación y dependencia de la base de datos, indicando a docker que genere la base de datos antes del contenedor de PHP.
No nos olvidemos de crear la carpeta app dentro de la raíz de symfony-test que es donde crearemos nuestra app de Symfony:
mkdir app
Definir el contenedor Nginx
Antes de construir el contenedor Nginx, tenemos que hacer la configuración predeterminada para el servidor. En la raíz de symfony-test, crearemos un un directorio llamado nginx y dentro un archivo default.conf para contener nuestra configuración usando el siguiente comandos.
mkdir -p nginx/default.conf
y dentor de default.conf
server { listen 80; index index.php; server_name localhost; root /var/www/symfony-test/public; error_log /var/log/nginx/project_error.log; access_log /var/log/nginx/project_access.log; location / { try_files $uri /index.php$is_args$args; } location ~ ^/index\\.php(/|$) { fastcgi_pass php:9000; fastcgi_split_path_info ^(.+\\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_busy_buffers_size 256k; internal; } location ~ \\.php$ { return 404; } }
y ahora terminamos nuestro docker-compose.yml y debería quedar así:
version: '3.8' services: database: container_name: database image: mysql:8.0 command: --default-authentication-plugin=caching_sha2_password environment: MYSQL_ROOT_PASSWORD: symfony MYSQL_DATABASE: symfony-test MYSQL_USER: symfony MYSQL_PASSWORD: symfony ports: - '4306:3306' volumes: - ./mysql:/var/lib/mysql php: container_name: php build: context: ./php ports: - '9000:9000' volumes: - ./app:/var/www/symfony-test depends_on: - database nginx: container_name: nginx image: nginx:stable-alpine ports: - '8080:80' volumes: - ./app:/var/www/symfony-test - ./nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php - database
Construir los contenedores
Una vez implementado todo esto, finalmente podemos construir nuestros contenedores ejecutando el siguiente comando.
docker compose up -d --build
Cuando termine de compilar debería saliros algo así como a mí:
Y si abrimos nuestro Docker Desktop deberíamos ver los contenedores funcionando:
Crear una aplicación Symfony
Tenemos 2 maneras de hacerlo, ya que hemos hecho que app sea una carpeta permanente, podemos usar Symfony CLI para crearla ahí directamente o ejecutar el CLI dentro del contenedor de docker
symfony new app
o si es dentro del contenedor:
symfony new .
Con la aplicación creada, puedes ir a http://localhost:8080/ y verás la página predeterminada de Symfony, te dejo un ejemplo justo debajo, además, si lo has creado desde docker verás dentro de app/ que persiste todo el proyecto.
Con esto os dejamos y continuaremos en la segunda parte de la Serie Symfony.
El código final lo pondremos en https://github.com/trecenode/symfony-test