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.con
Permite que PHP-FPM pueda acceder a las variables de entorno.RUN chown -R caddy:caddy /var/www /var/log
Modificación de los permisos para las carpetas a las que Caddy Server tiene que acceder (usando el usuariocaddy
).- El usuario y el grupo
caddy
se crean durante la instalación del paquete de Caddy Server.
- El usuario y el grupo
WORKDIR /var/www
Se 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 delDockerfile
si se especifica en elCaddyfile
.COPY files/Caddyfile /etc/Caddyfile
Copia el fichero de configuración de Caddy a contenedor.COPY files/index.html /var/www
yCOPY files/phpinfo.php /var/www
El ficheroindex.html
es 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 2015
El puerto por defecto de Caddy es el 2015, y no el 80 como es habitual en otros servidores web.USER caddy
Nos deshacemos de los privilegios deroot
y 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.0
Indica 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/www
root indica cuál es la raíz del site para Caddy.gzip
Habilita la compresión si el cliente lo soporta. Ver gzip docstartup php-fpm
startup ejecuta un comando cuando Caddy arranca. En este caso, arrancaphp-fpm
para 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 stdout
yerrors stdout
redirigen 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
www
y sus subcarpetas. Esto es necesario porque el usuariocaddy
en 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