En las entradas anteriores he descrito los problemas -tanto conceptuales como técnicos- que he encontrado al intentar llevar Dokuwiki a un contenedor.
En este artículo explico los pasos a seguir para construir una imagen con Caddy server y PHP, de manera que puedas servir tus aplicaciones PHP usando contenedores.
Me voy a centrar primero en la creación de una imagen para un equipo con arquitectura x64 y después para una Raspberry Pi (o cualquier otro dispositivo ARM).
Todos los ficheros están disponibles en el repositorio onthedock/alpine-caddy-php
El fichero Dockerfile
FROM alpine:3.6
RUN apk add --no-cache caddy php7 php7-fpm php7-gd \
php7-session php7-xml php7-openssl php7-zlib
RUN echo "clear_env = no" >> /etc/php7/php7-fpm.conf
RUN chown -R caddy:caddy /var/www /var/log
WORKDIR /var/www
COPY files/Caddyfile /etc/Caddyfile
COPY files/index.html /var/www
COPY files/phpinfo.php /var/www
EXPOSE 2015
USER caddy
ENTRYPOINT ["/usr/sbin/caddy"]
CMD ["--conf", "/etc/Caddyfile"]
FROM alpine:3: indica la imagen base que usaremos para construir nuestra imagen.RUN apk add ...comando de instalación de Caddy, PHP7 y las librerías que necesitemos. Para mantener al mínimo el número de librerías, deberías realizar un estudio para cada una de las aplicaciones con las que querrás usar esta imagen para poder incluir todas las que necesitarás. En mi caso, el listado incluye las que he identificado para Dokuwiki.RUN echo "clear_env = no" >> /etc/php7/php7-fpm.conPermite que PHP-FPM pueda acceder a las variables de entorno.RUN chown -R caddy:caddy /var/www /var/logModificación de los permisos para las carpetas a las que Caddy Server tiene que acceder (usando el usuariocaddy).- El usuario y el grupo
caddyse crean durante la instalación del paquete de Caddy Server.
- El usuario y el grupo
WORKDIR /var/wwwSe cambia el directorio de trabajo a la carpeta/var/www. Caddy Server sirve la carpeta actual si no se especifica ninguna en el ficheroCaddyfile. Puede omitirse delDockerfilesi se especifica en elCaddyfile.COPY files/Caddyfile /etc/CaddyfileCopia el fichero de configuración de Caddy a contenedor.COPY files/index.html /var/wwwyCOPY files/phpinfo.php /var/wwwEl ficheroindex.htmles el típico fichero indicando que el servidor funciona. En cuanto aphpinfo.php, permite validar que PHP funciona; también muestra qué versión se ha instalado y las librerías incluídas. Sólo se muestran si no se monta un volumen sobre/var/www.EXPOSE 2015El puerto por defecto de Caddy es el 2015, y no el 80 como es habitual en otros servidores web.USER caddyNos deshacemos de los privilegios derooty cambiamos al usuariocaddy(siguiendo las buenas prácticas de seguridad).ENTRYPOINT ["/usr/sbin/caddy"]Especificamos el comando por defecto al ejecutar el contenedor.CMD ["--conf", "/etc/Caddyfile"]Especificamos el fichero de configuración como un parámetro durante el lanzamiento, por lo que es posible pasar un fichero alternativo u otros parámetros desdedocker run.
Fichero Caddyfile
0.0.0.0
root /var/www/
gzip
startup php-fpm7
fastcgi / 127.0.0.1:9000 php {
index index.php
}
log stdout
errors stdout
0.0.0.0Indica en qué dirección IP escucha el servidor; indicamos todas las existentes. Ésta es la opción por defecto desde este commit: Default host is now 0.0.0.0 (wildcard), después de ver que es más docker friendly.root /var/wwwroot indica cuál es la raíz del site para Caddy.gzipHabilita la compresión si el cliente lo soporta. Ver gzip docstartup php-fpmstartup ejecuta un comando cuando Caddy arranca. En este caso, arrancaphp-fpmpara que se procesen las páginas con código PHP.fastcgi / 127.0.0.1:9000 php {...}fastcgi hace de intermediario (proxy) y pasa las peticiones a la ruta indicada a PHP (en este caso).log stdoutyerrors stdoutredirigen la salida de los logs y de los errores haciastdout. Esto permite que Docker muestre los logs (y los errores) mediantedocker logs.
Cómo usar la imagen para servir Dokuwiki en un contenedor
Puedes lanzar un contenedor vacío para verificar que la configuración de Caddy y PHP es correcta. Si no montas ningún volumen, Caddy servirá el fichero index.html que hemos copiado en la imagen. En el fichero de bienvenida hay un enlace que llama a phpinfo.php, que muestra la salida del comando phpinfo().
Por ejemplo:
docker run --rm -d --name test -p 8911:2015 xaviaznar/alpine-caddy-php
Caddy+PHP para Dokuwiki
Para usar la imagen con Dokuwiki:
- Creo una carpeta en el host llamada
/shared/wiki/www, donde wiki es el nombre del contenedor (esto es sólo por tener organizados los volúmenes compartidos entre host y contenedor). - Descargo Dokuwiki y lo descomprimo en esta carpeta.
- Asigno permisos a todo el mundo sobre la carpeta del
wwwy sus subcarpetas. Esto es necesario porque el usuariocaddyen el contenedor no existe en el hostsudo chmod -R 777 /shared/wiki/www - Monto la carpeta en el contenedor mediante:
docker run -d --name wiki -p 8001:2015 -v /shared/wiki/www:/var/www xaviaznar/alpine-caddy-php
Errores
Si al intentar acceder a la URL obtienes una página en blanco o un error 404, revisa los logs mediante docker logs wiki.
Si observas errores del tipo [ERROR 0 /index.php] Primary script unknow, lo más probable es que se trate de un problema de permisos sobre la carpeta /shared/wiki/www/.
Otro indicador de que puede haber problemas de acceso a alguna de las subcarpetas del Dokuwiki es:
Para solucionarlo, ejecuta:
sudo chown -R 777 /shared/wiki/www
Si todo está correctamente configurado, pulsando el enlace run the installer podrás configurar tu nuevo wiki:
Versión para Raspberry Pi
La única diferencia para contruir la imagen para Raspberry Pi consiste en modificar la imagen base. ARM32v6 y ARM32v7 ofrecen versiones semioficiales de algunas imágenes; en particular, para Alpine Linux.
Si tu aplicación PHP va a ejecutarse en una Raspberry Pi “1”, debes usar la imagen arm32v6/alpine mientras que para Raspberry Pi 2 y 3 debes usar arm32v7/alpine.
Modifica el fichero Dockerfile según convenga:
FROM arm32v6/alpine:3.6 # Para RPi 1
FROM arm32v7/alpine:3.6 # Para RPi 2,3