Slim PHP en Docker

slim php en docker

Hace un par de años me tocó trabajar en un servicio de API con Slim PHP con su versión 3, creo. Me gustó bastante, incluso hicimos una versión muy primitiva de un multi-tenancy para facturar, ya que cada usuario tenía sus propia base de datos. Hacía ya rato que no podía nada de PHP, ahora veremos como hacer funcionar Slim PHP en Docker.

Ahora se ha presentado de nuevo otro proyecto en donde usaremos Slim PHP, junto con Eloquent, que es el ORM de Laravel. Solo que en este post solo veremos la instalación de Slim, ya veré si me dan los tiempos para hacer uno integrando esto.

¡Manos a la obra!

Primero, vamos a crear el directorio donde haremos nuestra instalación y configuración de los contenedores:

mkdir slim4 && cd slim4

En este directorio estarán el código fuente y los directorios con la configuración de cada container.

PHP

Primero vamos a hacer la configuración de PHP e instalar sus dependencias.

Primero crearemos el Dockerfile dentro del directorio php:

mkdir php

touch php/Dockerfile

El contenido es el siguiente:

FROM php:8.1-fpm

RUN apt update \
    && apt install -y zlib1g-dev g++ git libicu-dev zip libzip-dev zip libpq-dev \
    && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
    && docker-php-ext-install intl opcache pdo pdo_pgsql \
    && pecl install apcu \
    && docker-php-ext-enable apcu \
    && docker-php-ext-configure zip \
    && docker-php-ext-install zip

WORKDIR /var/www/slim_app

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN git config --global user.email "<tu_usuario>@<example.com>" \
    && git config --global user.name "<Juanito Perez>"

Estos paquetes que se instalan son base y deberías considerar esta lista en caso de usar ciertas librerías o activar módulos, por ejemplo, si voy a trabajar con MySQL, PostgreSQL o necesito algo para procesar imágenes, etc. De cualquier manera vamos a montar el volumen local, así puedes eliminar la imagen y volver a generarla con las nuevas dependencias.

En términos generales, lo que hace esto es instalar dependencias generales para Slim, establecemos el directorio de trabajo en /var/www/slim_app y al final ¡muy importante! instalamos composer para luego hacer la instalación de Slim.

Nginx

Ya con PHP listo, ahora nos queda conectarlo con el servidor. Para esto usaremos nginx.

A este contenedor básicamente lo dejaremos tal cual la imagen viene del hub de Docker.

Solo montaremos un volumen y haremos el map del puerto donde está corriendo PHP (ahorita vemos):

mkdir -p nginx

touch nginx/default.conf

El archivo default.conf será el encargado de controlar la conexión con el contenedor de PHP.

server {

    listen 80;
    index index.php;
    server_name localhost;
    root /var/www/slim_app/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;
    }
}

Vemos que fastcgi_pass lee la instancia de php en el puerto 9000. Hay que recordar que nginx nos puede funcionar con un reverse proxy.

Docker-compose

Una vez configurados los dos containers, nos queda levantarlos con docker-compose.

Creamos el archivo docker-compose.yml:

version: "3.8"

services:
  php:
    container_name: slim_php
    build:
      context: ./php
    ports:
      - '9000:9000'
    volumes:
      - ./code:/var/www/slim_app

  nginx:
    container_name: slim_nginx
    image: nginx:stable-alpine
    ports:
      - '8080:80'
    volumes:
      - ./code:/var/www/slim_app
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php

Puntos clave:

  • Tenemos dos servicios: php y nginx
  • Se crean dos contenedores: slim_phpp y slim_nginx.
  • Se crean dos volúmenes, uno para php y otro para el archivo de configuración de nginx.
  • Para construir la imagen de PHP, usamos el servicio php, que a su vez necesita el archivo php/Dockerfile para generar la imagen base.
  • php usa el puerto 9000 que es el que dijimos que nginx usa para el reverse proxy.
  • En nginx exponemos el puerto 8080.

Crear los contenedores

Una vez que se han hecho las configuraciones, podemos ejecutar docker-compose:

docker-compose up --build

Este va a generar las imágenes y contenedores y levantará los servicios para poder acceder al puerto 8080 en localhost.

Instalar Slim PHP

Aquí seguiremos el manual oficial en https://www.slimframework.com/docs/v4/start/installation.html.

Previamente en el Dockerfile de la imagen de php, instalamos la herramienta composer que es la que nos ayudará.

Iremos a nuestro container y entraremos por bash a la imagen.

docker exec -it <container> bash 

Instalamos slim:

composer require slim/slim:"4.*"

Luego instalamos la implementación de “PSR-7”:

composer require slim/psr7 --with-all-dependencies

composer require nyholm/psr7 nyholm/psr7-server

composer require guzzlehttp/psr7 "^2"

composer require guzzlehttp/psr7 "^1"

composer require sapphirecat/slim4-http-interop-adapter

composer require laminas/laminas-diactoros

Ahora, con esto ya deberíamos poder comenzar a crear código.

Slim funciona bajo el directorio public, así que aquí colocaremos nuestro archivo index.php.

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/', function (Request $request, Response $response, $args) {
    $response->getBody()->write('{"mensaje": "Hello, Mundo!"}');
    return $response
                ->withHeader('Content-Type', 'application/json')
                ->withStatus(201);
});

$app->run();

Si vamos al navegador y entramos a http://localhost:8080 veremos nuestro mensaje en JSON.

curl http://localhost:8080

{"mensaje": "Hello, Mundo!"}

Los créditos son para el usuario de este post en dev.to, solo hice algunos cambios a mi docker-compose.yml y agregué la parte del “hello world” en Slim.

Espero que les haya servidor este manual para instalar Slim PHP en Docker.

Gracias por leer.


Posted

in

, , , , ,

by