Docker y symfony

Lo primero sería explicar brevemente que es Docker y porqué puede ser útil emplearlo en tus proyectos de Symfony (u otros) y luego pasaremos a crear un entorno completamente funcional empleando ambos paquetes. Vamos allá:

Docker es un paquete de software que te permite crear un sistema de ficheros independiente que contiene todo lo que necesitas para tener: código, herramientas y librerías del sistema y código en ejecución.

Esto parece un poco como tener una virtualización de un sistema operativo y ciertamente es algo similar pero Docker es un contenedor que necesita muchos menos recursos comparado con un completo sistema virtualizado. Esto te permite tener en equipos modestos diversos contenedores ejecutandose al mismo tiempo lo que a su vez facilita el escalado de tus aplicaciones de una manera muy sencilla y eficaz simplemente generando nuevos contenedores.

Docker también te permite resolver el problema de “en mi máquina funciona” pues cada desarrollador tendrá su propio contenedor que es una copia del contenedor o contenedores de otros entornos (test, producción)

Vayamos a la parte práctica e intentemos generar un entorno con symfony en docker. Para ello presupongo que estas trabajando en GNU-linux y ya tienes instalado docker en tu sistema. Si no es así vete a la página de Docker para saber como instalarlo.

Lo primero sería crear un máquina virtual linux:

$ docker-machine create symfony-project

Así creamos una nueva máquina virtual a la que hemos llamado symfony-project

Para conectarte a la máquina recién creada debes introducir:

$ eval $(docker-machine env symfony-project)

Para ver las máquinas que tienes en ejecución y comprobar que la que acabamos de crear está funcionando basta ejecutar:

$ docker-machine ls

Ahora comencemos con symfony creando un instalación nueva

 

$ symfony new symfony-docker

Cuando esté instalada entramos en el directorio y creamos un nuevo fichero docker-composer.yml

$ cd symfony-docker

$ touch docker-compose.yml

En nuestro nuevo entorno además de Symfony tendremos que instalar otras aplicaciones como php y un servidor web como nginx

Todas estas aplicaciones deberían proceder del hub de Docker que son contenedores ya creados y mantenidos con estas aplicaciones.

Ahora edita tu docker-compose.yml e introduce las siguientes líneas:

nginx:
  image: nginx:latest
  ports:
    - "8080:80"

php:
  image: php:7.0-fpm

 

Ahora ejecuta

$ docker-compose up -d

para inicializar los contenedores

Ejecuta

$ docker-compose ps

Para verificar que está funcionando. Ahora para conectarte a la máquina habría que saber su ip con:

$ docker-machine ip symfony-project

En mi caso es 192.168.99.100 así que para conectarte al nginx habría que conectarse a http://192.168.99.100:8080/

Ahora habría que configurar nginx para que apunte a nuestra aplicación symfony. Para ello tenemos que crear el fichero Dockerfile

Dockerfile representa cada paso que se ha de llevar a cabo una vez que el contenedor esté listo para usar. Normalmente usariamos una herramienta como puppet, ansible o chef  para hacer esto pero en Docker se emplea el fichero Dockerfile.

 

Para ello creamos la carpeta docker/nginx/

$ mkdir -p docker/nginx

y aquí creamos el fichero Dockerfile con el siguiente contenido

$ vi docker/nginx/Dockerfile

FROM nginx:latest
 
COPY symfony3.conf /etc/nginx/conf.d/symfony3.conf

Además creamos el fichero symfony3.conf con la configuración de nginx para symfony

$ vi docker/nginx/symfony3.conf

server {
    server_name symfony3.dev www.symfony3.dev;
    root /app/web;
 
    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
    }
    # DEV
    # This rule should only be placed on your development environment
    # In production, don't include this and don't deploy app_dev.php or config.php
    location ~ ^/(app_dev|config)\.php(/|$) {
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }
    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        # When you are using symlinks to link the document root to the
        # current version of your application, you should pass the real
        # application path instead of the path to the symlink to PHP
        # FPM.
        # Otherwise, PHP's OPcache may not properly detect changes to
        # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
        # for more information).
        fastcgi_param  SCRIPT_FILENAME  $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        # Prevents URIs that include the front controller. This will 404:
        # http://symfony3.dev/app.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }
}

Además necesitamos añadir el siguiente registro en nuestro fichero local /etc/hosts :

$ sudo vi /etc/hosts

192.168.99.100 symfony3.dev

Recuerda que la ip que pones aquí es la que has obtenido mediante la ejecución de:

$ docker-machine ip symfony-project

 

Con estos cambios actualizamos el docker-compose.yml:

nginx:
  build: docker/nginx
  ports:
    - "8080:80"
  links:
    - php
  volumes:
    - ./:/app
 
php:
  image: php:7.0-fpm
  volumes:
    - ./:/app
  working_dir: /app

 

Ahora para aplicar los cambios debemos detener los contenedores y construirlos de nuevo con estas modificaciones para ello:

$ dockercompose stop
$ dockercompose build
Ahora iniciamos de nuevo los contenedores con:
dockercompose up d
Ahora podemos acceder a nuestra instalación de symfony en la máquina a través de http://symfony3.dev:8080/app_dev.php
Con pequeñas modificaciones puedes aplicar este entorno dockerizado para symfony4